This commit is contained in:
Andrew Nicols 2020-05-01 10:16:37 +08:00
commit 5a477de341
8 changed files with 167 additions and 4 deletions

View File

@ -101,7 +101,7 @@ class MoodleQuickForm_checkbox extends HTML_QuickForm_checkbox implements templa
if (null === $value) {
// if no boxes were checked, then there is no value in the array
// yet we don't want to display default value in this case
if ($caller->isSubmitted()) {
if ($caller->isSubmitted() && !$caller->is_new_repeat($this->getName())) {
$value = $this->_findValue($caller->_submitValues);
} else {

View File

@ -168,7 +168,7 @@ class MoodleQuickForm_date_selector extends MoodleQuickForm_group {
if (null === $value) {
// If no boxes were checked, then there is no value in the array
// yet we don't want to display default value in this case.
if ($caller->isSubmitted()) {
if ($caller->isSubmitted() && !$caller->is_new_repeat($this->getName())) {
$value = $this->_findValue($caller->_submitValues);
} else {
$value = $this->_findValue($caller->_defaultValues);

View File

@ -187,7 +187,7 @@ class MoodleQuickForm_date_time_selector extends MoodleQuickForm_group {
if (null === $value) {
// If no boxes were checked, then there is no value in the array
// yet we don't want to display default value in this case.
if ($caller->isSubmitted()) {
if ($caller->isSubmitted() && !$caller->is_new_repeat($this->getName())) {
$value = $this->_findValue($caller->_submitValues);
} else {
$value = $this->_findValue($caller->_defaultValues);

View File

@ -218,7 +218,7 @@ class MoodleQuickForm_duration extends MoodleQuickForm_group {
if (null === $value) {
// if no boxes were checked, then there is no value in the array
// yet we don't want to display default value in this case
if ($caller->isSubmitted()) {
if ($caller->isSubmitted() && !$caller->is_new_repeat($this->getName())) {
$value = $this->_findValue($caller->_submitValues);
} else {
$value = $this->_findValue($caller->_defaultValues);

View File

@ -0,0 +1,91 @@
<?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 repeat elements + defaults
*
* @copyright 2020 Davo Smith, Synergy Learning
* @package core_form
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__.'/../../../../../config.php');
defined('BEHAT_SITE_RUNNING') || die();
global $CFG, $PAGE, $OUTPUT;
require_once($CFG->libdir.'/formslib.php');
$PAGE->set_url('/lib/form/tests/behat/fixtures/repeat_defaults_form.php');
require_login();
$PAGE->set_context(context_system::instance());
/**
* Class repeat_defaults_form
* @package core_form
*/
class repeat_defaults_form extends moodleform {
/**
* Form definition
*/
public function definition() {
$mform = $this->_form;
$repeatcount = $this->_customdata['repeatcount'];
$repeat = array();
$repeatopts = array();
$repeat[] = $mform->createElement('header', 'testheading', 'Heading {no}');
$repeat[] = $mform->createElement('checkbox', 'testcheckbox', 'Test checkbox (default checked)');
$repeatopts['testcheckbox']['default'] = 1;
$repeat[] = $mform->createElement('advcheckbox', 'testadvcheckbox', 'Test advcheckbox (default checked)');
$repeatopts['testadvcheckbox']['default'] = 1;
$repeat[] = $mform->createElement('date_selector', 'testdate', 'Test date (default 8th Sept 2013)');
$repeatopts['testdate']['default'] = mktime(0, 0, 0, 9, 8, 2013);
$repeat[] = $mform->createElement('date_time_selector', 'testdatetime', 'Test datetime (default 8th Sept 2013, 10:30am)');
$repeatopts['testdatetime']['default'] = mktime(10, 30, 0, 9, 8, 2013);
$repeat[] = $mform->createElement('duration', 'testduration', 'Test duration (default 3 hours)');
$repeatopts['testduration']['default'] = 3 * HOURSECS;
$repeat[] = $mform->createElement('select', 'testselect', 'Test select (default B)', array(1 => 'A', 2 => 'B', 3 => 'C'));
$repeatopts['testselect']['default'] = 2;
$repeat[] = $mform->createElement('selectyesno', 'testselectyes', 'Test selectyesno (default yes)');
$repeatopts['testselectyes']['default'] = 1;
$repeat[] = $mform->createElement('selectyesno', 'testselectno', 'Test selectyesno (default no)');
$repeatopts['testselectno']['default'] = 0;
$repeat[] = $mform->createElement('text', 'testtext', 'Test text (default \'Testing 123\')');
$repeatopts['testtext']['default'] = 'Testing 123';
$repeatopts['testtext']['type'] = PARAM_TEXT;
$this->repeat_elements($repeat, $repeatcount, $repeatopts, 'test_repeat', 'test_repeat_add', 1, 'Add repeats', true);
$this->add_action_buttons();
}
}
$repeatcount = optional_param('test_repeat', 1, PARAM_INT);
$form = new repeat_defaults_form(null, array('repeatcount' => $repeatcount));
echo $OUTPUT->header();
$form->display();
echo $OUTPUT->footer();

View File

@ -0,0 +1,24 @@
@core_form
Feature: Newly created repeat elements have the correct default values
Scenario: Clicking button to add repeat elements creates repeat elements with the correct default values
Given I log in as "admin"
And I am on fixture page "/lib/form/tests/behat/fixtures/repeat_defaults_form.php"
When I press "Add repeats"
Then the following fields match these values:
| testcheckbox[1] | 1 |
| testadvcheckbox[1] | 1 |
| testdate[1][day] | 8 |
| testdate[1][month] | September |
| testdate[1][year] | 2013 |
| testdatetime[1][day] | 8 |
| testdatetime[1][month] | September |
| testdatetime[1][year] | 2013 |
| testdatetime[1][hour] | 10 |
| testdatetime[1][minute] | 30 |
| testduration[1][number] | 3 |
| testduration[1][timeunit] | hours |
| testselect[1] | B |
| testselectyes[1] | Yes |
| testselectno[1] | No |
| testtext[1] | Testing 123 |

View File

@ -1110,6 +1110,7 @@ abstract class moodleform {
}
$repeats = $this->optional_param($repeathiddenname, $repeats, PARAM_INT);
$addfields = $this->optional_param($addfieldsname, '', PARAM_TEXT);
$oldrepeats = $repeats;
if (!empty($addfields)){
$repeats += $addfieldsno;
}
@ -1132,6 +1133,11 @@ abstract class moodleform {
$elementclone->setLabel(str_replace('{no}', $i + 1, $elementclone->getLabel()));
}
// Mark newly created elements, so they know not to look for any submitted data.
if ($i >= $oldrepeats) {
$mform->note_new_repeat($elementclone->getName());
}
$mform->addElement($elementclone);
}
}
@ -1542,6 +1548,9 @@ class MoodleQuickForm extends HTML_QuickForm_DHTMLRulesTableless {
*/
var $_pageparams = '';
/** @var array names of new repeating elements that should not expect to find submitted data */
protected $_newrepeats = array();
/** @var array $_ajaxformdata submitted form data when using mforms with ajax */
protected $_ajaxformdata;
@ -2867,6 +2876,28 @@ require(["core/event", "jquery"], function(Event, $) {
{
return parent::isSubmitted() && (!$this->isFrozen());
}
/**
* Add the element name to the list of newly-created repeat elements
* (So that elements that interpret 'no data submitted' as a valid state
* can tell when they should get the default value instead).
*
* @param string $name the name of the new element
*/
public function note_new_repeat($name) {
$this->_newrepeats[] = $name;
}
/**
* Check if the element with the given name has just been added by clicking
* on the 'Add repeating elements' button.
*
* @param string $name the name of the element being checked
* @return bool true if the element is newly added
*/
public function is_new_repeat($name) {
return in_array($name, $this->_newrepeats);
}
}
/**

View File

@ -962,4 +962,21 @@ class behat_navigation extends behat_base {
throw new ElementNotFoundException($this->getSession(),
'Link "' . join(' > ', $nodelist) . '" in the current page edit menu"');
}
/**
* Visit a fixture page for testing stuff that is not available in core.
*
* Please always, to prevent unwanted requests, protect behat fixture files with:
* defined('BEHAT_SITE_RUNNING') || die();
*
* @Given /^I am on fixture page "(?P<url_string>(?:[^"]|\\")*)"$/
* @param string $url local path to fixture page
*/
public function i_am_on_fixture_page($url) {
$fixtureregex = '|^/[a-z0-9_\-/]*/tests/behat/fixtures/[a-z0-9_\-]*\.php$|';
if (!preg_match($fixtureregex, $url)) {
throw new coding_exception("URL {$url} is not a fixture URL");
}
$this->getSession()->visit($this->locate_path($url));
}
}