From 80cd508669695967800e202c6797db129e9b0574 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Sat, 28 Dec 2013 11:35:48 +0800 Subject: [PATCH] MDL-34356 JavaScript: Allow chooser dialogues to submit values for hidden elements When we submit the chooser dialogue, we disable the radio buttons used for selection. Since browsers do not actually submit values for disabled elements, we store the radio value in a hidden element which is not disabled. This commit abstracts this out of the activity chooser and into the generic chooser dialogue such that other types of chooser dialogue may use it. --- course/renderer.php | 2 -- .../moodle-course-modchooser-debug.js | 10 +++++----- .../moodle-course-modchooser-min.js | 2 +- .../moodle-course-modchooser.js | 10 +++++----- course/yui/src/modchooser/js/modchooser.js | 10 +++++----- .../moodle-core-chooserdialogue-debug.js | 20 ++++++++++++++++--- .../moodle-core-chooserdialogue-min.js | 2 +- .../moodle-core-chooserdialogue.js | 20 ++++++++++++++++--- .../src/chooserdialogue/js/chooserdialogue.js | 20 ++++++++++++++++--- 9 files changed, 68 insertions(+), 28 deletions(-) diff --git a/course/renderer.php b/course/renderer.php index 10012127419..95021674eae 100644 --- a/course/renderer.php +++ b/course/renderer.php @@ -194,8 +194,6 @@ class core_course_renderer extends plugin_renderer_base { $formcontent .= html_writer::start_tag('div', array('id' => 'typeformdiv')); $formcontent .= html_writer::tag('input', '', array('type' => 'hidden', 'id' => 'course', 'name' => 'course', 'value' => $course->id)); - $formcontent .= html_writer::tag('input', '', - array('type' => 'hidden', 'class' => 'jump', 'name' => 'jump', 'value' => '')); $formcontent .= html_writer::tag('input', '', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey())); $formcontent .= html_writer::end_tag('div'); diff --git a/course/yui/build/moodle-course-modchooser/moodle-course-modchooser-debug.js b/course/yui/build/moodle-course-modchooser/moodle-course-modchooser-debug.js index 96126f3b649..d3bf0c1de2d 100644 --- a/course/yui/build/moodle-course-modchooser/moodle-course-modchooser-debug.js +++ b/course/yui/build/moodle-course-modchooser/moodle-course-modchooser-debug.js @@ -31,9 +31,6 @@ Y.extend(MODCHOOSER, M.core.chooserdialogue, { // The current section ID sectionid : null, - // The hidden element holding the jump param - jumplink : null, - initializer : function() { var dialogue = Y.one('.chooserdialoguebody'); var header = Y.one('.choosertitle'); @@ -157,8 +154,11 @@ Y.extend(MODCHOOSER, M.core.chooserdialogue, { e.preventDefault(); }, option_selected : function(thisoption) { - // Add the sectionid to the URL - this.jumplink.set('value', thisoption.get('value') + '§ion=' + this.sectionid); + // Add the sectionid to the URL. + this.hiddenRadioValue.setAttrs({ + name: 'jump', + value: thisoption.get('value') + '§ion=' + this.sectionid + }); } }, { diff --git a/course/yui/build/moodle-course-modchooser/moodle-course-modchooser-min.js b/course/yui/build/moodle-course-modchooser/moodle-course-modchooser-min.js index 33f576f2ad6..f9bddf445c7 100644 --- a/course/yui/build/moodle-course-modchooser/moodle-course-modchooser-min.js +++ b/course/yui/build/moodle-course-modchooser/moodle-course-modchooser-min.js @@ -1 +1 @@ -YUI.add("moodle-course-modchooser",function(e,t){var n={PAGECONTENT:"div#page-content",SECTION:"li.section",SECTIONMODCHOOSER:"span.section-modchooser-link",SITEMENU:"div.block_site_main_menu",SITETOPIC:"div.sitetopic"},r="course-modchooser",i=function(){i.superclass.constructor.apply(this,arguments)};e.extend(i,M.core.chooserdialogue,{sectionid:null,jumplink:null,initializer:function(){var t=e.one(".chooserdialoguebody"),n=e.one(".choosertitle"),r={};this.setup_chooser_dialogue(t,n,r),this.setup_for_section(),M.course.coursebase.register_module(this),e.all(".block_settings #settingsnav .type_course .modchoosertoggle a").on("click",this.toggle_mod_chooser,this)},setup_for_section:function(t){t||(t=n.PAGECONTENT),e.one(t).all(n.SITETOPIC).each(function(e){this._setup_for_section(e)},this),e.one(t).all(n.SECTION).each(function(e){this._setup_for_section(e)},this),e.one(t).all(n.SITEMENU).each(function(e){this._setup_for_section(e)},this)},_setup_for_section:function(t){var r=t.one(n.SECTIONMODCHOOSER);if(!r)return;var i=e.Node.create("");r.get("children").each(function(e){i.appendChild(e)}),r.insertBefore(i),i.on("click",this.display_mod_chooser,this)},display_mod_chooser:function(e){if(e.target.ancestor(n.SITETOPIC))this.sectionid=1;else if(e.target.ancestor(n.SECTION)){var t=e.target.ancestor(n.SECTION);this.sectionid=t.get("id").replace("section-","")}else e.target.ancestor(n.SITEMENU)&&(this.sectionid=0);this.display_chooser(e)},toggle_mod_chooser:function(t){var n=e.all("div.addresourcemodchooser"),r=e.all("div.addresourcedropdown");if(n.size()===0)return;var i=e.one(".block_settings #settingsnav .type_course .modchoosertoggle a"),s=i.get("lastChild"),o;n.item(0).hasClass("visibleifjs")?(o=0,n.removeClass("visibleifjs").addClass("hiddenifjs"),r.addClass("visibleifjs").removeClass("hiddenifjs"),s.set("data",M.util.get_string("modchooserenable","moodle")),i.set("href",i.get("href").replace("off","on"))):(o=1,n.addClass("visibleifjs").removeClass("hiddenifjs"),r.removeClass("visibleifjs").addClass("hiddenifjs"),s.set("data",M.util.get_string("modchooserdisable","moodle")),i.set("href",i.get("href").replace("on","off"))),M.util.set_user_preference("usemodchooser",o),t.preventDefault()},option_selected:function(e){this.jumplink.set("value",e.get("value")+"§ion="+this.sectionid)}},{NAME:r,ATTRS:{maxheight:{value:800}}}),M.course=M.course||{},M.course.init_chooser=function(e){return new i(e)}},"@VERSION@",{requires:["moodle-core-chooserdialogue","moodle-course-coursebase"]}); +YUI.add("moodle-course-modchooser",function(e,t){var n={PAGECONTENT:"div#page-content",SECTION:"li.section",SECTIONMODCHOOSER:"span.section-modchooser-link",SITEMENU:"div.block_site_main_menu",SITETOPIC:"div.sitetopic"},r="course-modchooser",i=function(){i.superclass.constructor.apply(this,arguments)};e.extend(i,M.core.chooserdialogue,{sectionid:null,initializer:function(){var t=e.one(".chooserdialoguebody"),n=e.one(".choosertitle"),r={};this.setup_chooser_dialogue(t,n,r),this.setup_for_section(),M.course.coursebase.register_module(this),e.all(".block_settings #settingsnav .type_course .modchoosertoggle a").on("click",this.toggle_mod_chooser,this)},setup_for_section:function(t){t||(t=n.PAGECONTENT),e.one(t).all(n.SITETOPIC).each(function(e){this._setup_for_section(e)},this),e.one(t).all(n.SECTION).each(function(e){this._setup_for_section(e)},this),e.one(t).all(n.SITEMENU).each(function(e){this._setup_for_section(e)},this)},_setup_for_section:function(t){var r=t.one(n.SECTIONMODCHOOSER);if(!r)return;var i=e.Node.create("");r.get("children").each(function(e){i.appendChild(e)}),r.insertBefore(i),i.on("click",this.display_mod_chooser,this)},display_mod_chooser:function(e){if(e.target.ancestor(n.SITETOPIC))this.sectionid=1;else if(e.target.ancestor(n.SECTION)){var t=e.target.ancestor(n.SECTION);this.sectionid=t.get("id").replace("section-","")}else e.target.ancestor(n.SITEMENU)&&(this.sectionid=0);this.display_chooser(e)},toggle_mod_chooser:function(t){var n=e.all("div.addresourcemodchooser"),r=e.all("div.addresourcedropdown");if(n.size()===0)return;var i=e.one(".block_settings #settingsnav .type_course .modchoosertoggle a"),s=i.get("lastChild"),o;n.item(0).hasClass("visibleifjs")?(o=0,n.removeClass("visibleifjs").addClass("hiddenifjs"),r.addClass("visibleifjs").removeClass("hiddenifjs"),s.set("data",M.util.get_string("modchooserenable","moodle")),i.set("href",i.get("href").replace("off","on"))):(o=1,n.addClass("visibleifjs").removeClass("hiddenifjs"),r.removeClass("visibleifjs").addClass("hiddenifjs"),s.set("data",M.util.get_string("modchooserdisable","moodle")),i.set("href",i.get("href").replace("on","off"))),M.util.set_user_preference("usemodchooser",o),t.preventDefault()},option_selected:function(e){this.hiddenRadioValue.setAttrs({name:"jump",value:e.get("value")+"§ion="+this.sectionid})}},{NAME:r,ATTRS:{maxheight:{value:800}}}),M.course=M.course||{},M.course.init_chooser=function(e){return new i(e)}},"@VERSION@",{requires:["moodle-core-chooserdialogue","moodle-course-coursebase"]}); diff --git a/course/yui/build/moodle-course-modchooser/moodle-course-modchooser.js b/course/yui/build/moodle-course-modchooser/moodle-course-modchooser.js index 96126f3b649..d3bf0c1de2d 100644 --- a/course/yui/build/moodle-course-modchooser/moodle-course-modchooser.js +++ b/course/yui/build/moodle-course-modchooser/moodle-course-modchooser.js @@ -31,9 +31,6 @@ Y.extend(MODCHOOSER, M.core.chooserdialogue, { // The current section ID sectionid : null, - // The hidden element holding the jump param - jumplink : null, - initializer : function() { var dialogue = Y.one('.chooserdialoguebody'); var header = Y.one('.choosertitle'); @@ -157,8 +154,11 @@ Y.extend(MODCHOOSER, M.core.chooserdialogue, { e.preventDefault(); }, option_selected : function(thisoption) { - // Add the sectionid to the URL - this.jumplink.set('value', thisoption.get('value') + '§ion=' + this.sectionid); + // Add the sectionid to the URL. + this.hiddenRadioValue.setAttrs({ + name: 'jump', + value: thisoption.get('value') + '§ion=' + this.sectionid + }); } }, { diff --git a/course/yui/src/modchooser/js/modchooser.js b/course/yui/src/modchooser/js/modchooser.js index 0bd98256746..b1033e33c86 100644 --- a/course/yui/src/modchooser/js/modchooser.js +++ b/course/yui/src/modchooser/js/modchooser.js @@ -29,9 +29,6 @@ Y.extend(MODCHOOSER, M.core.chooserdialogue, { // The current section ID sectionid : null, - // The hidden element holding the jump param - jumplink : null, - initializer : function() { var dialogue = Y.one('.chooserdialoguebody'); var header = Y.one('.choosertitle'); @@ -155,8 +152,11 @@ Y.extend(MODCHOOSER, M.core.chooserdialogue, { e.preventDefault(); }, option_selected : function(thisoption) { - // Add the sectionid to the URL - this.jumplink.set('value', thisoption.get('value') + '§ion=' + this.sectionid); + // Add the sectionid to the URL. + this.hiddenRadioValue.setAttrs({ + name: 'jump', + value: thisoption.get('value') + '§ion=' + this.sectionid + }); } }, { diff --git a/lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue-debug.js b/lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue-debug.js index 0d1d0a2ba7f..1e199204d7f 100644 --- a/lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue-debug.js +++ b/lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue-debug.js @@ -21,6 +21,9 @@ Y.extend(CHOOSERDIALOGUE, Y.Base, { headercontent : null, instanceconfig : null, + // The hidden field storing the disabled element values for submission. + hiddenRadioValue: null, + setup_chooser_dialogue : function(bodycontent, headercontent, config) { this.bodycontent = bodycontent; this.headercontent = headercontent; @@ -62,10 +65,15 @@ Y.extend(CHOOSERDIALOGUE, Y.Base, { this.panel.hide(); this.panel.render(); - // Set useful links + // Set useful links. this.container = this.panel.get('boundingBox').one('.choosercontainer'); this.options = this.container.all('.option input[type=radio]'); + // The hidden form element we use when submitting. + this.hiddenRadioValue = Y.Node.create(''); + this.container.one('form').appendChild(this.hiddenRadioValue); + + // Add the chooserdialogue class to the container for styling this.panel.get('boundingBox').addClass('chooserdialogue'); }, @@ -137,7 +145,6 @@ Y.extend(CHOOSERDIALOGUE, Y.Base, { this.listenevents.push(thisevent); // Add references to various elements we adjust - this.jumplink = this.container.one('.jump'); this.submitbutton = this.container.one('.submitbutton'); // Disable the submit element until the user makes a selection @@ -270,7 +277,14 @@ Y.extend(CHOOSERDIALOGUE, Y.Base, { }, this); }, - option_selected : function() { + option_selected : function(e) { + // Set a hidden input field with the value and name of the radio button. When we submit the form, we + // disable the radios to prevent duplicate submission. This has the result however that the value is never + // submitted so we set this value to a hidden field instead + this.hiddenRadioValue.setAttrs({ + value: e.get('value'), + name: e.get('name') + }); } }, { diff --git a/lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue-min.js b/lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue-min.js index c044e7dceaa..ed61bb18edd 100644 --- a/lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue-min.js +++ b/lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue-min.js @@ -1 +1 @@ -YUI.add("moodle-core-chooserdialogue",function(e,t){var n=function(){n.superclass.constructor.apply(this,arguments)};e.extend(n,e.Base,{panel:null,submitbutton:null,container:null,listenevents:[],bodycontent:null,headercontent:null,instanceconfig:null,setup_chooser_dialogue:function(e,t,n){this.bodycontent=e,this.headercontent=t,this.instanceconfig=n},prepare_chooser:function(){if(this.panel)return;var e,t={bodyContent:this.bodycontent.get("innerHTML"),headerContent:this.headercontent.get("innerHTML"),width:"540px",draggable:!0,visible:!1,zindex:100,modal:!0,shim:!0,closeButtonTitle:this.get("closeButtonTitle")};for(e in this.instanceconfig)t[e]=this.instanceconfig[e];this.panel=new M.core.dialogue(t),this.bodycontent.remove(),this.headercontent.remove(),this.panel.hide(),this.panel.render(),this.container=this.panel.get("boundingBox").one(".choosercontainer"),this.options=this.container.all(".option input[type=radio]"),this.panel.get("boundingBox").addClass("chooserdialogue")},display_chooser:function(t){var n,r,i;this.prepare_chooser(),t.preventDefault(),n=this.panel.get("boundingBox"),r=this.container.one(".alloptions"),i=e.one("document").on("orientationchange",function(){this.center_dialogue(r)},this),this.listenevents.push(i),i=e.one("window").on("resize",function(){this.center_dialogue(r)},this),this.listenevents.push(i),i=this.container.on("click",this.check_options,this),this.listenevents.push(i),i=this.container.on("key_up",this.check_options,this),this.listenevents.push(i),i=this.container.on("dblclick",function(e){e.target.ancestor("div.option")&&(this.check_options(),this.submitbutton.setAttribute("disabled","disabled"),this.options.setAttribute("disabled","disabled"),this.cancel_listenevents(),this.container.one("form").submit())},this),this.listenevents.push(i),this.container.one("form").on("submit",function(){this.submitbutton.setAttribute("disabled","disabled"),this.options.setAttribute("disabled","disabled"),this.cancel_listenevents()},this),i=this.container.one(".addcancel").on("click",this.cancel_popup,this),this.listenevents.push(i),i=n.one("button.closebutton").on("click",this.cancel_popup,this),this.listenevents.push(i),i=e.one("document").on("keydown",this.handle_key_press,this),this.listenevents.push(i),this.jumplink=this.container.one(".jump"),this.submitbutton=this.container.one(".submitbutton"),this.submitbutton.set("disabled","true"),this.options.removeAttribute("disabled"),this.panel.show(),this.center_dialogue(r),this.container.one(".option input[type=radio]").focus(),this.check_options()},cancel_listenevents:function(){var e;while(this.listenevents.length)e=this.listenevents.shift(),e.detach()},center_dialogue:function(e){var t=this.panel.get("boundingBox"),n=t.get("winHeight"),r,i;if(this.panel.shouldResizeFullscreen())return;r=this.get("maxheight"),n<=r&&(n<=this.get("minheight")?r=this.get("minheight"):r=n),i=r,r-=110,e.setStyle("maxHeight",r+"px"),dialogueheight=t.getStyle("height"),dialogueheight.match(/.*px$/)?dialogueheight=dialogueheight.replace(/px$/,""):dialogueheight=i,dialogueheight'),this.container.one("form").appendChild(this.hiddenRadioValue),this.panel.get("boundingBox").addClass("chooserdialogue")},display_chooser:function(t){var n,r,i;this.prepare_chooser(),t.preventDefault(),n=this.panel.get("boundingBox"),r=this.container.one(".alloptions"),i=e.one("document").on("orientationchange",function(){this.center_dialogue(r)},this),this.listenevents.push(i),i=e.one("window").on("resize",function(){this.center_dialogue(r)},this),this.listenevents.push(i),i=this.container.on("click",this.check_options,this),this.listenevents.push(i),i=this.container.on("key_up",this.check_options,this),this.listenevents.push(i),i=this.container.on("dblclick",function(e){e.target.ancestor("div.option")&&(this.check_options(),this.submitbutton.setAttribute("disabled","disabled"),this.options.setAttribute("disabled","disabled"),this.cancel_listenevents(),this.container.one("form").submit())},this),this.listenevents.push(i),this.container.one("form").on("submit",function(){this.submitbutton.setAttribute("disabled","disabled"),this.options.setAttribute("disabled","disabled"),this.cancel_listenevents()},this),i=this.container.one(".addcancel").on("click",this.cancel_popup,this),this.listenevents.push(i),i=n.one("button.closebutton").on("click",this.cancel_popup,this),this.listenevents.push(i),i=e.one("document").on("keydown",this.handle_key_press,this),this.listenevents.push(i),this.submitbutton=this.container.one(".submitbutton"),this.submitbutton.set("disabled","true"),this.options.removeAttribute("disabled"),this.panel.show(),this.center_dialogue(r),this.container.one(".option input[type=radio]").focus(),this.check_options()},cancel_listenevents:function(){var e;while(this.listenevents.length)e=this.listenevents.shift(),e.detach()},center_dialogue:function(e){var t=this.panel.get("boundingBox"),n=t.get("winHeight"),r,i;if(this.panel.shouldResizeFullscreen())return;r=this.get("maxheight"),n<=r&&(n<=this.get("minheight")?r=this.get("minheight"):r=n),i=r,r-=110,e.setStyle("maxHeight",r+"px"),dialogueheight=t.getStyle("height"),dialogueheight.match(/.*px$/)?dialogueheight=dialogueheight.replace(/px$/,""):dialogueheight=i,dialogueheight