Merge branch 'MDL-57680' of https://github.com/timhunt/moodle
authorAndrew Nicols <andrew@nicols.co.uk>
Fri, 1 May 2020 03:00:19 +0000 (11:00 +0800)
committerAndrew Nicols <andrew@nicols.co.uk>
Fri, 1 May 2020 03:00:19 +0000 (11:00 +0800)
lib/amd/build/form-autocomplete.min.js
lib/amd/build/form-autocomplete.min.js.map
lib/amd/src/form-autocomplete.js
lib/form/course.php
lib/form/tests/behat/autocomplete.feature
lib/form/tests/behat/behat_core_form.php [new file with mode: 0644]
lib/form/tests/fixtures/autocomplete-disabledif.php [new file with mode: 0644]

index 9c07fdd..154a606 100644 (file)
Binary files a/lib/amd/build/form-autocomplete.min.js and b/lib/amd/build/form-autocomplete.min.js differ
index 72d5f1b..944df5c 100644 (file)
Binary files a/lib/amd/build/form-autocomplete.min.js.map and b/lib/amd/build/form-autocomplete.min.js.map differ
index 4738bb6..035f94e 100644 (file)
@@ -145,7 +145,10 @@ function($, log, str, templates, notification, LoadingIcon) {
         if (typeof M.core_formchangechecker !== 'undefined') {
             M.core_formchangechecker.set_form_changed();
         }
-        originalSelect.change();
+
+        // Note, jQuery .change() was not working here. Better to
+        // use plain JavaScript anyway.
+        originalSelect[0].dispatchEvent(new Event('change'));
     };
 
     /**
@@ -1026,6 +1029,12 @@ function($, log, str, templates, notification, LoadingIcon) {
             uniqueId++;
 
             options.multiple = originalSelect.attr('multiple');
+            if (!options.multiple) {
+                // If this is a single select then there is no way to de-select the current value -
+                // unless we add a bogus blank option to be selected when nothing else is.
+                // This matches similar code in updateAjax above.
+                originalSelect.prepend('<option>');
+            }
 
             if (typeof closeSuggestionsOnSelect !== "undefined") {
                 options.closeSuggestionsOnSelect = closeSuggestionsOnSelect;
index f651398..1c11681 100644 (file)
@@ -124,7 +124,7 @@ class MoodleQuickForm_course extends MoodleQuickForm_autocomplete {
         $coursestofetch = array();
 
         foreach ($values as $onevalue) {
-            if ((!$this->optionExists($onevalue)) &&
+            if ($onevalue && !$this->optionExists($onevalue) &&
                     ($onevalue !== '_qf__force_multiselect_submission')) {
                 array_push($coursestofetch, $onevalue);
             }
index b6882df..b4c805e 100644 (file)
@@ -4,18 +4,18 @@ Feature: Autocomplete functionality in forms
   As a user
   I need to use the autocomplete form element
 
-  Background:
+  Scenario: Use autocomplete element which accepts a single value
     Given the following "users" exist:
       | username | firstname | lastname |
       | user1    | Jane      | Jones    |
       | user2    | Sam       | Smith    |
     And I log in as "admin"
 
-  Scenario: Use autocomplete element which accepts a single value
     When I navigate to "Users > Privacy and policies > Data requests" in site administration
     And I follow "New request"
     And I open the autocomplete suggestions list
     And I click on "Jane Jones" item in the autocomplete list
+
     Then "Jane Jones" "autocomplete_selection" should exist
     # Change selection
     And I open the autocomplete suggestions list
@@ -25,4 +25,40 @@ Feature: Autocomplete functionality in forms
     # Remove selection
     And I click on "Sam Smith" "autocomplete_selection"
     And "Sam Smith" "autocomplete_selection" should not exist
-    And I should see "No selection" in the ".form-autocomplete-selection" "css_element"
\ No newline at end of file
+    And I should see "No selection" in the ".form-autocomplete-selection" "css_element"
+
+  @javascript
+  Scenario: Single-select autocomplete can be cleared after being set
+    Given the following "courses" exist:
+      | fullname | shortname |
+      | Course 1 | C1        |
+    And I am on the "autocomplete-disabledif" "core_form > Fixture" page logged in as "admin"
+    When I set the field "Controls the rest" to "Course 1"
+    And "Course 1" "autocomplete_selection" should be visible
+    And I click on "Course 1" "autocomplete_selection"
+    Then "frog" "autocomplete_selection" should not exist
+
+  @javascript
+  Scenario: Single-select autocomplete can be cleared immediately after page load
+    Given the following "courses" exist:
+      | fullname | shortname |
+      | Course 1 | C1        |
+    And I am on the "autocomplete-disabledif" "core_form > Fixture" page logged in as "admin"
+    When I set the field "Controls the rest" to "Course 1"
+    And I press "Save changes"
+    And "Course 1" "autocomplete_selection" should be visible
+    And I click on "Course 1" "autocomplete_selection"
+    Then "frog" "autocomplete_selection" should not exist
+
+  @javascript
+  Scenario: Autocomplete can control other form fields via disabledIf
+    Given the following "courses" exist:
+      | fullname | shortname |
+      | Course 1 | C1        |
+    And I am on the "autocomplete-disabledif" "core_form > Fixture" page logged in as "admin"
+    When I set the field "Controls the rest" to "Course 1"
+    Then the "Single select will be enabled if the control is blank" "field" should be disabled
+    And the "Single select will be disabled if the control is blank" "field" should be enabled
+    And I click on "Course 1" "autocomplete_selection"
+    And the "Single select will be enabled if the control is blank" "field" should be enabled
+    And the "Single select will be disabled if the control is blank" "field" should be disabled
diff --git a/lib/form/tests/behat/behat_core_form.php b/lib/form/tests/behat/behat_core_form.php
new file mode 100644 (file)
index 0000000..eb88d7b
--- /dev/null
@@ -0,0 +1,82 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Steps definitions related to mod_quiz.
+ *
+ * @package   core_form
+ * @category  test
+ * @copyright 2020 The Open University
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
+
+require_once(__DIR__ . '/../../../../lib/behat/behat_base.php');
+require_once(__DIR__ . '/../../../../question/tests/behat/behat_question_base.php');
+
+use Behat\Gherkin\Node\TableNode as TableNode;
+
+use Behat\Mink\Exception\ExpectationException as ExpectationException;
+
+/**
+ * Steps definitions related to core_form.
+ */
+class behat_core_form extends behat_question_base {
+
+    /**
+     * Convert page names to URLs for steps like 'When I am on the "core_form > [page name]" page'.
+     *
+     * Recognised page names are:
+     * | None so far!      |                                                              |
+     *
+     * @param string $page name of the page, with the component name removed e.g. 'Admin notification'.
+     * @return moodle_url the corresponding URL.
+     * @throws Exception with a meaningful error message if the specified page cannot be found.
+     */
+    protected function resolve_page_url(string $page): moodle_url {
+        switch ($page) {
+            default:
+                throw new Exception('Unrecognised core_form page type "' . $page . '."');
+        }
+    }
+
+    /**
+     * Convert page names to URLs for steps like 'When I am on the "[identifier]" "core_form > [page type]" page'.
+     *
+     * Recognised page names are:
+     * | pagetype | name meaning | description                         |
+     * | Fixture  | script-name  | Fixture file name without extension |
+     *
+     * The fixture name should be the filename without path or extension. E.g.
+     * autocomplete-disabledif for lib/form/tests/fixtures/autocomplete-disabledif.php.
+     *
+     * @param string $type identifies which type of page this is, e.g. 'Fixture'.
+     * @param string $identifier identifies the particular page, e.g. 'autocomplete-disabledif'.
+     * @return moodle_url the corresponding URL.
+     * @throws Exception with a meaningful error message if the specified page cannot be found.
+     */
+    protected function resolve_page_instance_url(string $type, string $identifier): moodle_url {
+        switch ($type) {
+            case 'Fixture':
+                return new moodle_url('/lib/form/tests/fixtures/' .
+                        clean_param($identifier, PARAM_ALPHAEXT) . '.php');
+
+            default:
+                throw new Exception('Unrecognised core_form page type "' . $type . '."');
+        }
+    }
+}
diff --git a/lib/form/tests/fixtures/autocomplete-disabledif.php b/lib/form/tests/fixtures/autocomplete-disabledif.php
new file mode 100644 (file)
index 0000000..6c4a611
--- /dev/null
@@ -0,0 +1,66 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Test form for testing autocomplete behaviour.
+ *
+ * @copyright 2020 The Open University
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once(__DIR__ . '/../../../../config.php');
+require_once($CFG->libdir . '/formslib.php');
+
+if (!defined('BEHAT_SITE_RUNNING')) {
+    throw new coding_exception('This fixture can only be used in Behat tests.');
+}
+require_login();
+require_capability('moodle/site:config', context_system::instance());
+
+
+/**
+ * The form class for our test.
+ */
+class test_form extends moodleform {
+
+    protected function definition() {
+        $mform = $this->_form;
+
+        $mform->addElement('course', 'x', 'Controls the rest');
+
+        $mform->addElement('text', 'enabledifblank', 'Single select will be enabled if the control is blank');
+        $mform->disabledIf('enabledifblank', 'x', 'neq', '');
+        $mform->setType('enabledifblank', PARAM_RAW);
+
+        $mform->addElement('text', 'disabledifblank', 'Single select will be disabled if the control is blank');
+        $mform->disabledIf('disabledifblank', 'x', 'eq', '');
+        $mform->setType('disabledifblank', PARAM_RAW);
+
+        $this->add_action_buttons();
+    }
+}
+
+$PAGE->set_context(context_system::instance());
+$PAGE->set_url('/lib/form/tests/fixtures/autocomplete-disabledif.php');
+echo $OUTPUT->header();
+
+$form = new test_form();
+if ($data = $form->get_data()) {
+    echo $OUTPUT->notification("Data was submitted (but still re-showing form).", 'success');
+}
+
+$form->display();
+echo $OUTPUT->footer();