From b5233f9bc9b045cebb4085abba21dec92d9253d9 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Thu, 23 Jun 2016 13:04:17 +0800 Subject: [PATCH] MDL-55000 grade: Convert remaining YUI2 -> AMD --- grade/amd/build/edittree_index.min.js | 1 + grade/amd/src/edittree_index.js | 127 +++++++++++++ grade/edit/tree/functions.js | 259 -------------------------- grade/edit/tree/index.php | 4 +- grade/edit/tree/lib.php | 62 ++++-- 5 files changed, 174 insertions(+), 279 deletions(-) create mode 100644 grade/amd/build/edittree_index.min.js create mode 100644 grade/amd/src/edittree_index.js delete mode 100644 grade/edit/tree/functions.js diff --git a/grade/amd/build/edittree_index.min.js b/grade/amd/build/edittree_index.min.js new file mode 100644 index 00000000000..b960b823421 --- /dev/null +++ b/grade/amd/build/edittree_index.min.js @@ -0,0 +1 @@ +define(["jquery"],function(a){var b=function(){a("body").on("change",".itemselect.ignoredirty",b.checkMoveMenuState),a("body").on("click",'[data-action="grade_edittree-index-bulkselect"]',b.toggleAllSelectItems),a("body").on("change",".weightoverride",b.toggleWeightInput),a("#menumoveafter").on("change",function(){var b=a(this).closest("form"),c=b.find("#bulkmoveinput");c.val(1),b.submit()}),b.checkMoveMenuState()};return b.toggleWeightInput=function(b){b.preventDefault();var c=a(this),d=c.closest("tr");a('input[name="weight_'+d.data("itemid")+'"]').prop("disabled",!c.prop("checked"))},b.toggleAllSelectItems=function(c){c.preventDefault();var d=a(this),e=d.closest("tr");a("."+e.data("category")+" .itemselect").prop("checked",d.data("checked")),b.checkMoveMenuState()},b.getMoveMenu=function(){return a("#menumoveafter")},b.checkMoveMenuState=function(){var c=b.getMoveMenu();if(!c.length)return!1;var d;return a(".itemselect").each(function(){return d=a(this).prop("checked"),!d}),c.prop("disabled",!d),d},{enhance:b}}); \ No newline at end of file diff --git a/grade/amd/src/edittree_index.js b/grade/amd/src/edittree_index.js new file mode 100644 index 00000000000..eade80d3e1f --- /dev/null +++ b/grade/amd/src/edittree_index.js @@ -0,0 +1,127 @@ +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see . + +/** + * Handle add/remove competency links. + * + * @module grade + * @package edittree_index + * @copyright 2016 Andrew Nicols + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +define([ + 'jquery', +], function($) { + /** + * Enhance the edittree functionality. + * + * @method edittree + */ + var edittree = function() { + // Watch items and toggle the move menu accordingly. + $('body').on('change', '.itemselect.ignoredirty', edittree.checkMoveMenuState); + + // Watch for the 'All' and 'None' links. + $('body').on('click', '[data-action="grade_edittree-index-bulkselect"]', edittree.toggleAllSelectItems); + + // Watch for the weight override checkboxes. + $('body').on('change', '.weightoverride', edittree.toggleWeightInput); + + // Watch changes to the bulk move menu and submit. + $('#menumoveafter').on('change', function() { + var form = $(this).closest('form'), + bulkmove = form.find('#bulkmoveinput'); + + bulkmove.val(1); + form.submit(); + }); + + // CHeck the initial state of the move menu. + edittree.checkMoveMenuState(); + }; + + /** + * Toggle the weight input field based on its checkbox. + * + * @method toggleWeightInput + * @param {EventFacade} e + * @private + */ + edittree.toggleWeightInput = function(e) { + e.preventDefault(); + var node = $(this), + row = node.closest('tr'); + + $('input[name="weight_' + row.data('itemid') + '"]').prop('disabled', !node.prop('checked')); + }; + + /** + * Toggle all select boxes on or off. + * + * @method toggleAllSelectItems + * @param {EventFacade} e + * @private + */ + edittree.toggleAllSelectItems = function(e) { + e.preventDefault(); + + var node = $(this), + row = node.closest('tr'); + $('.' + row.data('category') + ' .itemselect').prop('checked', node.data('checked')); + + edittree.checkMoveMenuState(); + }; + + /** + * Get the move menu. + * + * @method getMoveMenu + * @private + * @return {jQuery} + */ + edittree.getMoveMenu = function() { + return $('#menumoveafter'); + }; + + /** + * Check whether any checkboxes are ticked. + * + * @method checkMoveMenuState + * @private + * @return {Boolean} + */ + edittree.checkMoveMenuState = function() { + var menu = edittree.getMoveMenu(); + if (!menu.length) { + return false; + } + + var selected; + $('.itemselect').each(function() { + selected = $(this).prop('checked'); + + // Return early if any are checked. + return !selected; + }); + + menu.prop('disabled', !selected); + + return selected; + }; + + return /** @alias module:grade/edittree_index */ { + enhance: edittree + }; +}); diff --git a/grade/edit/tree/functions.js b/grade/edit/tree/functions.js deleted file mode 100644 index 2da2f011658..00000000000 --- a/grade/edit/tree/functions.js +++ /dev/null @@ -1,259 +0,0 @@ -/** - * Toggles the selection checkboxes of all grade items children of the given eid (a category id) - */ -function togglecheckboxes(event, args) { -YUI().use('yui2-dom', 'yui2-element', function (Y) { - - var rows = Y.YUI2.util.Dom.getElementsByClassName(args.eid); - - for (var i = 0; i < rows.length; i++) { - var element = new Y.YUI2.util.Element(rows[i]); - var checkboxes = element.getElementsByClassName('itemselect'); - if (checkboxes[0]) { - checkboxes[0].checked=args.check; - } - } - - toggleCategorySelector(); - -}); -} - -function toggle_advanced_columns() { -YUI().use('yui2-dom', function (Y) { - - var advEls = Y.YUI2.util.Dom.getElementsByClassName("advanced"); - var shownAdvEls = Y.YUI2.util.Dom.getElementsByClassName("advancedshown"); - - for (var i = 0; i < advEls.length; i++) { - Y.YUI2.util.Dom.replaceClass(advEls[i], "advanced", "advancedshown"); - } - - for (var i = 0; i < shownAdvEls.length; i++) { - Y.YUI2.util.Dom.replaceClass(shownAdvEls[i], "advancedshown", "advanced"); - } - -}); -} - -/** - * Check if any of the grade item checkboxes is ticked. If yes, enable the dropdown. Otherwise, disable it - */ -function toggleCategorySelector() { -YUI().use('yui2-dom', function (Y) { - - var menumoveafter = document.getElementById('menumoveafter'); - if (!menumoveafter) { - return; - } - - var itemboxes = Y.YUI2.util.Dom.getElementsByClassName('itemselect'); - for (var i = 0; i < itemboxes.length; i++) { - if (itemboxes[i].checked) { - menumoveafter.disabled = false; - return true; - } - } - menumoveafter.disabled = 'disabled'; - -}); -} - -function submit_bulk_move(e, args) { - document.getElementById('bulkmoveinput').value = 1; - document.getElementById('gradetreeform').submit(); -} - -function update_category_aggregation(e, args) { - var selectmenu = e.target; - window.location = 'index.php?id='+args.courseid+'&category='+args.category+'&aggregationtype='+selectmenu.get('value')+'&sesskey='+args.sesskey; -} - -/** - * The weight override checkboxes toggle the disabled status of their associated weight fields. - */ -YUI().use('node', 'delegate', function(Y) { - Y.on('domready', function() { - Y.delegate('click', function(e) { - var t = e.currentTarget, - itemid = t.get('id').split('_')[1]; - Y.one('input[name=weight_' + itemid + ']').set('disabled', t.get('checked') ? false : true); - }, Y.config.doc.body, 'input.weightoverride'); - }); -}); - -/* TODO: finish and rewrite for YUI3... -Y.YUI2.namespace('grade_edit_tree'); - -(function() { - var Dom = Y.YUI2.util.Dom; - var DDM = Y.YUI2.util.DragDropMgr; - var Event = Y.YUI2.util.Event; - var gretree = Y.YUI2.grade_edit_tree; - - gretree.DDApp = { - - init: function() { - - var edit_tree_table = Dom.get('grade_edit_tree_table'); - var i; - var item_rows = edit_tree_table.getElementsByClassName('item', 'tr'); - var category_rows = edit_tree_table.getElementsByClassName('category', 'tr'); - - new Y.YUI2.util.DDTarget('grade_edit_tree_table'); - - for (i = 0; i < item_rows.length; i++) { - if (!Dom.hasClass(item_rows[i],'categoryitem')) { - new gretree.DDList(item_rows[i]); - } - } - - for (i = 0; i < category_rows.length; i++) { - if (!Dom.hasClass(category_rows[i],'coursecategory')) { - // Find the cell that spans rows for this category - var rowspancell = category_rows[i].getElementsByClassName('name', 'td'); - var rowspan = parseInt(rowspancell[0].previousSibling.rowSpan) + 1; - var rows = Array(rowspan); - var lastRow = category_rows[i]; - - for (var j = 0; j < rowspan; j++) { - rows[j] = lastRow; - lastRow = lastRow.nextSibling; - } - - new gretree.DDList(rows); - } - } - - Y.YUI2.util.Event.on("showButton", "click", this.showOrder); - Y.YUI2.util.Event.on("switchButton", "click", this.switchStyles); - }, - - showOrder: function() { - var parseTable = function(table, title) { - var items = table.getElementsByTagName('tr'); - var out = title + ": "; - - for (i = 0; i < items.length; i++) { - out += items[i].id + ' '; - } - return out; - }; - - var table = Dom.get('grade_edit_tree_table'); - alert(parseTable(table, "Grade edit tree table")); - }, - - switchStyles: function() { - Dom.get('grade_edit_tree_table').className = 'draglist_alt'; - } - }; - - gretree.DDList = function(id, sGroup, config) { - - gretree.DDList.superclass.constructor.call(this, id, sGroup, config); - this.logger = this.logger || Y.YUI2; - var el = this.getDragEl(); - Dom.setStyle(el, 'opacity', 0.67); - - this.goingUp = false; - this.lastY = 0; - }; - - Y.YUI2.extend(gretree.DDList, Y.YUI2.util.DDProxy, { - - startDrag: function(x, y) { - this.logger.log(this.id + ' startDrag'); - - // Make the proxy look like the source element - var dragEl = this.getDragEl(); - var clickEl = this.getEl(); - - Dom.setStyle(clickEl, 'visibility', 'hidden'); - - dragEl.innerHTML = clickEl.innerHTML; - - Dom.setStyle(dragEl, 'color', Dom.getStyle(clickEl, 'color')); - Dom.setStyle(dragEl, 'backgroundColor', Dom.getStyle(clickEl, 'backgroundColor')); - Dom.setStyle(dragEl, 'border', '2px solid gray'); - }, - - endDrag: function(e) { - this.logger.log(this.id + ' endDrag'); - var srcEl = this.getEl(); - var proxy = this.getDragEl(); - - // Show the proxy element and adnimate it to the src element's location - Dom.setStyle(proxy, 'visibility', ''); - var a = new Y.YUI2.util.Motion(proxy, { points: { to: Dom.getXY(srcEl) } }, 0.2, Y.YUI2.util.Easing.easeOut); - var proxyid = proxy.id; - var thisid = this.id; - - // Hide the proxy and show the source element when finished with the animation - a.onComplete.subscribe(function() { - Dom.setStyle(proxyid, 'visibility', 'hidden'); - Dom.setStyle(thisid, 'visibility', ''); - }); - - a.animate(); - }, - - onDragDrop: function(e, id) { - this.logger.log(this.id + ' dragDrop'); - - // If there is one drop interaction, the tr was dropped either on the table, or it was dropped on the current location of the source element - - if (DDM.interactionInfo.drop.length === 1) { - // The position of the cursor at the time of the drop (Y.YUI2.util.Point) - var pt = DDM.interactionInfo.point; - - // The region occupied by the source element at the time of the drop - var region = DDM.interactionInfo.sourceRegion; - - // Check to see if we are over the source element's location. We will append to the bottom of the list once we are sure it was a drop in the negative space - if (!region.intersect(pt)) { - var destEl = Dom.get(id); - var destDD = DDM.getDDById(id); - destEl.appendChild(this.getEl()); - destDD.isEmpty = false; - DDM.refreshCache(); - } - } - }, - - onDrag: function(e) { - - // Keep track of the direction of the drag for use during onDragOver - var y = Event.getPageY(e); - - if (y < this.lastY) { - this.goingUp = true; - } else if (y > this.lastY) { - this.goingUp = false; - } - - this.lastY = y; - }, - - onDragOver: function(e, id) { - var srcEl = this.getEl(); - var destEl = Dom.get(id); - - // We are only concerned with tr items, we ignore the dragover notifications for the table - if (destEl.nodeName.toLowerCase() == 'tr') { - var orig_p = srcEl.parentNode; - var p = destEl.parentNode; - - if (this.goingup) { - p.insertBefore(srcEl, destEl); // insert above - } else { - p.insertBefore(srcEl, destEl.nextSibling); // insert below - } - - DDM.refreshCache(); - } - } - }); - // Y.YUI2.util.Event.onDOMReady(gretree.DDApp.init, gretree.DDApp, true); // Uncomment this line when dragdrop is fully implemented -})(); -*/ \ No newline at end of file diff --git a/grade/edit/tree/index.php b/grade/edit/tree/index.php index 838425934d0..02577987ab1 100644 --- a/grade/edit/tree/index.php +++ b/grade/edit/tree/index.php @@ -45,8 +45,7 @@ require_login($course); $context = context_course::instance($course->id); require_capability('moodle/grade:manage', $context); -// todo $PAGE->requires->js_module() should be used here instead -$PAGE->requires->js('/grade/edit/tree/functions.js'); +$PAGE->requires->js_call_amd('grades/edittree_index', 'enhance'); /// return tracking object $gpr = new grade_plugin_return(array('type'=>'edit', 'plugin'=>'tree', 'courseid'=>$courseid)); @@ -266,7 +265,6 @@ if (!$moving && count($grade_edit_tree->categories) > 1) { $attributes = array('id'=>'menumoveafter', 'class' => 'ignoredirty singleselect'); echo html_writer::label(get_string('moveselectedto', 'grades'), 'menumoveafter'); echo html_writer::select($grade_edit_tree->categories, 'moveafter', '', array(''=>'choosedots'), $attributes); - $OUTPUT->add_action_handler(new component_action('change', 'submit_bulk_move'), 'menumoveafter'); echo '
'; diff --git a/grade/edit/tree/lib.php b/grade/edit/tree/lib.php index bf4a4a6c6de..8b9e101fe19 100644 --- a/grade/edit/tree/lib.php +++ b/grade/edit/tree/lib.php @@ -295,6 +295,8 @@ class grade_edit_tree { $row = new html_table_row(); $row->id = 'grade-item-' . $eid; $row->attributes['class'] = $courseclass . ' category ' . $dimmed; + $row->attributes['data-category'] = $eid; + $row->attributes['data-itemid'] = $category->get_grade_item()->id; foreach ($rowclasses as $class) { $row->attributes['class'] .= ' ' . $class; } @@ -309,9 +311,14 @@ class grade_edit_tree { foreach ($this->columns as $column) { if (!($this->moving && $column->hide_when_moving)) { - $row->cells[] = $column->get_category_cell($category, $levelclass, array('id' => $id, - 'name' => $object->name, 'level' => $level, 'actions' => $actions, - 'moveaction' => $moveaction, 'eid' => $eid)); + $row->cells[] = $column->get_category_cell($category, $levelclass, [ + 'id' => $id, + 'name' => $object->name, + 'level' => $level, + 'actions' => $actions, + 'moveaction' => $moveaction, + 'eid' => $eid, + ]); } } @@ -344,6 +351,7 @@ class grade_edit_tree { $gradeitemrow = new html_table_row(); $gradeitemrow->id = 'grade-item-' . $eid; $gradeitemrow->attributes['class'] = $categoryitemclass . ' item ' . $dimmed; + $gradeitemrow->attributes['data-itemid'] = $object->id; foreach ($rowclasses as $class) { $gradeitemrow->attributes['class'] .= ' ' . $class; } @@ -392,20 +400,35 @@ class grade_edit_tree { $str = ''; if ($aggcoef == 'aggregationcoefweight' || $aggcoef == 'aggregationcoef' || $aggcoef == 'aggregationcoefextraweight') { - return ''. - ''; + return '' . + html_writer::empty_tag('input', [ + 'type' => 'text', + 'size' => 6, + 'id' => 'weight_' . $item->id, + 'name' => 'weight_' . $item->id, + 'value' => self::format_number($item->aggregationcoef), + ]); + } else if ($aggcoef == 'aggregationcoefextraweightsum') { $checkboxname = 'weightoverride_' . $item->id; $checkboxlbl = html_writer::tag('label', get_string('overrideweightofa', 'grades', $itemname), array('for' => $checkboxname, 'class' => 'accesshide')); - $checkbox = html_writer::empty_tag('input', array('name' => $checkboxname, - 'type' => 'hidden', 'value' => 0)); - $checkbox .= html_writer::empty_tag('input', array('name' => $checkboxname, - 'type' => 'checkbox', 'value' => 1, 'id' => $checkboxname, 'class' => 'weightoverride', - 'checked' => ($item->weightoverride ? 'checked' : null))); + $checkbox = html_writer::empty_tag('input', [ + 'name' => $checkboxname, + 'type' => 'hidden', + 'value' => 0, + ]); + + $checkbox .= html_writer::empty_tag('input', [ + 'name' => $checkboxname, + 'type' => 'checkbox', + 'value' => 1, + 'id' => $checkboxname, + 'class' => 'weightoverride', + 'checked' => ($item->weightoverride ? 'checked' : null), + ]); $name = 'weight_' . $item->id; $hiddenlabel = html_writer::tag( @@ -854,15 +877,20 @@ class grade_edit_tree_column_select extends grade_edit_tree_column { } public function get_category_cell($category, $levelclass, $params) { - global $OUTPUT; if (empty($params['eid'])) { throw new Exception('Array key (eid) missing from 3rd param of grade_edit_tree_column_select::get_category_cell($category, $levelclass, $params)'); } - $selectall = new action_link(new moodle_url('#'), get_string('all'), new component_action('click', 'togglecheckboxes', array('eid' => $params['eid'], 'check' => true))); - $selectnone = new action_link(new moodle_url('#'), get_string('none'), new component_action('click', 'togglecheckboxes', array('eid' => $params['eid'], 'check' => false))); + $selectall = html_writer::link('#', get_string('all'), [ + 'data-action' => 'grade_edittree-index-bulkselect', + 'data-checked' => true, + ]); + $selectnone = html_writer::link('#', get_string('none'), [ + 'data-action' => 'grade_edittree-index-bulkselect', + 'data-checked' => false, + ]); $categorycell = parent::get_category_cell($category, $levelclass, $params); - $categorycell->text = $OUTPUT->render($selectall) . ' / ' . $OUTPUT->render($selectnone); + $categorycell->text = $selectall . ' / ' . $selectnone; return $categorycell; } @@ -876,7 +904,7 @@ class grade_edit_tree_column_select extends grade_edit_tree_column { $itemcell->text = ' '; // TODO: convert to YUI handler + '"/>'; } return $itemcell; }