MDL-55000 grade: Convert remaining YUI2 -> AMD
authorAndrew Nicols <andrew@nicols.co.uk>
Thu, 23 Jun 2016 05:04:17 +0000 (13:04 +0800)
committerAndrew Nicols <andrew@nicols.co.uk>
Tue, 5 Jul 2016 12:07:46 +0000 (20:07 +0800)
grade/amd/build/edittree_index.min.js [new file with mode: 0644]
grade/amd/src/edittree_index.js [new file with mode: 0644]
grade/edit/tree/functions.js [deleted file]
grade/edit/tree/index.php
grade/edit/tree/lib.php

diff --git a/grade/amd/build/edittree_index.min.js b/grade/amd/build/edittree_index.min.js
new file mode 100644 (file)
index 0000000..b960b82
Binary files /dev/null and b/grade/amd/build/edittree_index.min.js differ
diff --git a/grade/amd/src/edittree_index.js b/grade/amd/src/edittree_index.js
new file mode 100644 (file)
index 0000000..eade80d
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.
+
+/**
+ * Handle add/remove competency links.
+ *
+ * @module     grade
+ * @package    edittree_index
+ * @copyright  2016 Andrew Nicols <andrew@nicols.co.uk>
+ * @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 (file)
index 2da2f01..0000000
+++ /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
index 8384259..0257798 100644 (file)
@@ -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 '<div id="noscriptgradetreeform" class="hiddenifjs">
             <input type="submit" value="'.get_string('go').'" />
           </div>';
index bf4a4a6..8b9e101 100644 (file)
@@ -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 '<label class="accesshide" for="weight_'.$item->id.'">'.
-                get_string('extracreditvalue', 'grades', $itemname).'</label>'.
-                '<input type="text" size="6" id="weight_'.$item->id.'" name="weight_'.$item->id.'"
-                value="'.grade_edit_tree::format_number($item->aggregationcoef).'" />';
+            return '<label class="accesshide" for="weight_'.$item->id.'">' .
+                get_string('extracreditvalue', 'grades', $itemname).'</label>' .
+                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 = '<label class="accesshide" for="select_'.$params['eid'].'">'.
                 get_string('select', 'grades', $item->itemname).'</label>
                 <input class="itemselect ignoredirty" type="checkbox" name="select_'.$params['eid'].'" id="select_'.$params['eid'].
-                '" onchange="toggleCategorySelector();"/>'; // TODO: convert to YUI handler
+                '"/>';
         }
         return $itemcell;
     }