MDL-55417 forms: Render form elements with a template

This change allows form elements to be overridden with a mustache template.
The template can even listen for form validation errors and supply the JS to
change the look of the form element when there is/isn't a validation error.

Initial support is for all core form elements including:

text, select, selectyesno and checkboxes, groups, dateselector, datetimeselector,
autocomplete, modvisible, advcheckbox, button, duration, filemanager, filepicker, editor, static, grading,
warning, textarea, password, url, submit, questioncategory, recaptcha.

Part of MDL-55071
This commit is contained in:
Damyon Wiese
2016-09-23 10:53:30 +01:00
committed by Dan Poltawski
parent ef18a21f93
commit 91bda4cd45
69 changed files with 1566 additions and 367 deletions
+89 -1
View File
@@ -26,6 +26,7 @@
*/
require_once("HTML/QuickForm/group.php");
require_once(__DIR__ . '/../outputcomponents.php');
/**
* HTML class for a form element group
@@ -37,13 +38,15 @@ require_once("HTML/QuickForm/group.php");
* @copyright 2007 Jamie Pratt <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class MoodleQuickForm_group extends HTML_QuickForm_group{
class MoodleQuickForm_group extends HTML_QuickForm_group implements templatable {
/** @var string html for help button, if empty then no help */
var $_helpbutton='';
/** @var MoodleQuickForm */
protected $_mform = null;
var $_renderedfromtemplate = false;
/**
* constructor
*
@@ -147,4 +150,89 @@ class MoodleQuickForm_group extends HTML_QuickForm_group{
}
return call_user_func_array([$this->_mform, 'createElement'], func_get_args());
}
public function export_for_template(renderer_base $output) {
global $OUTPUT;
$this->_renderedfromtemplate = true;
include_once('HTML/QuickForm/Renderer/Default.php');
$context = [];
$context['frozen'] = $this->_flagFrozen;
foreach ($this->getAttributes() as $name => $value) {
$context[$name] = $value;
}
$elements = [];
foreach ($this->_elements as $key => $element) {
$element->_generateId();
$name = $this->getName();
$elementname = '';
if ($this->_appendName) {
$elementname = $element->getName();
if (isset($elementname)) {
$element->setName($name . '['. (strlen($elementname) ? $elementname : $key) .']');
} else {
$element->setName($name);
}
}
$out = $OUTPUT->mform_element($element, false, '', true);
if (empty($out)) {
$renderer = new HTML_QuickForm_Renderer_Default();
$renderer->setElementTemplate('{element}');
$element->accept($renderer);
$out = $renderer->toHtml();
}
$elements[] = $out;
// Restore the element's name.
if ($this->_appendName) {
$element->setName($elementname);
}
}
$context['elements'] = $elements;
return $context;
}
/**
* Accepts a renderer
*
* @param object An HTML_QuickForm_Renderer object
* @param bool Whether a group is required
* @param string An error message associated with a group
* @access public
* @return void
*/
function accept(&$renderer, $required = false, $error = null) {
$this->_createElementsIfNotExist();
$renderer->startGroup($this, $required, $error);
if (!$this->_renderedfromtemplate) {
// Backwards compatible path - only do this if we didn't render the sub-elements already.
$name = $this->getName();
foreach (array_keys($this->_elements) as $key) {
$element =& $this->_elements[$key];
if ($this->_appendName) {
$elementName = $element->getName();
if (isset($elementName)) {
$element->setName($name . '['. (strlen($elementName)? $elementName: $key) .']');
} else {
$element->setName($name);
}
}
$required = !$element->isFrozen() && in_array($element->getName(), $this->_required);
$element->accept($renderer, $required);
// restore the element's name
if ($this->_appendName) {
$element->setName($elementName);
}
}
}
$renderer->finishGroup($this);
}
}