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.
This commit is contained in:
Andrew Nicols
2013-12-28 11:35:52 +08:00
parent bbb291b7b7
commit 80cd508669
9 changed files with 68 additions and 28 deletions
-2
View File
@@ -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');
@@ -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') + '&section=' + this.sectionid);
// Add the sectionid to the URL.
this.hiddenRadioValue.setAttrs({
name: 'jump',
value: thisoption.get('value') + '&section=' + this.sectionid
});
}
},
{
@@ -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("<a href='#' />");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")+"&section="+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("<a href='#' />");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")+"&section="+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"]});
@@ -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') + '&section=' + this.sectionid);
// Add the sectionid to the URL.
this.hiddenRadioValue.setAttrs({
name: 'jump',
value: thisoption.get('value') + '&section=' + this.sectionid
});
}
},
{
+5 -5
View File
@@ -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') + '&section=' + this.sectionid);
// Add the sectionid to the URL.
this.hiddenRadioValue.setAttrs({
name: 'jump',
value: thisoption.get('value') + '&section=' + this.sectionid
});
}
},
{
@@ -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('<input type="hidden" value="" />');
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')
});
}
},
{
@@ -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.get("baseheight")&&(dialogueheight=this.get("baseheight"),e.setStyle("height",dialogueheight+"px")),this.panel.centerDialogue()},handle_key_press:function(e){e.keyCode===27&&this.cancel_popup(e)},cancel_popup:function(e){e.preventDefault(),this.hide()},hide:function(){this.cancel_listenevents(),this.container.detachAll(),this.panel.hide()},check_options:function(){this.options.each(function(e){var t=e.get("parentNode").get("parentNode");e.get("checked")?(t.addClass("selected"),this.option_selected(e),this.submitbutton.removeAttribute("disabled"),e.focus()):t.removeClass("selected")},this)},option_selected:function(){}},{NAME:"moodle-core-chooserdialogue",ATTRS:{minheight:{value:300},baseheight:{value:400},maxheight:{value:660},closeButtonTitle:{validator:e.Lang.isString,value:"Close"}}}),M.core=M.core||{},M.core.chooserdialogue=n},"@VERSION@",{requires:["base","panel","moodle-core-notification"]});
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,hiddenRadioValue: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 t,n={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(t in this.instanceconfig)n[t]=this.instanceconfig[t];this.panel=new M.core.dialogue(n),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.hiddenRadioValue=e.Node.create('<input type="hidden" value="" />'),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<this.get("baseheight")&&(dialogueheight=this.get("baseheight"),e.setStyle("height",dialogueheight+"px")),this.panel.centerDialogue()},handle_key_press:function(e){e.keyCode===27&&this.cancel_popup(e)},cancel_popup:function(e){e.preventDefault(),this.hide()},hide:function(){this.cancel_listenevents(),this.container.detachAll(),this.panel.hide()},check_options:function(){this.options.each(function(e){var t=e.get("parentNode").get("parentNode");e.get("checked")?(t.addClass("selected"),this.option_selected(e),this.submitbutton.removeAttribute("disabled"),e.focus()):t.removeClass("selected")},this)},option_selected:function(e){this.hiddenRadioValue.setAttrs({value:e.get("value"),name:e.get("name")})}},{NAME:"moodle-core-chooserdialogue",ATTRS:{minheight:{value:300},baseheight:{value:400},maxheight:{value:660},closeButtonTitle:{validator:e.Lang.isString,value:"Close"}}}),M.core=M.core||{},M.core.chooserdialogue=n},"@VERSION@",{requires:["base","panel","moodle-core-notification"]});
@@ -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('<input type="hidden" value="" />');
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')
});
}
},
{
+17 -3
View File
@@ -19,6 +19,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;
@@ -60,10 +63,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('<input type="hidden" value="" />');
this.container.one('form').appendChild(this.hiddenRadioValue);
// Add the chooserdialogue class to the container for styling
this.panel.get('boundingBox').addClass('chooserdialogue');
},
@@ -135,7 +143,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
@@ -268,7 +275,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')
});
}
},
{