From 5eadb30e07d3f04140f71855d92ee7824acb9597 Mon Sep 17 00:00:00 2001
From: Andrew Robert Nicols
Date: Fri, 21 Sep 2012 15:17:22 +0100
Subject: [PATCH 1/2] MDL-35569 AJAX Move auto-submitting selects to separate
YUI module
sam note: Some changes removed from 2.4 version (deprecation warning, lib/upgrade.txt).
---
course/category.php | 7 +-
course/search.php | 9 +-
lib/outputrenderers.php | 20 ++++-
lib/yui/formautosubmit/formautosubmit.js | 108 +++++++++++++++++++++++
mod/choice/lib.php | 7 +-
mod/feedback/analysis_course.php | 8 +-
mod/lesson/report.php | 7 +-
theme/mymobile/renderers.php | 10 ++-
8 files changed, 161 insertions(+), 15 deletions(-)
create mode 100644 lib/yui/formautosubmit/formautosubmit.js
diff --git a/course/category.php b/course/category.php
index cb1d0c79fa5..793b1204853 100644
--- a/course/category.php
+++ b/course/category.php
@@ -434,8 +434,11 @@ if (!$courses) {
$movetocategories[$category->id] = get_string('moveselectedcoursesto');
echo '| ';
echo html_writer::label(get_string('moveselectedcoursesto'), 'movetoid', false, array('class' => 'accesshide'));
- echo html_writer::select($movetocategories, 'moveto', $category->id, null, array('id'=>'movetoid'));
- $PAGE->requires->js_init_call('M.util.init_select_autosubmit', array('movecourses', 'movetoid', false));
+ echo html_writer::select($movetocategories, 'moveto', $category->id, null, array('id'=>'movetoid', 'class' => 'autosubmit'));
+ $PAGE->requires->yui_module('moodle-core-formautosubmit',
+ 'M.core.init_formautosubmit',
+ array(array('selectid' => 'movetoid', 'nothing' => $category->id))
+ );
echo '';
echo ' |
';
}
diff --git a/course/search.php b/course/search.php
index 8c9f85cd156..86b99322bf7 100644
--- a/course/search.php
+++ b/course/search.php
@@ -378,8 +378,11 @@ if ($courses) {
echo "\n";
// Select box should only show categories in which user has min capability to move course.
echo html_writer::label(get_string('moveselectedcoursesto'), 'movetoid', false, array('class' => 'accesshide'));
- echo html_writer::select($usercatlist, 'moveto', '', array(''=>get_string('moveselectedcoursesto')), array('id'=>'movetoid'));
- $PAGE->requires->js_init_call('M.util.init_select_autosubmit', array('movecourses', 'movetoid', false));
+ echo html_writer::select($usercatlist, 'moveto', '', array(''=>get_string('moveselectedcoursesto')), array('id'=>'movetoid', 'class' => 'autosubmit'));
+ $PAGE->requires->yui_module('moodle-core-formautosubmit',
+ 'M.core.init_formautosubmit',
+ array(array('selectid' => 'movetoid', 'nothing' => false))
+ );
echo "\n\n";
echo "\n";
@@ -432,4 +435,4 @@ function print_navigation_bar($totalcount, $page, $perpage, $encodedsearch, $mod
echo "".get_string("showperpage", "", $defaultperpage)."";
echo "
";
}
-}
\ No newline at end of file
+}
diff --git a/lib/outputrenderers.php b/lib/outputrenderers.php
index 85816b16f38..775e1f65261 100644
--- a/lib/outputrenderers.php
+++ b/lib/outputrenderers.php
@@ -1336,6 +1336,11 @@ class core_renderer extends renderer_base {
$select->attributes['title'] = $select->tooltip;
}
+ $select->attributes['class'] = 'autosubmit';
+ if ($select->class) {
+ $select->attributes['class'] .= ' ' . $select->class;
+ }
+
if ($select->label) {
$output .= html_writer::label($select->label, $select->attributes['id'], false, $select->labelattributes);
}
@@ -1351,7 +1356,10 @@ class core_renderer extends renderer_base {
$output .= html_writer::tag('noscript', html_writer::tag('div', $go), array('style'=>'inline'));
$nothing = empty($select->nothing) ? false : key($select->nothing);
- $this->page->requires->js_init_call('M.util.init_select_autosubmit', array($select->formid, $select->attributes['id'], $nothing));
+ $this->page->requires->yui_module('moodle-core-formautosubmit',
+ 'M.core.init_formautosubmit',
+ array(array('selectid' => $select->attributes['id'], 'nothing' => $nothing))
+ );
// then div wrapper for xhtml strictness
$output = html_writer::tag('div', $output);
@@ -1417,6 +1425,11 @@ class core_renderer extends renderer_base {
$output .= html_writer::label($select->label, $select->attributes['id'], false, $select->labelattributes);
}
+ $select->attributes['class'] = 'autosubmit';
+ if ($select->class) {
+ $select->attributes['class'] .= ' ' . $select->class;
+ }
+
if ($select->helpicon instanceof help_icon) {
$output .= $this->render($select->helpicon);
} else if ($select->helpicon instanceof old_help_icon) {
@@ -1474,7 +1487,10 @@ class core_renderer extends renderer_base {
$go = html_writer::empty_tag('input', array('type'=>'submit', 'value'=>get_string('go')));
$output .= html_writer::tag('noscript', html_writer::tag('div', $go), array('style'=>'inline'));
$nothing = empty($select->nothing) ? false : key($select->nothing);
- $output .= $this->page->requires->js_init_call('M.util.init_url_select', array($select->formid, $select->attributes['id'], $nothing));
+ $this->page->requires->yui_module('moodle-core-formautosubmit',
+ 'M.core.init_formautosubmit',
+ array(array('selectid' => $select->attributes['id'], 'nothing' => $nothing))
+ );
} else {
$output .= html_writer::empty_tag('input', array('type'=>'submit', 'value'=>$select->showbutton));
}
diff --git a/lib/yui/formautosubmit/formautosubmit.js b/lib/yui/formautosubmit/formautosubmit.js
new file mode 100644
index 00000000000..01d666879c8
--- /dev/null
+++ b/lib/yui/formautosubmit/formautosubmit.js
@@ -0,0 +1,108 @@
+YUI.add('moodle-core-formautosubmit',
+ function(Y) {
+ // The CSS selectors we use
+ var CSS = {
+ AUTOSUBMIT : 'autosubmit'
+ };
+
+ var FORMAUTOSUBMITNAME = 'core-formautosubmit';
+
+ var FORMAUTOSUBMIT = function() {
+ FORMAUTOSUBMIT.superclass.constructor.apply(this, arguments);
+ }
+
+ // We only want to initialize the module fully once
+ var INITIALIZED = false;
+
+ Y.extend(FORMAUTOSUBMIT, Y.Base, {
+
+ /**
+ * Initialize the module
+ */
+ initializer : function(config) {
+ // We only apply the delegation once
+ if (!INITIALIZED) {
+ INITIALIZED = true;
+ var applyto = Y.one('body');
+
+ // We don't listen for change events by default as using the keyboard triggers these too.
+ applyto.delegate('key', this.process_changes, 'press:13', 'select.' + CSS.AUTOSUBMIT, this);
+ applyto.delegate('click', this.process_changes, 'select.' + CSS.AUTOSUBMIT, this);
+
+ if (Y.UA.os == 'macintosh' && Y.UA.webkit) {
+ // Macintosh webkit browsers like change events, but non-macintosh webkit browsers don't.
+ applyto.delegate('change', this.process_changes, 'select.' + CSS.AUTOSUBMIT, this);
+ }
+ if (Y.UA.ios) {
+ // IOS doesn't trigger click events because it's touch-based.
+ applyto.delegate('change', this.process_changes, 'select.' + CSS.AUTOSUBMIT, this);
+ }
+ }
+
+ // Assign this select items 'nothing' value and lastindex (current value)
+ var thisselect = Y.one('select#' + this.get('selectid'));
+ thisselect.setData('nothing', this.get('nothing'));
+ thisselect.setData('startindex', thisselect.get('selectedIndex'));
+ },
+
+ /**
+ * Check whether the select element was changed
+ */
+ check_changed : function(e) {
+ var select = e.target.ancestor('select.' + CSS.AUTOSUBMIT, true);
+ if (!select) {
+ return false;
+ }
+
+ var nothing = select.getData('nothing');
+ var startindex = select.getData('startindex');
+ var currentindex = select.get('selectedIndex');
+
+ var previousindex = select.getAttribute('data-previousindex');
+ select.setAttribute('data-previousindex', currentindex);
+ if (!previousindex) {
+ previousindex = startindex;
+ }
+
+ // Check whether the field has changed, and is not the 'nothing' value
+ if ((nothing===false || select.get('value') != nothing) && startindex != select.get('selectedIndex') && currentindex != previousindex) {
+ return select;
+ }
+ return false;
+ },
+
+ /**
+ * Process any changes
+ */
+ process_changes : function(e) {
+ var select = this.check_changed(e);
+ if (select) {
+ var form = select.ancestor('form', true);
+ form.submit();
+ }
+ }
+ },
+ {
+ NAME : FORMAUTOSUBMITNAME,
+ ATTRS : {
+ selectid : {
+ 'value' : ''
+ },
+ nothing : {
+ 'value' : ''
+ },
+ ignorechangeevent : {
+ 'value' : false
+ }
+ }
+ });
+
+ M.core = M.core || {};
+ M.core.init_formautosubmit = M.core.init_formautosubmit || function(config) {
+ return new FORMAUTOSUBMIT(config);
+ };
+ },
+ '@VERSION@', {
+ requires : ['base', 'event-key']
+ }
+);
diff --git a/mod/choice/lib.php b/mod/choice/lib.php
index 2b37b382c48..2e1bdb1c202 100644
--- a/mod/choice/lib.php
+++ b/mod/choice/lib.php
@@ -501,8 +501,11 @@ function prepare_choice_show_results($choice, $course, $cm, $allresponses, $forc
echo ''.get_string('deselectall').' ';
echo ' ';
echo html_writer::label(get_string('withselected', 'choice'), 'menuaction');
- echo html_writer::select(array('delete' => get_string('delete')), 'action', '', array(''=>get_string('withselectedusers')), array('id'=>'menuaction'));
- $PAGE->requires->js_init_call('M.util.init_select_autosubmit', array('attemptsform', 'menuaction', ''));
+ echo html_writer::select(array('delete' => get_string('delete')), 'action', '', array(''=>get_string('withselectedusers')), array('id'=>'menuaction', 'class' => 'autosubmit'));
+ $PAGE->requires->yui_module('moodle-core-formautosubmit',
+ 'M.core.init_formautosubmit',
+ array(array('selectid' => 'menuaction'))
+ );
echo '';
diff --git a/mod/feedback/analysis_course.php b/mod/feedback/analysis_course.php
index faf95fff973..ccbcaefa5d4 100644
--- a/mod/feedback/analysis_course.php
+++ b/mod/feedback/analysis_course.php
@@ -187,10 +187,12 @@ if ($courseitemfilter > 0) {
echo ' '. html_writer::label(get_string('filter_by_course', 'feedback'), 'coursefilterid'). ': ';
echo html_writer::select($courses, 'coursefilter', $coursefilter,
- null, array('id'=>'coursefilterid'));
+ null, array('id'=>'coursefilterid', 'class' => 'autosubmit'));
- $PAGE->requires->js_init_call('M.util.init_select_autosubmit',
- array('analysis-form', 'coursefilterid', false));
+ $PAGE->requires->yui_module('moodle-core-formautosubmit',
+ 'M.core.init_formautosubmit',
+ array(array('selectid' => 'coursefilterid', 'nothing' => false))
+ );
}
echo '
';
$itemnr = 0;
diff --git a/mod/lesson/report.php b/mod/lesson/report.php
index 37d6cba7151..889b43372e0 100644
--- a/mod/lesson/report.php
+++ b/mod/lesson/report.php
@@ -315,8 +315,11 @@ if ($action === 'delete') {
$checklinks = ''.get_string('selectall').' / ';
$checklinks .= ''.get_string('deselectall').'';
$checklinks .= html_writer::label('action', 'menuaction', false, array('class' => 'accesshide'));
- $checklinks .= html_writer::select(array('delete' => get_string('deleteselected')), 'action', 0, array(''=>'choosedots'), array('id'=>'actionid'));
- $PAGE->requires->js_init_call('M.util.init_select_autosubmit', array('theform', 'actionid', ''));
+ $checklinks .= html_writer::select(array('delete' => get_string('deleteselected')), 'action', 0, array(''=>'choosedots'), array('id'=>'actionid', 'class' => 'autosubmit'));
+ $PAGE->requires->yui_module('moodle-core-formautosubmit',
+ 'M.core.init_formautosubmit',
+ array(array('selectid' => 'actionid', 'nothing' => false))
+ );
echo $OUTPUT->box($checklinks, 'center');
echo '';
}
diff --git a/theme/mymobile/renderers.php b/theme/mymobile/renderers.php
index 2b340d95212..3a4d0c7575d 100644
--- a/theme/mymobile/renderers.php
+++ b/theme/mymobile/renderers.php
@@ -749,6 +749,11 @@ class theme_mymobile_core_renderer extends core_renderer {
$select->attributes['title'] = $select->tooltip;
}
+ $select->attributes['class'] = 'autosubmit';
+ if ($select->class) {
+ $select->attributes['class'] .= ' ' . $select->class;
+ }
+
if ($select->label) {
$output .= html_writer::label($select->label, $select->attributes['id']);
}
@@ -767,7 +772,10 @@ class theme_mymobile_core_renderer extends core_renderer {
$output .= html_writer::tag('noscript', html_writer::tag('div', $go), array('style' => 'inline'));
$nothing = empty($select->nothing) ? false : key($select->nothing);
- $this->page->requires->js_init_call('M.util.init_select_autosubmit', array($select->formid, $select->attributes['id'], $nothing));
+ $this->page->requires->yui_module('moodle-core-formautosubmit',
+ 'M.core.init_formautosubmit',
+ array(array('selectid' => $select->attributes['id'], 'nothing' => $nothing))
+ );
// then div wrapper for xhtml strictness
$output = html_writer::tag('div', $output);
From 1365b07390c2db42cd2f16082ce1751688627dc0 Mon Sep 17 00:00:00 2001
From: Andrew Robert Nicols
Date: Fri, 30 Nov 2012 09:54:37 +0000
Subject: [PATCH 2/2] MDL-36934 Only set the autosubmit class on selects when
required
The url_select class can optionally show a button (much like the non-JS
fallback). In this case, the autosubmit nature of the form shouldn't be
enforced and it should only submit on the button.
---
lib/outputrenderers.php | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/lib/outputrenderers.php b/lib/outputrenderers.php
index 775e1f65261..bc89a754f8d 100644
--- a/lib/outputrenderers.php
+++ b/lib/outputrenderers.php
@@ -1425,9 +1425,15 @@ class core_renderer extends renderer_base {
$output .= html_writer::label($select->label, $select->attributes['id'], false, $select->labelattributes);
}
- $select->attributes['class'] = 'autosubmit';
+ $classes = array();
+ if (!$select->showbutton) {
+ $classes[] = 'autosubmit';
+ }
if ($select->class) {
- $select->attributes['class'] .= ' ' . $select->class;
+ $classes[] = $select->class;
+ }
+ if (count($classes)) {
+ $select->attributes['class'] = implode(' ', $classes);
}
if ($select->helpicon instanceof help_icon) {