MDL-46731 gradereport_grader: Move tooltips to YUI module

This issue is a part of the MDL-46658 Task.
This issue is a part of the MDL-25544 Epic.
This commit is contained in:
Andrew Nicols
2014-10-03 15:43:16 +08:00
parent d3eec1584a
commit feb0014b84
8 changed files with 526 additions and 123 deletions
+7 -5
View File
@@ -643,7 +643,6 @@ class grade_report_grader extends grade_report {
$usercell = new html_table_cell();
$usercell->attributes['class'] = 'user';
$usercell->attributes['data-uid'] = $userid;
$usercell->header = true;
$usercell->scope = 'row';
@@ -653,7 +652,9 @@ class grade_report_grader extends grade_report {
}
$fullname = fullname($user);
$usercell->text .= html_writer::link(new moodle_url('/user/view.php', array('id' => $user->id, 'course' => $this->course->id)), $fullname);
$usercell->text .= html_writer::link(new moodle_url('/user/view.php', array('id' => $user->id, 'course' => $this->course->id)), $fullname, array(
'class' => 'username',
));
if (!empty($user->suspendedenrolment)) {
$usercell->attributes['class'] .= ' usersuspended';
@@ -689,6 +690,7 @@ class grade_report_grader extends grade_report {
$userrow->cells[] = $fieldcell;
}
$userrow->attributes['data-uid'] = $userid;
$rows[] = $userrow;
}
@@ -929,9 +931,9 @@ class grade_report_grader extends grade_report {
}
if (!empty($grade->feedback)) {
//should we be truncating feedback? ie $short_feedback = shorten_text($feedback, $this->feedback_trunc_length);
$jsarguments['feedback'][] = array('user'=>$userid, 'item'=>$itemid, 'content'=>wordwrap(trim(format_string($grade->feedback, $grade->feedbackformat)),
34, '<br/ >'));
$feedback = wordwrap(trim(format_string($grade->feedback, $grade->feedbackformat)), 34, '<br>');
$itemcell->attributes['data-feedback'] = $feedback;
$jsarguments['feedback'][] = array('user'=>$userid, 'item'=>$itemid, 'content' => $feedback);
}
if ($grade->is_excluded()) {
-113
View File
@@ -11,10 +11,6 @@ M.gradereport_grader = {
* @param {Object} reports A collection of classes used by the grader report module
*/
classes : {},
/**
* @param {Object} tooltip Null or a tooltip object
*/
tooltip : null,
/**
* Instantiates a new grader report
*
@@ -28,73 +24,6 @@ M.gradereport_grader = {
* @param {Array} An array of student grades
*/
init_report : function(Y, id, cfg, items, users, feedback, grades) {
this.tooltip = this.tooltip || {
overlay : null, // Y.Overlay instance
/**
* Attaches the tooltip event to the provided cell
*
* @function M.gradereport_grader.tooltip.attach
* @this M.gradereport_grader
* @param {Y.Node} td The cell to attach the tooltip event to
*/
attach : function(td, report) {
td.on('mouseenter', this.show, this, report);
},
/**
* Shows the tooltip: Callback from @see M.gradereport_grader.tooltip#attach
*
* @function M.gradereport_grader.tooltip.show
* @this {M.gradereport_grader.tooltip}
* @param {Event} e
* @param {M.gradereport_grader.classes.report} report
*/
show : function(e, report) {
e.halt();
var properties = report.get_cell_info(e.target);
if (!properties) {
return;
}
var overriden = /.*overridden.*/g.test(properties.cell.getAttribute('class')) ? 'overriden' : '';
var content = '<div class="graderreportoverlay ' + overriden + '" role="tooltip" aria-describedby="' + properties.id + '">';
content += '<div class="fullname">'+properties.username+'</div><div class="itemname">'+properties.itemname+'</div>';
if (properties.feedback) {
content += '<div class="feedback">'+properties.feedback+'</div>';
}
content += '</div>';
properties.cell.on('mouseleave', this.hide, this, properties.cell);
properties.cell.addClass('tooltipactive');
this.overlay = this.overlay || (function(){
var overlay = new Y.Overlay({
bodyContent : 'Loading',
visible : false,
zIndex : 2
});
overlay.render(report.table.ancestor('div'));
return overlay;
})();
this.overlay.set('xy', [e.target.getX()+(e.target.get('offsetWidth')/2),e.target.getY()+e.target.get('offsetHeight')-5]);
this.overlay.set("bodyContent", content);
this.overlay.show();
this.overlay.get('boundingBox').setStyle('visibility', 'visible');
},
/**
* Hides the tooltip
*
* @function M.gradereport_grader.tooltip.hide
* @this {M.gradereport_grader.tooltip}
* @param {Event} e
* @param {Y.Node} cell
*/
hide : function(e, cell) {
cell.removeClass('tooltipactive');
this.overlay.hide();
this.overlay.get('boundingBox').setStyle('visibility', 'hidden');
}
};
// Create the actual report
this.reports[id] = new this.classes.report(Y, id, cfg, items, users, feedback, grades);
}
@@ -128,18 +57,6 @@ M.gradereport_grader.classes.report = function(Y, id, cfg, items, users, feedbac
this.table = Y.one('#user-grades');
this.grades = grades;
// Alias this so that we can use the correct scope in the coming
// node iteration
this.table.all('tr').each(function(tr){
// Check it is a user row
if (tr.getAttribute('id').match(/^(fixed_)?user_(\d+)$/)) {
// Display tooltips
tr.all('td.cell').each(function(cell){
M.gradereport_grader.tooltip.attach(cell, this);
}, this);
}
}, this);
// If ajax is enabled then initialise the ajax component
if (this.ajaxenabled) {
this.ajax = new M.gradereport_grader.classes.ajax(this, cfg);
@@ -191,13 +108,6 @@ M.gradereport_grader.classes.report.prototype.get_cell_info = function(arg) {
return null;
}
for (i in this.feedback) {
if (this.feedback[i] && this.feedback[i].user == userid && this.feedback[i].item == itemid) {
feedback = this.feedback[i].content;
break;
}
}
return {
id : cell.getAttribute('id'),
userid : userid,
@@ -207,7 +117,6 @@ M.gradereport_grader.classes.report.prototype.get_cell_info = function(arg) {
itemtype : this.items[itemid].type,
itemscale : this.items[itemid].scale,
itemdp : this.items[itemid].decimals,
feedback : feedback,
cell : cell
};
};
@@ -231,28 +140,6 @@ M.gradereport_grader.classes.report.prototype.update_feedback = function(userid,
this.feedback.push({user:userid,item:itemid,content:newfeedback});
return true;
};
/**
* Updates or creates the grade JS structure for the given user/item
*
* @function
* @this {M.gradereport_grader}
* @param {Int} userid
* @param {Int} itemid
* @param {String} newgrade
* @return {Bool}
*/
/*M.gradereport_grader.classes.report.prototype.update_grade = function(userid, itemid, newgrade) {
for (var i in this.grades) {
if (this.grades[i].user == userid && this.grades[i].item == itemid) {
this.grades[i].content = newgrade;
return true;
}
}
this.grades.push({user:userid,item:itemid,content:newgrade});
return true;
};*/
/**
* Initialises the AJAX component of this report
* @class ajax
@@ -882,6 +882,176 @@ FloatingHeaders.prototype = {
};
Y.Base.mix(Y.M.gradereport_grader.ReportTable, [FloatingHeaders]);
// 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/>.
/**
* @module moodle-gradereport_grader-gradereporttable
* @submodule tooltip
*/
/**
* Provides tooltip functionality on the grader report.
*
* See {{#crossLink "M.gradereport_grader.ReportTable"}}{{/crossLink}} for details.
*
* @namespace M.gradereport_grader
* @class Tooltip
*/
function Tooltip() {}
Tooltip.ATTRS= {
};
var CONTENT = '<div class="graderreportoverlay {{overridden}}" role="tooltip" aria-describedby="{{id}}">' +
'<div class="fullname">{{username}}</div><div class="itemname">{{itemname}}</div>' +
'{{#if feedback}}' +
'<div class="feedback">{{feedback}}</div>' +
'{{/if}}' +
'</div>';
Tooltip.prototype = {
/**
* A reference to the tooltip. A single tooltip is lazily instantiated
* and then reused.
*
* @property _tooltip
* @type Overlay
* @protected
*/
_tooltip: null,
/**
* A reference to the boundingBox of the tooltip. This is used as an
* optimisation in the hideTooltip test.
*
* @property _tooltipBoundingBox
* @type Node
* @protected
*/
_tooltipBoundingBox: null,
/**
* The compiled template for the tooltip content.
* This is setup the first time that {{#crossLink "_getTooltip"}}{{/crossLink}} is called.
*
* @property _tooltipTemplate
* @type Function
* @default null
* @protected
*/
_tooltipTemplate: null,
/**
* Setup the tooltip.
*
* @method setupTooltips
* @chainable
*/
setupTooltips: function() {
this._eventHandles.push(
this.graderTable.delegate('hover', this._showTooltip, this._hideTooltip, SELECTORS.GRADECELL, this),
this.graderTable.delegate('click', this._toggleTooltip, SELECTORS.GRADECELL, this)
);
return this;
},
/**
* Prepare and retrieve the tooltip.
*
* @method _getTooltip
* @return Overlay
* @protected
*/
_getTooltip: function() {
if (!this._tooltip) {
this._tooltip = new Y.Overlay({
visible: false,
render: Y.one(SELECTORS.GRADEPARENT)
});
this._tooltipBoundingBox = this._tooltip.get('boundingBox');
this._tooltipTemplate = Y.Handlebars.compile(CONTENT);
this._tooltipBoundingBox.addClass('grader-information-tooltip');
}
return this._tooltip;
},
/**
* Display the tooltip.
*
* @method _showTooltip
* @param {EventFacade} e
* @protected
*/
_showTooltip: function(e) {
var cell = e.currentTarget;
var tooltip = this._getTooltip();
tooltip.set('bodyContent', this._tooltipTemplate({
cellid: cell.get('id'),
username: this.getGradeUserName(cell),
itemname: this.getGradeItemName(cell),
feedback: this.getGradeFeedback(cell),
overridden: cell.hasClass(CSS.OVERRIDDEN) ? CSS.OVERRIDDEN : ''
}))
.set('xy', [
cell.getX() + (cell.get('offsetWidth') / 2),
cell.getY() + (cell.get('offsetHeight') / 2)
])
.show();
e.currentTarget.addClass(CSS.TOOLTIPACTIVE);
},
/**
* Hide the tooltip.
*
* @method _hideTooltip
* @param {EventFacade} e
* @protected
*/
_hideTooltip: function(e) {
if (e.relatedTarget && this._tooltipBoundingBox && this._tooltipBoundingBox.contains(e.relatedTarget)) {
// Do not exit if the user is mousing over the tooltip itself.
return;
}
if (this._tooltip) {
e.currentTarget.removeClass(CSS.TOOLTIPACTIVE);
this._tooltip.hide();
}
},
/**
* Toggle the tooltip between visible and hidden.
*
* @method _toggleTooltip
* @param {EventFacade} e
* @protected
*/
_toggleTooltip: function(e) {
if (e.currentTarget.hasClass(CSS.TOOLTIPACTIVE)) {
this._hideTooltip(e);
} else {
this._showTooltip(e);
}
}
};
Y.Base.mix(Y.M.gradereport_grader.ReportTable, [Tooltip]);
}, '@VERSION@', {"requires": ["base", "node", "event", "node-event-simulate"]});
}, '@VERSION@', {"requires": ["base", "node", "event", "handlebars", "overlay", "event-hover", "node-event-simulate"]});
File diff suppressed because one or more lines are too long
@@ -881,6 +881,176 @@ FloatingHeaders.prototype = {
};
Y.Base.mix(Y.M.gradereport_grader.ReportTable, [FloatingHeaders]);
// 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/>.
/**
* @module moodle-gradereport_grader-gradereporttable
* @submodule tooltip
*/
/**
* Provides tooltip functionality on the grader report.
*
* See {{#crossLink "M.gradereport_grader.ReportTable"}}{{/crossLink}} for details.
*
* @namespace M.gradereport_grader
* @class Tooltip
*/
function Tooltip() {}
Tooltip.ATTRS= {
};
var CONTENT = '<div class="graderreportoverlay {{overridden}}" role="tooltip" aria-describedby="{{id}}">' +
'<div class="fullname">{{username}}</div><div class="itemname">{{itemname}}</div>' +
'{{#if feedback}}' +
'<div class="feedback">{{feedback}}</div>' +
'{{/if}}' +
'</div>';
Tooltip.prototype = {
/**
* A reference to the tooltip. A single tooltip is lazily instantiated
* and then reused.
*
* @property _tooltip
* @type Overlay
* @protected
*/
_tooltip: null,
/**
* A reference to the boundingBox of the tooltip. This is used as an
* optimisation in the hideTooltip test.
*
* @property _tooltipBoundingBox
* @type Node
* @protected
*/
_tooltipBoundingBox: null,
/**
* The compiled template for the tooltip content.
* This is setup the first time that {{#crossLink "_getTooltip"}}{{/crossLink}} is called.
*
* @property _tooltipTemplate
* @type Function
* @default null
* @protected
*/
_tooltipTemplate: null,
/**
* Setup the tooltip.
*
* @method setupTooltips
* @chainable
*/
setupTooltips: function() {
this._eventHandles.push(
this.graderTable.delegate('hover', this._showTooltip, this._hideTooltip, SELECTORS.GRADECELL, this),
this.graderTable.delegate('click', this._toggleTooltip, SELECTORS.GRADECELL, this)
);
return this;
},
/**
* Prepare and retrieve the tooltip.
*
* @method _getTooltip
* @return Overlay
* @protected
*/
_getTooltip: function() {
if (!this._tooltip) {
this._tooltip = new Y.Overlay({
visible: false,
render: Y.one(SELECTORS.GRADEPARENT)
});
this._tooltipBoundingBox = this._tooltip.get('boundingBox');
this._tooltipTemplate = Y.Handlebars.compile(CONTENT);
this._tooltipBoundingBox.addClass('grader-information-tooltip');
}
return this._tooltip;
},
/**
* Display the tooltip.
*
* @method _showTooltip
* @param {EventFacade} e
* @protected
*/
_showTooltip: function(e) {
var cell = e.currentTarget;
var tooltip = this._getTooltip();
tooltip.set('bodyContent', this._tooltipTemplate({
cellid: cell.get('id'),
username: this.getGradeUserName(cell),
itemname: this.getGradeItemName(cell),
feedback: this.getGradeFeedback(cell),
overridden: cell.hasClass(CSS.OVERRIDDEN) ? CSS.OVERRIDDEN : ''
}))
.set('xy', [
cell.getX() + (cell.get('offsetWidth') / 2),
cell.getY() + (cell.get('offsetHeight') / 2)
])
.show();
e.currentTarget.addClass(CSS.TOOLTIPACTIVE);
},
/**
* Hide the tooltip.
*
* @method _hideTooltip
* @param {EventFacade} e
* @protected
*/
_hideTooltip: function(e) {
if (e.relatedTarget && this._tooltipBoundingBox && this._tooltipBoundingBox.contains(e.relatedTarget)) {
// Do not exit if the user is mousing over the tooltip itself.
return;
}
if (this._tooltip) {
e.currentTarget.removeClass(CSS.TOOLTIPACTIVE);
this._tooltip.hide();
}
},
/**
* Toggle the tooltip between visible and hidden.
*
* @method _toggleTooltip
* @param {EventFacade} e
* @protected
*/
_toggleTooltip: function(e) {
if (e.currentTarget.hasClass(CSS.TOOLTIPACTIVE)) {
this._hideTooltip(e);
} else {
this._showTooltip(e);
}
}
};
Y.Base.mix(Y.M.gradereport_grader.ReportTable, [Tooltip]);
}, '@VERSION@', {"requires": ["base", "node", "event", "node-event-simulate"]});
}, '@VERSION@', {"requires": ["base", "node", "event", "handlebars", "overlay", "event-hover", "node-event-simulate"]});
@@ -5,7 +5,8 @@
"jsfiles": [
"gradereporttable.js",
"highlighter.js",
"floatingheaders.js"
"floatingheaders.js",
"tooltip.js"
]
}
}
@@ -0,0 +1,170 @@
// 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/>.
/**
* @module moodle-gradereport_grader-gradereporttable
* @submodule tooltip
*/
/**
* Provides tooltip functionality on the grader report.
*
* See {{#crossLink "M.gradereport_grader.ReportTable"}}{{/crossLink}} for details.
*
* @namespace M.gradereport_grader
* @class Tooltip
*/
function Tooltip() {}
Tooltip.ATTRS= {
};
var CONTENT = '<div class="graderreportoverlay {{overridden}}" role="tooltip" aria-describedby="{{id}}">' +
'<div class="fullname">{{username}}</div><div class="itemname">{{itemname}}</div>' +
'{{#if feedback}}' +
'<div class="feedback">{{feedback}}</div>' +
'{{/if}}' +
'</div>';
Tooltip.prototype = {
/**
* A reference to the tooltip. A single tooltip is lazily instantiated
* and then reused.
*
* @property _tooltip
* @type Overlay
* @protected
*/
_tooltip: null,
/**
* A reference to the boundingBox of the tooltip. This is used as an
* optimisation in the hideTooltip test.
*
* @property _tooltipBoundingBox
* @type Node
* @protected
*/
_tooltipBoundingBox: null,
/**
* The compiled template for the tooltip content.
* This is setup the first time that {{#crossLink "_getTooltip"}}{{/crossLink}} is called.
*
* @property _tooltipTemplate
* @type Function
* @default null
* @protected
*/
_tooltipTemplate: null,
/**
* Setup the tooltip.
*
* @method setupTooltips
* @chainable
*/
setupTooltips: function() {
this._eventHandles.push(
this.graderTable.delegate('hover', this._showTooltip, this._hideTooltip, SELECTORS.GRADECELL, this),
this.graderTable.delegate('click', this._toggleTooltip, SELECTORS.GRADECELL, this)
);
return this;
},
/**
* Prepare and retrieve the tooltip.
*
* @method _getTooltip
* @return Overlay
* @protected
*/
_getTooltip: function() {
if (!this._tooltip) {
this._tooltip = new Y.Overlay({
visible: false,
render: Y.one(SELECTORS.GRADEPARENT)
});
this._tooltipBoundingBox = this._tooltip.get('boundingBox');
this._tooltipTemplate = Y.Handlebars.compile(CONTENT);
this._tooltipBoundingBox.addClass('grader-information-tooltip');
}
return this._tooltip;
},
/**
* Display the tooltip.
*
* @method _showTooltip
* @param {EventFacade} e
* @protected
*/
_showTooltip: function(e) {
var cell = e.currentTarget;
var tooltip = this._getTooltip();
tooltip.set('bodyContent', this._tooltipTemplate({
cellid: cell.get('id'),
username: this.getGradeUserName(cell),
itemname: this.getGradeItemName(cell),
feedback: this.getGradeFeedback(cell),
overridden: cell.hasClass(CSS.OVERRIDDEN) ? CSS.OVERRIDDEN : ''
}))
.set('xy', [
cell.getX() + (cell.get('offsetWidth') / 2),
cell.getY() + (cell.get('offsetHeight') / 2)
])
.show();
e.currentTarget.addClass(CSS.TOOLTIPACTIVE);
},
/**
* Hide the tooltip.
*
* @method _hideTooltip
* @param {EventFacade} e
* @protected
*/
_hideTooltip: function(e) {
if (e.relatedTarget && this._tooltipBoundingBox && this._tooltipBoundingBox.contains(e.relatedTarget)) {
// Do not exit if the user is mousing over the tooltip itself.
return;
}
if (this._tooltip) {
e.currentTarget.removeClass(CSS.TOOLTIPACTIVE);
this._tooltip.hide();
}
},
/**
* Toggle the tooltip between visible and hidden.
*
* @method _toggleTooltip
* @param {EventFacade} e
* @protected
*/
_toggleTooltip: function(e) {
if (e.currentTarget.hasClass(CSS.TOOLTIPACTIVE)) {
this._hideTooltip(e);
} else {
this._showTooltip(e);
}
}
};
Y.Base.mix(Y.M.gradereport_grader.ReportTable, [Tooltip]);
@@ -4,6 +4,9 @@
"base",
"node",
"event",
"handlebars",
"overlay",
"event-hover",
"node-event-simulate"
]
}