From 4f110c471aa2775565386a9713069bc77d6631e8 Mon Sep 17 00:00:00 2001 From: Marina Glancy Date: Fri, 4 Nov 2011 11:29:01 +0800 Subject: [PATCH 1/2] MDL-30023: rubriceditor usability - skip buttons for reorder and delete in tabindex --- grade/grading/form/rubric/renderer.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grade/grading/form/rubric/renderer.php b/grade/grading/form/rubric/renderer.php index 622520f454e..768749a9068 100644 --- a/grade/grading/form/rubric/renderer.php +++ b/grade/grading/form/rubric/renderer.php @@ -69,7 +69,7 @@ class gradingform_rubric_renderer extends plugin_renderer_base { foreach (array('moveup', 'delete', 'movedown') as $key) { $value = get_string('criterion'.$key, 'gradingform_rubric'); $button = html_writer::empty_tag('input', array('type' => 'submit', 'name' => '{NAME}[criteria][{CRITERION-id}]['.$key.']', - 'id' => '{NAME}-criteria-{CRITERION-id}-'.$key, 'value' => $value, 'title' => $value)); + 'id' => '{NAME}-criteria-{CRITERION-id}-'.$key, 'value' => $value, 'title' => $value, 'tabindex' => -1)); $criterion_template .= html_writer::tag('div', $button, array('class' => $key)); } $criterion_template .= html_writer::end_tag('td'); // .controls @@ -203,7 +203,7 @@ class gradingform_rubric_renderer extends plugin_renderer_base { } if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FULL) { $value = get_string('leveldelete', 'gradingform_rubric'); - $button = html_writer::empty_tag('input', array('type' => 'submit', 'name' => '{NAME}[criteria][{CRITERION-id}][levels][{LEVEL-id}][delete]', 'id' => '{NAME}-criteria-{CRITERION-id}-levels-{LEVEL-id}-delete', 'value' => $value, 'title' => $value)); + $button = html_writer::empty_tag('input', array('type' => 'submit', 'name' => '{NAME}[criteria][{CRITERION-id}][levels][{LEVEL-id}][delete]', 'id' => '{NAME}-criteria-{CRITERION-id}-levels-{LEVEL-id}-delete', 'value' => $value, 'title' => $value, 'tabindex' => -1)); $level_template .= html_writer::tag('div', $button, array('class' => 'delete')); } $level_template .= html_writer::end_tag('div'); // .level-wrapper From 59be90119e0ff96cb2f1e07ba7504410844550e4 Mon Sep 17 00:00:00 2001 From: Marina Glancy Date: Fri, 4 Nov 2011 14:58:05 +0800 Subject: [PATCH 2/2] MDL-30023: rubric editor usability - support for tab key and adding multiple levels --- grade/grading/form/rubric/js/rubriceditor.js | 97 +++++++++++++------ .../rubric/lang/en/gradingform_rubric.php | 2 +- 2 files changed, 71 insertions(+), 28 deletions(-) diff --git a/grade/grading/form/rubric/js/rubriceditor.js b/grade/grading/form/rubric/js/rubriceditor.js index 4d1fc763787..28465096e4a 100644 --- a/grade/grading/form/rubric/js/rubriceditor.js +++ b/grade/grading/form/rubric/js/rubriceditor.js @@ -1,51 +1,60 @@ -M.gradingform_rubriceditor = {'templates' : {}, 'eventhandler' : null}; +M.gradingform_rubriceditor = {'templates' : {}, 'eventhandler' : null, 'name' : null, 'Y' : null}; /** * This function is called for each rubriceditor on page. */ M.gradingform_rubriceditor.init = function(Y, options) { + M.gradingform_rubriceditor.name = options.name + M.gradingform_rubriceditor.Y = Y M.gradingform_rubriceditor.templates[options.name] = { 'criterion' : options.criteriontemplate, 'level' : options.leveltemplate } - M.gradingform_rubriceditor.disablealleditors(null, Y, options.name) - M.gradingform_rubriceditor.addhandlers(Y, options.name) + M.gradingform_rubriceditor.disablealleditors() + Y.on('click', M.gradingform_rubriceditor.clickanywhere, 'body', null) + M.gradingform_rubriceditor.addhandlers() }; // Adds handlers for clicking submit button. This function must be called each time JS adds new elements to html -M.gradingform_rubriceditor.addhandlers = function(Y, name) { +M.gradingform_rubriceditor.addhandlers = function() { + var Y = M.gradingform_rubriceditor.Y + var name = M.gradingform_rubriceditor.name if (M.gradingform_rubriceditor.eventhandler) M.gradingform_rubriceditor.eventhandler.detach() - M.gradingform_rubriceditor.eventhandler = Y.on('click', M.gradingform_rubriceditor.clickanywhere, 'body', null, Y, name); - M.gradingform_rubriceditor.eventhandler = Y.on('click', M.gradingform_rubriceditor.buttonclick, '#rubric-'+name+' input[type=submit]', null, Y, name); + M.gradingform_rubriceditor.eventhandler = Y.on('click', M.gradingform_rubriceditor.buttonclick, '#rubric-'+name+' input[type=submit]', null); } -M.gradingform_rubriceditor.disablealleditors = function(e, Y, name) { +M.gradingform_rubriceditor.disablealleditors = function() { + var Y = M.gradingform_rubriceditor.Y + var name = M.gradingform_rubriceditor.name Y.all('#rubric-'+name+' .level').each( function(node) {M.gradingform_rubriceditor.editmode(node, false)} ); Y.all('#rubric-'+name+' .description').each( function(node) {M.gradingform_rubriceditor.editmode(node, false)} ); } -M.gradingform_rubriceditor.clickanywhere = function(e, Y, name) { +M.gradingform_rubriceditor.clickanywhere = function(e) { var el = e.target // if clicked on button - disablecurrenteditor, continue if (el.get('tagName') == 'INPUT' && el.get('type') == 'submit') { - M.gradingform_rubriceditor.disablealleditors(null, Y, name) return } // else if clicked on level and this level is not enabled - enable it // or if clicked on description and this description is not enabled - enable it - while (el && !(el.hasClass('level') || el.hasClass('description'))) el = el.get('parentNode') + var focustb = false + while (el && !(el.hasClass('level') || el.hasClass('description'))) { + if (el.hasClass('score')) focustb = true + el = el.get('parentNode') + } if (el) { if (el.one('textarea').getStyle('display') == 'none') { - M.gradingform_rubriceditor.disablealleditors(null, Y, name) - M.gradingform_rubriceditor.editmode(el, true) + M.gradingform_rubriceditor.disablealleditors() + M.gradingform_rubriceditor.editmode(el, true, focustb) } return } // else disablecurrenteditor - M.gradingform_rubriceditor.disablealleditors(null, Y, name) + M.gradingform_rubriceditor.disablealleditors() } -M.gradingform_rubriceditor.editmode = function(el, editmode) { +M.gradingform_rubriceditor.editmode = function(el, editmode, focustb) { var ta = el.one('textarea') if (!ta.get('parentNode').one('.plainvalue')) { ta.get('parentNode').append('
') @@ -55,6 +64,7 @@ M.gradingform_rubriceditor.editmode = function(el, editmode) { tb.get('parentNode').append('
') } if (!editmode) { + if (ta.getStyle('display') == 'none') return; var value = ta.get('value') if (value.length) ta.get('parentNode').one('.plainvalue').removeClass('empty') else { @@ -83,13 +93,25 @@ M.gradingform_rubriceditor.editmode = function(el, editmode) { } ta.get('parentNode').one('.plainvalue').setStyle('display', 'none') ta.setStyle('display', 'block').setStyle('width', width).setStyle('height', height) - ta.focus() + if (tb && focustb) tb.focus(); else ta.focus() + } + if (!ta.get('parentNode').one('.plainvalue').one('.pseudotablink')) { + var pseudotablink = ' ' + ta.get('parentNode').one('.plainvalue').append(pseudotablink) + ta.get('parentNode').one('.plainvalue').one('.pseudotablink').on('focus', M.gradingform_rubriceditor.clickanywhere) + if (tb) { + tb.get('parentNode').one('.plainvalue').append(pseudotablink) + tb.get('parentNode').one('.plainvalue').one('.pseudotablink').on('focus', M.gradingform_rubriceditor.clickanywhere) + } } } // handler for clicking on submit buttons within rubriceditor element. Adds/deletes/rearranges criteria and/or levels on client side -M.gradingform_rubriceditor.buttonclick = function(e, Y, name, confirmed) { +M.gradingform_rubriceditor.buttonclick = function(e, confirmed) { + var Y = M.gradingform_rubriceditor.Y + var name = M.gradingform_rubriceditor.name if (e.target.get('type') != 'submit') return; + M.gradingform_rubriceditor.disablealleditors() var chunks = e.target.get('id').split('-'), action = chunks[chunks.length-1] if (chunks[0] != name || chunks[1] != 'criteria') return; @@ -100,34 +122,42 @@ M.gradingform_rubriceditor.buttonclick = function(e, Y, name, confirmed) { elements_str = '#rubric-'+name+' .criterion' } // prepare the id of the next inserted level or criterion - var newid = 1 if (action == 'addcriterion' || action == 'addlevel') { - Y.all(elements_str).each( function(node) { - var idchunks = node.get('id').split('-'), id = idchunks.pop(); - if (id.match(/^NEWID(\d+)$/)) newid = Math.max(newid, parseInt(id.substring(5))+1); - } ); + var newid = M.gradingform_rubriceditor.calculatenewid('#rubric-'+name+' .criterion') + var newlevid = M.gradingform_rubriceditor.calculatenewid('#rubric-'+name+' .level') } var dialog_options = { 'scope' : this, - 'callbackargs' : [e, Y, name, true], + 'callbackargs' : [e, true], 'callback' : M.gradingform_rubriceditor.buttonclick }; if (chunks.length == 3 && action == 'addcriterion') { // ADD NEW CRITERION + var nlevels = 3 + var criteria = Y.all('#'+name+'-criteria .criterion') + if (criteria.size()) nlevels = Math.max(nlevels, criteria.item(criteria.size()-1).all('.level').size()) + var levelsstr = ''; + for (var levidx=0;levidxtbody')) parentel = parentel.one('>tbody') parentel.append(newcriterion) - M.gradingform_rubriceditor.addhandlers(Y, name); + M.gradingform_rubriceditor.addhandlers(); + M.gradingform_rubriceditor.assignclasses('#rubric-'+name+' #'+name+'-criteria-NEWID'+newid+'-levels .level') + M.gradingform_rubriceditor.editmode(Y.one('#rubric-'+name+' #'+name+'-criteria-NEWID'+newid+'-description'),true) } else if (chunks.length == 5 && action == 'addlevel') { // ADD NEW LEVEL var newlevel = M.gradingform_rubriceditor.templates[name]['level']. - replace(/\{CRITERION-id\}/g, chunks[2]).replace(/\{LEVEL-id\}/g, 'NEWID'+newid).replace(/\{.+?\}/g, '') + replace(/\{CRITERION-id\}/g, chunks[2]).replace(/\{LEVEL-id\}/g, 'NEWID'+newlevid).replace(/\{.+?\}/g, '') Y.one('#'+name+'-criteria-'+chunks[2]+'-levels').append(newlevel) var levels = Y.all('#'+name+'-criteria-'+chunks[2]+'-levels .level') if (levels.size()) levels.set('width', Math.round(100/levels.size())+'%') - M.gradingform_rubriceditor.addhandlers(Y, name); + M.gradingform_rubriceditor.addhandlers(); + M.gradingform_rubriceditor.editmode(levels.item(levels.size()-1),true) } else if (chunks.length == 4 && action == 'moveup') { // MOVE CRITERION UP el = Y.one('#'+name+'-criteria-'+chunks[2]) @@ -160,7 +190,11 @@ M.gradingform_rubriceditor.buttonclick = function(e, Y, name, confirmed) { } e.preventDefault(); // properly set classes and sortorder - var elements = Y.all(elements_str) + M.gradingform_rubriceditor.assignclasses(elements_str) +} + +M.gradingform_rubriceditor.assignclasses = function (elements_str) { + var elements = M.gradingform_rubriceditor.Y.all(elements_str) for (var i=0;i