gradebook-graderreport MDL-21535 Upgraded to YUI3 and reoganised JS code

This commit is contained in:
Sam Hemelryk 2010-02-16 08:26:21 +00:00
parent e9b66095a3
commit fe21336587
10 changed files with 1380 additions and 866 deletions

View File

@ -1,582 +0,0 @@
<script type="text/javascript">
//<![CDATA[
// If the mouse is clicked outside this element, the edit is CANCELLED (even if the mouse clicks another grade/feedback cell)
// If ctrl-arrow is used, or if [tab] or [enter] are pressed, the edit is RECORDED and the row is updated. The previous element returns to normal
YAHOO.namespace("grader_report");
YAHOO.grader_report.el_being_edited = null;
YAHOO.grader_report.courseid = <?php echo $COURSE->id; ?>;
YAHOO.grader_report.wwwroot = '<?php echo $CFG->wwwroot; ?>';
YAHOO.grader_report.straddfeedback = '<?php echo get_string("addfeedback", "grades"); ?>';
YAHOO.grader_report.strfeedback = '<?php echo get_string("feedback", "grades"); ?>';
YAHOO.grader_report.feedback_trunc_length = <?php echo $report->feedback_trunc_length ?>;
YAHOO.grader_report.decimalpoints = <?php echo $report->getItemsDecimalPoints() ?>;
YAHOO.grader_report.studentsperpage = <?php echo $report->get_pref('studentsperpage'); ?>;
YAHOO.grader_report.showquickfeedback = <?php echo $report->get_pref('showquickfeedback'); ?>;
// Feedback data is cached in a JS array: we don't want to show complete feedback strings in the report, but
// neither do we want to fetch the feedback from PHP each time we click one to edit it
YAHOO.grader_report.feedbacks = <?php echo $report->getFeedbackJsArray(); ?>
/**
* Given an elementId formatted as grade[cell|value|feedback]_u[$userId]-i[$itemId], returns an object with key-value pairs
* @param string elId
* @return object
*/
YAHOO.grader_report.getIdData = function(elId) {
var re = /grade(value|feedback|cell|scale)_([0-9]*)-i([0-9]*)/;
var matches = re.exec(elId);
if (undefined != matches && matches.length > 0) {
return {type: matches[1], userId: matches[2], itemId: matches[3]};
} else {
YAHOO.log("getIdData: Invalid elementId: " + elId, "warn");
return false;
}
};
/**
* Reverse-engineering of getIdData: returns a string based on an object
* @param object idData
* @return string
*/
YAHOO.grader_report.getElementId = function(idData) {
if (undefined != idData.userId && undefined != idData.type && undefined != idData.itemId) {
return "grade" + idData.type + "_" + idData.userId + "-i" + idData.itemId;
} else {
YAHOO.log("getElementId: Invalid elementId: " + idData, "warn");
return false;
}
};
/**
* Interface to the overlib js library. DEPENDENCY ALERT!
*/
YAHOO.grader_report.tooltip = function(e, dataObj) {
var gr = YAHOO.grader_report;
if (undefined != dataObj.text) {
return overlib(dataObj.text, BORDER, 0, FGCLASS, 'feedback', CAPTIONFONTCLASS, 'caption', CAPTION, gr.strfeedback);
} else {
return null;
}
};
/**
* Sends the record request and un-edits the element
* @param object editedEl The DOM element being edited, whose value we are trying to save in DB
* @return array An array of values used to update the row
*/
YAHOO.grader_report.saveField = function(editedEl) {
var gr = YAHOO.grader_report;
var idData = gr.getIdData(editedEl.id);
if (idData.type == 'value') { // Text input
var newVal = editedEl.firstChild.value;
} else if (idData.type == 'feedback') { // Textarea
var newVal = editedEl.firstChild.innerHTML;
} else if (idData.type == 'scale') { // Select
var newVal = editedEl.options[editedEl.selectedIndex].value;
}
// Don't save if the new value is the same as the old
if (gr.el_being_edited.value == newVal || (gr.el_being_edited.value == gr.straddfeedback && newVal == '')) {
YAHOO.log("saveField: Field unchanged, not saving. (" + newVal + ")", "info");
return false;
}
YAHOO.log("saveField: Old value: " + gr.el_being_edited.value + ", new value: " + newVal + ". Saving field...", "info");
var postData = "id=" + gr.courseid + "&userid=" + idData.userId + "&itemid=" + idData.itemId +
"&action=update&newvalue=" + newVal + "&type=" + idData.type;
var handleSuccess = function(o) {
try {
var queryResult = YAHOO.lang.JSON.parse(o.responseText);
} catch (e) {
YAHOO.log("saveField: JSON syntax error! " + o.responseText, "error");
}
if (queryResult.result == "success") {
// For a textarea, truncate the feedback to 40 chars and provide a tooltip with the full text
if (queryResult.gradevalue == null) {
if (idData.type == 'scale') {
editedEl.selectedIndex = 0;
} else {
editedEl.innerHTML = '';
}
} else if (idData.type == 'feedback') {
editedEl.innerHTML = gr.truncateText(queryResult.gradevalue);
YAHOO.util.Event.addListener(editedEl.id, 'mouseover', gr.tooltip, {text: queryResult.gradevalue}, true);
YAHOO.util.Event.addListener(editedEl.id, 'mouseout', nd); // See overlib doc for reference
gr.feedbacks[idData.userId][idData.itemId] = queryResult.gradevalue;
} else if (idData.type == 'value') {
editedEl.innerHTML = gr.roundValue(queryResult.gradevalue, idData.itemId);
}
YAHOO.util.Dom.addClass(editedEl, "editable");
// TODO "highlight" the updated element using animation of color (yellow fade-out)
// Update the row's final grade values
gr.updateRow(gr.getIdData(editedEl.id).userId, queryResult.row);
} else {
}
// Display message
gr.displayMessage(queryResult.result, queryResult.message, editedEl);
}
var handleFailure = function(o) {
YAHOO.log("saveField: Failure to call the ajax callbacks page!", "error");
}
var uri = gr.wwwroot + '/grade/report/grader/ajax_callbacks.php';
var callback = {success: handleSuccess, failure: handleFailure};
var conn = YAHOO.util.Connect.asyncRequest("post", uri, callback, postData);
}; // End of saveField function
/**
* Displays a message in the message bar above the report, Google-style
* @param string result "success", "notice" or "error"
* @param string message
* @param object An element to highlight
*/
YAHOO.grader_report.displayMessage = function(result, message, elToHighlight) {
var messageDiv = document.getElementById('grader_report_message');
// Remove previous message
// TODO log messages in DB?
messageDiv.innerHTML = '';
if (message.length < 1 || !message) {
return false;
}
// Remove all state classes first
YAHOO.util.Dom.removeClass(messageDiv, 'success');
YAHOO.util.Dom.removeClass(messageDiv, 'error');
YAHOO.util.Dom.removeClass(messageDiv, 'notice');
var attributes = {backgroundColor: { to: '#00F0F0'} };
// Add result class
YAHOO.util.Dom.addClass(messageDiv, result);
messageDiv.innerHTML = message;
// Highlight given element
if (result == 'error' && elToHighlight != null) {
YAHOO.util.Dom.addClass(elToHighlight, 'error');
}
};
/**
* Given a userId and an array of string values, updates the innerHTML of each grade cell in the row
* @param string userId Identifies the correct row
* @param array An array of values
*
*/
YAHOO.grader_report.updateRow = function(userId, row) {
var gr = YAHOO.grader_report;
// Send update request and update the row
YAHOO.log("updateRow: Updating row..." + row, "info");
for (var i in row) {
if (row[i].finalgrade != null) {
// Build id string
var gradevalue = gr.roundValue(row[i].finalgrade, row[i].itemid);
if (row[i].scale) {
var idString = "gradescale_";
} else {
var idString = "gradevalue_";
}
idString += row[i].userid + "-i" + row[i].itemid;
var elementToUpdate = document.getElementById(idString);
if (undefined == elementToUpdate) {
YAHOO.log("updateRow: Element with id " + idString + " does not exist!", "error");
} else {
if (row[i].scale) {
elementToUpdate.selectedIndex = gradevalue;
} else {
elementToUpdate.innerHTML = gradevalue;
}
// Add overridden class where it applies, and remove it where it does not
// TODO fix the code below, it doesn't currently work. See ajax_callbacks.php for the code building the JSON data
if (row[i].overridden > 0) {
YAHOO.util.Dom.addClass(elementToUpdate.parentNode, "overridden");
} else if (YAHOO.util.Dom.hasClass(elementToUpdate.parentNode, "overridden")) {
YAHOO.util.Dom.removeClass(elementToUpdate.parentNode, "overridden");
}
YAHOO.log("updateRow: Updated finalgrade (" + gradevalue + ") of user " + row[i].userid + " for grade item " + row[i].itemid, "info");
}
}
}
};
/**
* Given a gradevalue or gradefeedback <a> element,
* @param object element A DOM element
*/
YAHOO.grader_report.openField = function(element) {
YAHOO.log("openField: Moving to next item: " + element.id, "info");
var gr = YAHOO.grader_report;
var idData = gr.getIdData(element.id);
element.inputId = element.id + "_input";
// If field is in error, empty it before editing
if (YAHOO.util.Dom.hasClass(element, 'error')) {
if (idData.type == 'feedback') {
element.innerHTML = '';
} else if (idData.type == 'value') {
element.value = '';
}
YAHOO.util.Dom.removeClass(element, 'error');
}
// Show a textarea for feedback, input for grade and leave scale as it is
if (undefined == idData.type) {
YAHOO.log("openField: Could not get info from elementId: " + element.id, "warn");
} else if (idData.type == 'feedback') {
var original = gr.feedbacks[idData.userId][idData.itemId].toString();
var tabIndex = element.tabIndex.toString();
var displayValue = null;
// If empty feedback, show empty textarea
if (original == gr.straddfeedback) {
displayValue = '';
} else {
displayValue = original;
}
element.innerHTML = '<textarea id="' + element.inputId + '" name="' + idData.type + '">' + displayValue + '</textarea>';
setTimeout(function() {element.firstChild.focus(); }, 0);
} else if (idData.type == 'value') {
var original = element.innerHTML.toString(); // Removes reference to original
element.innerHTML = '<input onfocus="this.select()" id="' + element.inputId + '" type="text" name="' +
idData.type + '" value="' + gr.roundValue(original, idData.itemId) + '" />';
setTimeout(function() {element.firstChild.focus(); }, 0);
} else if (idData.type == 'scale') {
var original = element.options[element.selectedIndex].value;
setTimeout(function() {element.focus(); }, 0);
}
YAHOO.util.Dom.removeClass(element, "editable");
// Save the element and its original value
gr.el_being_edited = {elementId: element.id, value: original, tabIndex: tabIndex};
YAHOO.log("openField: el_being_edited saved as: " + gr.el_being_edited.value, "info");
}
/**
* Replaces the input, textarea or select inside a gradecell with the value currently held in that
* input, textarea or select. If the second argument (cancel) is true, replaces the innerHTML with
* the value held in YAHOO.grader_report.el_being_edited
*
* @param object element DOM element being closed
* @param boolean forcecancel If true, current value held in input element is dropped in favour of original value in memory
*/
YAHOO.grader_report.closeField = function(element, forcecancel) {
YAHOO.log("closeField: Closing field: " + element.id, "info");
var gr = YAHOO.grader_report;
var idData = gr.getIdData(element.id);
if (idData.type == 'feedback') {
var newValue = element.firstChild.value;
var originalValue = gr.feedbacks[idData.userId][idData.itemId];
if (!forcecancel && originalValue == newValue) {
YAHOO.log("closeField: originalValue == newvalue, forcing a cancel", "info");
forcecancel = true;
originalValue = gr.truncateText(originalValue);
}
} else if (idData.type == 'value') {
var originalValue = gr.el_being_edited.value;
var newValue = element.firstChild.value;
}
YAHOO.util.Dom.addClass(element, "editable");
// No need to change HTML for select element
if (idData.type == 'scale') {
gr.el_being_edited = null;
return;
}
if (forcecancel || ((newValue == '' && idData.type == 'feedback') && idData.type != 'scale')) {
// Replace the input by the original value as plain text
element.innerHTML = gr.truncateText(originalValue);
YAHOO.log("closeField: Cancelling : Replacing field by original value: " + originalValue, "info");
} else {
// For numeric grades, round off to item decimal points
if (idData.type == 'value') {
element.innerHTML = gr.roundValue(newValue, idData.itemId);
} else if (idData.type == 'feedback') {
element.innerHTML = newValue;
}
}
// Erase the element in memory
gr.el_being_edited = null;
};
/**
* Given a string, truncates it if over the limit defined in the report's preferences, adding an ellipsis at the end.
* TODO improve the regex so that it doesn't truncate halfway through a word
* @param string text
* @return string
*/
YAHOO.grader_report.truncateText = function(text) {
var gr = YAHOO.grader_report;
var returnString = '';
returnString = text.substring(0, gr.feedback_trunc_length);
// Add ... if the string was truncated
if (returnString.length < text.length) {
returnString += '...';
}
return returnString;
}
/**
* Given a float value and an itemId, uses that grade_item's decimalpoints preference to round off the value and return it.
* @param float value
* @param int itemId
* @return string
*/
YAHOO.grader_report.roundValue = function(value, itemId) {
return value;
// I am ignoring the rest for now, because I am not sure we should round values while in editing mode
if (value.length == 0) {
return '';
}
var gr = YAHOO.grader_report;
var decimalpoints = gr.decimalpoints[itemId];
var gradevalue = Math.round(Number(value) * Math.pow(10, decimalpoints)) / Math.pow(10, decimalpoints);
// If the value is an integer, add appropriate zeros after the decimal point
if (gradevalue % 1 == 0 && decimalpoints > 0) {
gradevalue += '.';
for (var i = 0; i < decimalpoints; i++) {
gradevalue += '0';
}
}
return gradevalue;
};
/**
* Given an element of origin, returns the field to be edited in the given direction.
* @param object origin_element
* @param string direction previous|next|left|right|up|down
* @return object element
*/
YAHOO.grader_report.getField = function(origin_element, direction) {
var gr = YAHOO.grader_report;
// get all 'editable' elements
var haystack = YAHOO.util.Dom.getElementsByClassName('editable');
var wrapElement = null;
var feedbackModifier = 1;
var upDownOffset = 1;
var idData = gr.getIdData(origin_element.id);
if (gr.showquickfeedback) {
feedbackModifier = 2;
if (idData.type == 'value' || idData.type == 'scale') {
upDownOffset = gr.studentsperpage;
}
}
if (direction == 'next') {
var wrapValue = 1;
var needle = origin_element.tabIndex + 1;
} else if (direction == 'previous') {
var wrapValue = haystack.length;
var needle = origin_element.tabIndex - 1;
} else if (direction == 'right') {
var needle = origin_element.tabIndex + gr.studentsperpage * feedbackModifier;
var wrapValue = null; // TODO implement wrapping when moving right
} else if (direction == 'left') {
var needle = origin_element.tabIndex - gr.studentsperpage * feedbackModifier;
var wrapValue = null; // TODO implement wrapping when moving left
} else if (direction == 'up') {
// Jump up from value to feedback: origin + (studentsperpage - 1)
if (idData.type == 'value' || idData.type == 'scale') {
var upDownOffset = gr.studentsperpage - 1;
// Jump up from feedback to value: origin - studentsperpage
} else if (idData.type == 'feedback') {
var upDownOffset = -(gr.studentsperpage);
}
var needle = origin_element.tabIndex + upDownOffset;
var wrapValue = haystack.length;
} else if (direction == 'down') {
// Jump down from value to feedback: origin + studentsperpage
if (idData.type == 'value' || idData.type == 'scale') {
var upDownOffset = gr.studentsperpage;
// Jump down from feedback to value: origin - (studentsperpage - 1)
} else if (idData.type == 'feedback') {
var upDownOffset = -(gr.studentsperpage - 1);
}
var needle = origin_element.tabIndex + upDownOffset;
var wrapValue = 1;
}
for (var i = 0; i < haystack.length; i++) {
if (haystack[i].tabIndex == wrapValue) {
wrapElement = haystack[i];
}
if (haystack[i].tabIndex == needle) {
return haystack[i];
}
}
// If we haven't returned yet, it means we have reached the end of tabindices: return the wrap element
if (wrapElement != null) {
return wrapElement;
} else { // If no wrap element, just return the element of origin: we are stuck!
return origin_element;
}
};
YAHOO.grader_report.init = function() {
var gr = YAHOO.grader_report;
// Handle Key presses: Tab and Enter
this.keyHandler = function(e) {
var charCode = YAHOO.util.Event.getCharCode(e);
YAHOO.log("init: Key pressed (" + charCode + "). el_being_edited = " + gr.el_being_edited, "info");
// Handle keys if editing
if (gr.el_being_edited !== null) {
var editedEl = document.getElementById(gr.el_being_edited.elementId);
var idData = gr.getIdData(editedEl.id);
// Handle Tab and Shift-Tab for navigation forward/backward
if (charCode == 9) {
gr.saveField(editedEl);
gr.closeField(editedEl, false);
if (e.shiftKey) {
var fieldToOpen = gr.getField(editedEl, 'previous');
} else {
var fieldToOpen = gr.getField(editedEl, 'next');
}
gr.openField(fieldToOpen);
}
// Handle Enter key press
if (charCode == 13 && idData.type != 'feedback') { // textareas need [enter]
// Locate element being edited
var editedEl = document.getElementById(gr.el_being_edited.elementId);
gr.saveField(editedEl);
gr.closeField(editedEl, false);
}
// Handle ctrl-arrows
var arrows = { 37: "left", 38: "up", 39: "right", 40: "down" };
if (e.ctrlKey && (charCode == 37 || charCode == 38 || charCode == 39 || charCode == 40)) {
gr.saveField(editedEl);
gr.closeField(editedEl, false);
var fieldToOpen = gr.getField(editedEl, arrows[charCode]);
gr.openField(fieldToOpen);
}
}
}
// Handle mouse clicks
this.clickHandler = function(e) {
var clickTargetElement = YAHOO.util.Event.getTarget(e);
// Handle a click while a grade value or feedback is being edited
if (gr.el_being_edited !== null) {
// idData represents the element being edited, not the clicked element
var idData = gr.getIdData(gr.el_being_edited.elementId);
if (idData.type != 'scale') {
// If clicking in a cell being edited, no action
// parentNode is the original a to which the element was added as a Child node
if (gr.el_being_edited.elementId == clickTargetElement.parentNode.id) {
YAHOO.log("init: Clicked within the edited element, no action.", "info");
return false;
}
// Otherwise, we CANCEL the current edit
var originalTarget = document.getElementById(gr.el_being_edited.elementId);
YAHOO.log("init: Clicked out of the edited element, cancelling edit.", "info");
gr.closeField(originalTarget, true);
} else if (idData.type == 'scale' && gr.el_being_edited.elementId == clickTargetElement.id) {
// An option has been selected, update the element
gr.saveField(clickTargetElement);
// Then open the element to save the new value in el_being_edited
gr.openField(clickTargetElement);
return;
}
}
while (clickTargetElement.id != 'grade-report-grader-index') {
anchor_re = /(gradevalue|gradefeedback|gradescale)(.*) editable/;
anchor_matches = anchor_re.exec(clickTargetElement.className);
// YAHOO.log("className = " + clickTargetElement.className, "info");
var nodeName = clickTargetElement.nodeName.toLowerCase();
if ((nodeName == 'a' || nodeName == 'select') && anchor_matches) {
gr.openField(clickTargetElement);
break;
// If clicked anywhere else in the cell, default to editing the grade, not the feedback
} else if (clickTargetElement.nodeName.toLowerCase() == "td" && clickTargetElement.id.match(/gradecell/)) {
anchors = YAHOO.util.Dom.getElementsByClassName("editable", "a", clickTargetElement);
if (anchors.length > 0) {
clickTargetElement = anchors[0];
} else {
break;
}
} else {
clickTargetElement = clickTargetElement.parentNode;
}
}
}
YAHOO.util.Event.on("grade-report-grader-index", "click", this.clickHandler);
YAHOO.util.Event.on(document, "keydown", this.keyHandler, this, true);
};
YAHOO.util.Event.onDOMReady(YAHOO.grader_report.init);
// ]]>
</script>

View File

@ -25,6 +25,7 @@ require_once($CFG->dirroot . '/grade/report/grader/lib.php');
* Class providing an API for the grader report building and displaying.
* @uses grade_report
* @package gradebook
* @todo MDL-21562 Look at this class + its methods and try to work out what is still required
*/
class grade_report_grader_ajax extends grade_report_grader {
@ -131,6 +132,7 @@ class grade_report_grader_ajax extends grade_report_grader {
/**
* Builds and return the HTML rows of the table (grades headed by student).
* @todo MDL-21562 Is this still used anywhere
* @return string HTML
*/
function get_studentshtml() {
@ -154,6 +156,9 @@ class grade_report_grader_ajax extends grade_report_grader {
/**
* Given a userid, and provided the gtree is correctly loaded, returns a complete HTML row for this user.
*
* @todo MDL-21562 Apparently not used anywhere please check
* @todo MDL-21562 Calls to JavaScript function `set_row` will no longer work
* and need to be replaced
* @param object $user
* @return string
*/

View File

@ -1,32 +0,0 @@
/** highlight/unset the row of a table **/
function set_row(idx) {
var table = document.getElementById('user-grades');
var rowsize = table.rows[idx].cells.length;
for (var i = 0; i < rowsize; i++) {
if (table.rows[idx].cells[i]) {
if (table.rows[idx].cells[i].className.search(/hmarked/) != -1) {
table.rows[idx].cells[i].className = table.rows[idx].cells[i].className.replace(' hmarked', '');
} else {
table.rows[idx].cells[i].className += ' hmarked';
}
}
}
}
function yui_set_row(e) {
set_row(this.parentNode.rowIndex);
}
/** highlight/unset the column of a table **/
function set_col(idx) {
var table = document.getElementById('user-grades');
for (var i = 1; i < table.rows.length; i++) {
if (table.rows[i].cells[idx]) {
if (table.rows[i].cells[idx].className.search(/vmarked/) != -1) {
table.rows[i].cells[idx].className = table.rows[i].cells[idx].className.replace(' vmarked', '');
} else {
table.rows[i].cells[idx].className += ' vmarked';
}
}
}
}

View File

@ -1,141 +0,0 @@
YAHOO.namespace("graderreport");
YAHOO.graderreport.init = function() {
// attach event listener to the table for mouseover and mouseout
var table = document.getElementById('user-grades');
YAHOO.util.Event.on(table, 'mouseover', YAHOO.graderreport.mouseoverHandler);
YAHOO.util.Event.on(table, 'mouseout', YAHOO.graderreport.mouseoutHandler);
// Make single panel that can be dynamically re-rendered wit the right data.
YAHOO.graderreport.panelEl = new YAHOO.widget.Panel("tooltipPanel", {
draggable: false,
visible: false,
close: false,
preventcontextoverlap: true,
underlay: 'none'
});
YAHOO.graderreport.panelEl.render(table);
};
YAHOO.graderreport.mouseoverHandler = function (e) {
var tempNode = '';
var searchString = '';
var tooltipNode = '';
// get the element that we just moved the mouse over
var elTarget = YAHOO.util.Event.getTarget(e);
// if it was part of the yui panel, we don't want to redraw yet
searchString = /fullname|itemname|feedback/;
if (elTarget.className.search(searchString) > -1) {
return false;
}
// move up until we are in the actual cell, not any other child div or span
while (elTarget.id != 'user-grades') {
if(elTarget.nodeName.toUpperCase() == "TD") {
break;
} else {
elTarget = elTarget.parentNode;
}
}
// only make a tooltip for cells with grades
if (elTarget.className.search('grade cell') > -1) {
// each time we go over a new cell, we need to put it's tooltip into a div to stop it from
// popping up on top of the panel.
// don't do anything if we have already made the tooltip div
var makeTooltip = true;
for (var k=0; k < elTarget.childNodes.length; k++) {
if (typeof(elTarget.childNodes[k].className) != 'undefined') {
if (elTarget.childNodes[k].className.search('tooltipDiv') > -1) {
makeTooltip = false;
}
}
}
// if need to, make the tooltip div and append it to the cell
if (makeTooltip) {
tempNode = document.createElement("div");
tempNode.className = "tooltipDiv";
tempNode.innerHTML = elTarget.title;
elTarget.appendChild(tempNode);
elTarget.title = null;
}
// Get the tooltip div
elChildren = elTarget.childNodes;
for (var m=0; m < elChildren.length; m++) {
if (typeof(elChildren[m].className) != 'undefined') {
if (elChildren[m].className.search('tooltipDiv') > -1) {
tooltipNode = elChildren[m];
break;
}
}
}
//build and show the tooltip (if not empty)
if(tooltipNode.innerHTML)
{
YAHOO.graderreport.panelEl.setBody(tooltipNode.innerHTML);
YAHOO.graderreport.panelEl.render(elTarget);
YAHOO.graderreport.panelEl.show();
}
}
};
// only hide the overlay if the mouse has not moved over it
YAHOO.graderreport.mouseoutHandler = function (e) {
var classVar = '';
var searchString = '';
var newTargetClass = '';
var newTarget = YAHOO.util.Event.getRelatedTarget(e);
// deals with an error if the mouseout event is over the lower scrollbar
try {
classVar = newTarget.className;
} catch (err) {
YAHOO.graderreport.panelEl.hide()
return false;
}
// if we are over any part of the panel, do not hide
// do this by walking up the DOM till we reach table level, looking for panel tag
while ((typeof(newTarget.id) == 'undefined') || (newTarget.id != 'user-grades')) {
try {
newTargetClass = newTarget.className;
} catch (err) {
// we've gone over the scrollbar again
YAHOO.graderreport.panelEl.hide()
return false;
}
searchString = /yui-panel|grade cell/;
if (newTargetClass.search(searchString) > -1) {
// we're in the panel so don't hide it
return false;
}
if (newTarget.nodeName.toUpperCase() == "HTML") {
// we missed the user-grades table altogether by moving down off screen to read a long one
YAHOO.graderreport.panelEl.hide()
break;
}
newTarget = newTarget.parentNode;
}
// no panel so far and we went up to the
YAHOO.graderreport.panelEl.hide()
};
YAHOO.util.Event.onDOMReady(YAHOO.graderreport.init);

View File

@ -110,17 +110,6 @@ $reportname = get_string('modulename', 'gradereport_grader');
// Initialise the grader report object
$report = new grade_report_grader($courseid, $gpr, $context, $page, $sortitemid);
$PAGE->requires->yui2_lib('event');
$PAGE->requires->yui2_lib('json');
$PAGE->requires->yui2_lib('connection');
$PAGE->requires->yui2_lib('dragdrop');
$PAGE->requires->yui2_lib('element');
$PAGE->requires->yui2_lib('container');
$PAGE->requires->js('/grade/report/grader/functions.js');
$PAGE->requires->js('/grade/report/grader/grader.js');
$PAGE->requires->js('/lib/overlib/overlib.js', true);
$PAGE->requires->js('/lib/overlib/overlib_cssstyle.js', true);
if ($report->get_pref('enableajax')) {
$report = new grade_report_grader_ajax($courseid, $gpr, $context, $page, $sortitemid);
}
@ -172,7 +161,7 @@ if (!empty($studentsperpage)) {
$reporthtml = $report->get_grade_table();
// print submit button
if ($USER->gradeediting[$course->id] && ($report->get_pref('showquickfeedback') || $report->get_pref('quickgrading')) && !$report->get_pref('enableajax')) {
if ($USER->gradeediting[$course->id] && ($report->get_pref('showquickfeedback') || $report->get_pref('quickgrading'))) {
echo '<form action="index.php" method="post">';
echo '<div>';
echo '<input type="hidden" value="'.s($courseid).'" name="id" />';
@ -189,10 +178,4 @@ if ($USER->gradeediting[$course->id] && ($report->get_pref('showquickfeedback')
if (!empty($studentsperpage) && $studentsperpage >= 20) {
echo $OUTPUT->paging_bar(moodle_paging_bar::make($numusers, $report->page, $studentsperpage, $report->pbarurl));
}
echo $OUTPUT->container('tooltip panel', '', 'hiddentooltiproot');
// Print AJAX code
if ($report->get_pref('enableajax')) {
require_once 'ajax.php';
}
echo $OUTPUT->footer();

View File

@ -545,7 +545,7 @@ class grade_report_grader extends grade_report {
for ($i = 0; $i < $levels; $i++) {
$fillercell = new html_table_cell();
$fillercell->add_classes(array('fixedcolumn', 'cell', 'c0', 'topleft'));
$fillercell->add_classes(array('fixedcolumn', 'cell', 'topleft'));
$fillercell->text = ' ';
$fillercell->colspan = $colspan;
$row = html_table_row::make(array($fillercell));
@ -556,7 +556,7 @@ class grade_report_grader extends grade_report {
$headerrow->add_class('heading');
$studentheader = new html_table_cell();
$studentheader->add_classes(array('header', 'c0'));
$studentheader->add_classes(array('header'));
$studentheader->scope = 'col';
$studentheader->header = true;
$studentheader->id = 'studentheader';
@ -572,7 +572,7 @@ class grade_report_grader extends grade_report {
$sortidnumberlink = html_writer::link(new moodle_url($this->baseurl, array('sortitemid'=>'idnumber')), get_string('idnumber'));
$idnumberheader = new html_table_cell();
$idnumberheader->add_classes(array('header', 'c0', 'useridnumber'));
$idnumberheader->add_classes(array('header', 'useridnumber'));
$idnumberheader->scope = 'col';
$idnumberheader->header = true;
$idnumberheader->text = $arrows['idnumber'];
@ -588,13 +588,13 @@ class grade_report_grader extends grade_report {
foreach ($this->users as $userid => $user) {
$userrow = new html_table_row();
$userrow->id = 'fixed_user_'.$userid;
$userrow->add_classes(array('r'.$this->rowcount++, $rowclasses[$this->rowcount % 2]));
$usercell = new html_table_cell();
$usercell->add_classes(array('c0', 'user'));
$usercell->add_classes(array('user'));
$usercell->header = true;
$usercell->scope = 'row';
$usercell->add_action('click', 'yui_set_row');
if ($showuserimage) {
$usercell->text = $OUTPUT->container($OUTPUT->user_picture($user), 'userpic');
@ -617,10 +617,9 @@ class grade_report_grader extends grade_report {
if ($showuseridnumber) {
$idnumbercell = new html_table_cell();
$idnumbercell->add_classes(array('header', 'c0', 'useridnumber'));
$idnumbercell->add_classes(array('header', 'useridnumber'));
$idnumbercell->header = true;
$idnumbercell->scope = 'row';
$idnumbercell->add_action('click', 'yui_set_row');
$userrow->cells[] = $idnumbercell;
}
@ -639,7 +638,7 @@ class grade_report_grader extends grade_report {
* @return array Array of html_table_row objects
*/
public function get_right_rows() {
global $CFG, $USER, $OUTPUT, $DB;
global $CFG, $USER, $OUTPUT, $DB, $PAGE;
$rows = array();
$this->rowcount = 0;
@ -648,10 +647,19 @@ class grade_report_grader extends grade_report {
$gradetabindex = 1;
$columnstounset = array();
$strgrade = $this->get_lang_string('grade');
$strfeedback = $this->get_lang_string("feedback");
$arrows = $this->get_sort_arrows();
$jsarguments = array(
'id' => '#fixed_column',
'cfg' => array('ajaxenabled'=>false),
'items' => array(),
'users' => array(),
'feedback' => array()
);
$jsscales = array();
foreach ($this->gtree->get_levels() as $key=>$row) {
$columncount = 0;
if ($key == 0) {
// do not display course grade category
// continue;
@ -673,10 +681,8 @@ class grade_report_grader extends grade_report {
$itemmodule = null;
$iteminstance = null;
$columnclass = 'c' . $columncount++;
if (!empty($element['colspan'])) {
$colspan = $element['colspan'];
$columnclass = '';
} else {
$colspan = 1;
}
@ -690,7 +696,7 @@ class grade_report_grader extends grade_report {
// Element is a filler
if ($type == 'filler' or $type == 'fillerfirst' or $type == 'fillerlast') {
$fillercell = new html_table_cell();
$fillercell->add_classes(array($columnclass, $type, $catlevel));
$fillercell->add_classes(array($type, $catlevel));
$fillercell->colspan = $colspan;
$fillercell->text = '&nbsp;';
$fillercell->header = true;
@ -700,7 +706,7 @@ class grade_report_grader extends grade_report {
// Element is a category
else if ($type == 'category') {
$categorycell = new html_table_cell();
$categorycell->add_classes(array($columnclass, 'category', $catlevel));
$categorycell->add_classes(array('category', $catlevel));
$categorycell->colspan = $colspan;
$categorycell->text = shorten_text($element['object']->get_name());
$categorycell->text .= $this->get_collapsing_icon($element);
@ -732,7 +738,7 @@ class grade_report_grader extends grade_report {
$headerlink = $this->gtree->get_element_header($element, true, $this->get_pref('showactivityicons'), false);
$itemcell = new html_table_cell();
$itemcell->add_classes(array($columnclass, $type, $catlevel));
$itemcell->add_classes(array($type, $catlevel, 'highlightable'));
if ($element['object']->is_hidden()) {
$itemcell->add_class('hidden');
@ -742,11 +748,10 @@ class grade_report_grader extends grade_report {
$itemcell->text = shorten_text($headerlink) . $arrow;
$itemcell->header = true;
$itemcell->scope = 'col';
$itemcell->onclick = 'set_col(this.cellIndex);';
$headingrow->cells[] = $itemcell;
}
}
$rows[] = $headingrow;
}
@ -757,11 +762,14 @@ class grade_report_grader extends grade_report {
$scaleslist = array();
$tabindices = array();
foreach ($this->gtree->get_items() as $item) {
foreach ($this->gtree->get_items() as $itemid=>$item) {
$scale = null;
if (!empty($item->scaleid)) {
$scaleslist[] = $item->scaleid;
$jsarguments['items'][$itemid] = array('id'=>$itemid, 'name'=>$item->get_name(true), 'type'=>'scale', 'scale'=>$item->scaleid, 'decimals'=>$item->get_decimals());
} else {
$jsarguments['items'][$itemid] = array('id'=>$itemid, 'name'=>$item->get_name(true), 'type'=>'value', 'scale'=>false, 'decimals'=>$item->get_decimals());
}
$tabindices[$item->id]['grade'] = $gradetabindex;
$tabindices[$item->id]['feedback'] = $gradetabindex + $numusers;
$gradetabindex += $numusers * 2;
@ -771,6 +779,7 @@ class grade_report_grader extends grade_report {
if (!empty($scaleslist)) {
$scalesarray = $DB->get_records_list('scale', 'id', $scaleslist);
}
$jsscales = $scalesarray;
$rowclasses = array('even', 'odd');
@ -786,17 +795,21 @@ class grade_report_grader extends grade_report {
unset($hidingaffected);
}
$columncount = 0;
$itemrow = new html_table_row();
$itemrow->id = 'user_'.$userid;
$itemrow->add_class($rowclasses[$this->rowcount % 2]);
$jsarguments['users'][$userid] = fullname($user);
foreach ($this->gtree->items as $itemid=>$unused) {
$item =& $this->gtree->items[$itemid];
$grade = $this->grades[$userid][$item->id];
$itemcell = new html_table_cell();
$itemcell->id = 'u'.$userid.'i'.$itemid;
// Get the decimal points preference for this item
$decimalpoints = $item->get_decimals();
@ -840,15 +853,10 @@ class grade_report_grader extends grade_report {
// $itemcell->add_class('excluded');
}
$gradetitle = $OUTPUT->container(fullname($user), 'fullname');
$gradetitle .= $OUTPUT->container($item->get_name(true), 'itemname');
if (!empty($grade->feedback) && !$USER->gradeediting[$this->courseid]) {
$gradetitle .= $OUTPUT->container(wordwrap(trim(format_string($grade->feedback, $grade->feedbackformat)), 34, '<br/ >'), 'feedback');
if (!empty($grade->feedback)) {
$jsarguments['feedback'][] = array('user'=>$userid, 'item'=>$itemid, 'content'=>wordwrap(trim(format_string($grade->feedback, $grade->feedbackformat)), 34, '<br/ >'));
}
$itemcell->title = s($gradetitle);
if ($grade->is_excluded()) {
$itemcell->text .= $OUTPUT->span(get_string('excluded', 'grades'), 'excludedfloater');
}
@ -900,9 +908,8 @@ class grade_report_grader extends grade_report {
} else {
$nogradestr = $this->get_lang_string('nooutcome', 'grades');
}
$itemcell->text .= '<input type="hidden" name="oldgrade_'.$userid.'_'
.$item->id.'" value="'.$oldval.'"/>';
$attributes = array('tabindex' => $tabindices[$item->id]['grade']);
$itemcell->text .= '<input type="hidden" id="oldgrade_'.$userid.'_'.$item->id.'" name="oldgrade_'.$userid.'_'.$item->id.'" value="'.$oldval.'"/>';
$attributes = array('tabindex' => $tabindices[$item->id]['grade'], 'id'=>'grade_'.$userid.'_'.$item->id);
$itemcell->text .= html_writer::select($scaleopt, 'grade_'.$userid.'_'.$item->id, $gradeval, array(-1=>$nogradestr), $attributes);;
} elseif(!empty($scale)) {
$scales = explode(",", $scale->scale);
@ -921,10 +928,10 @@ class grade_report_grader extends grade_report {
} else if ($item->gradetype != GRADE_TYPE_TEXT) { // Value type
if ($this->get_pref('quickgrading') and $grade->is_editable()) {
$value = format_float($gradeval, $decimalpoints);
$itemcell->text .= '<input type="hidden" name="oldgrade_'.$userid.'_'.$item->id.'" value="'.$value.'" />';
$itemcell->text .= '<input type="hidden" id="oldgrade_'.$userid.'_'.$item->id.'" name="oldgrade_'.$userid.'_'.$item->id.'" value="'.$value.'" />';
$itemcell->text .= '<input size="6" tabindex="' . $tabindices[$item->id]['grade']
. '" type="text" class="text" title="'. $strgrade .'" name="grade_'
.$userid.'_' .$item->id.'" value="'.$value.'" />';
.$userid.'_' .$item->id.'" id="grade_'.$userid.'_'.$item->id.'" value="'.$value.'" />';
} else {
$itemcell->text .= $OUTPUT->span(format_float($gradeval, $decimalpoints), "gradevalue$hidden$gradepass");
}
@ -934,17 +941,19 @@ class grade_report_grader extends grade_report {
// If quickfeedback is on, print an input element
if ($this->get_pref('showquickfeedback') and $grade->is_editable()) {
$itemcell->text .= '<input type="hidden" name="oldfeedback_'
.$userid.'_'.$item->id.'" value="' . s($grade->feedback) . '" />';
$itemcell->text .= '<input class="quickfeedback" tabindex="' . $tabindices[$item->id]['feedback']
. '" size="6" title="' . $strfeedback . '" type="text" name="feedback_'
.$userid.'_'.$item->id.'" value="' . s($grade->feedback) . '" />';
$itemcell->text .= '<input type="hidden" id="oldfeedback_'.$userid.'_'.$item->id.'" name="oldfeedback_'.$userid.'_'.$item->id.'" value="' . s($grade->feedback) . '" />';
$itemcell->text .= '<input class="quickfeedback" tabindex="' . $tabindices[$item->id]['feedback'].'" id="feedback_'.$userid.'_'.$item->id
. '" size="6" title="' . $strfeedback . '" type="text" name="feedback_'.$userid.'_'.$item->id.'" value="' . s($grade->feedback) . '" />';
}
} else { // Not editing
$gradedisplaytype = $item->get_displaytype();
// If feedback present, surround grade with feedback tooltip: Open span here
if ($item->scaleid && !empty($scalesarray[$item->scaleid])) {
$itemcell->add_class('grade_type_scale');
} else if ($item->gradetype != GRADE_TYPE_TEXT) {
$itemcell->add_class('grade_type_text');
}
if ($item->needsupdate) {
$itemcell->text .= $OUTPUT->span(get_string('error'), "gradingerror$hidden$gradepass");
@ -962,6 +971,29 @@ class grade_report_grader extends grade_report {
$rows[] = $itemrow;
}
if ($this->get_pref('enableajax')) {
$jsarguments['cfg']['ajaxenabled'] = true;
$jsarguments['cfg']['scales'] = array();
foreach ($jsscales as $scale) {
$jsarguments['cfg']['scales'][$scale->id] = explode(',',$scale->scale);
}
$jsarguments['cfg']['feedbacktrunclength'] = $this->feedback_trunc_length;
$jsarguments['cfg']['feedback'] = $this->feedbacks;
}
$jsarguments['cfg']['isediting'] = (bool)$USER->gradeediting[$this->courseid];
$jsarguments['cfg']['courseid'] = $this->courseid;
$jsarguments['cfg']['studentsperpage'] = $this->get_pref('studentsperpage');
$jsarguments['cfg']['showquickfeedback'] = (bool)$this->get_pref('showquickfeedback');
$module = array(
'name' => 'gradereport_grader',
'fullpath' => '/grade/report/grader/module.js',
'requires' => array('base', 'dom', 'event', 'event-mouseenter', 'event-key', 'io', 'json-parse', 'overlay')
);
$PAGE->requires->js_init_call('M.gradereport_grader.init_report', $jsarguments, false, $module);
$PAGE->requires->strings_for_js(array('addfeedback','feedback', 'grade'), 'grades');
$PAGE->requires->strings_for_js(array('ajaxchoosescale','ajaxclicktoclose','ajaxerror','ajaxfailedupdate', 'ajaxfieldchanged'), 'gradereport_grader');
$rows = $this->get_right_range_row($rows);
$rows = $this->get_right_avg_row($rows, true);
$rows = $this->get_right_avg_row($rows);
@ -984,6 +1016,7 @@ class grade_report_grader extends grade_report {
$html = '';
if ($fixedstudents) {
$fixedcolumntable = new html_table();
$fixedcolumntable->id = 'fixed_column';
@ -1027,7 +1060,7 @@ class grade_report_grader extends grade_report {
$controlsrow = new html_table_row();
$controlsrow->add_class('controls');
$controlscell = new html_table_cell();
$controlscell->add_classes(array('header', 'c0', 'controls'));
$controlscell->add_classes(array('header', 'controls'));
$controlscell->colspan = $colspan;
$controlscell->text = $this->get_lang_string('controls','grades');
@ -1050,7 +1083,7 @@ class grade_report_grader extends grade_report {
$rangerow = new html_table_row();
$rangerow->add_classes(array('range', 'r'.$this->rowcount++));
$rangecell = new html_table_cell();
$rangecell->add_classes(array('header', 'c0', 'range'));
$rangecell->add_classes(array('header', 'range'));
$rangecell->colspan = $colspan;
$rangecell->header = true;
$rangecell->scope = 'row';
@ -1085,7 +1118,7 @@ class grade_report_grader extends grade_report {
$groupavgrow = new html_table_row();
$groupavgrow->add_classes(array('groupavg', 'r'.$this->rowcount++));
$groupavgcell = new html_table_cell();
$groupavgcell->add_classes(array('header', 'c0', 'range'));
$groupavgcell->add_classes(array('header', 'range'));
$groupavgcell->colspan = $colspan;
$groupavgcell->header = true;
$groupavgcell->scope = 'row';
@ -1100,7 +1133,7 @@ class grade_report_grader extends grade_report {
$avgrow = new html_table_row();
$avgrow->add_classes(array('avg', 'r'.$this->rowcount++));
$avgcell = new html_table_cell();
$avgcell->add_classes(array('header', 'c0', 'range'));
$avgcell->add_classes(array('header', 'range'));
$avgcell->colspan = $colspan;
$avgcell->header = true;
$avgcell->scope = 'row';
@ -1126,7 +1159,6 @@ class grade_report_grader extends grade_report {
$showuseridnumber = $this->get_pref('showuseridnumber');
$columncount = 0;
foreach ($this->gtree->items as $itemid=>$unused) {
// emulate grade element
$item =& $this->gtree->get_item($itemid);

File diff suppressed because it is too large Load Diff

View File

@ -11,10 +11,6 @@ height:20px;
background-color:#f9f9f9;
}
.grade-report-grader table#user-grades td.overridden {
background-color:#ddd;
}
.grade-report-grader table#user-grades tr.avg td.cell {
background-color:#efefff;
font-weight:700;
@ -26,13 +22,11 @@ background-color:#efefef;
white-space:nowrap;
}
.grade-report-grader table#user-grades tr.even td.overridden {
background-color:#F3E4C0;
}
.grade-report-grader table#user-grades tr td.overridden {background-color:#F3E4C0;}
.grade-report-grader table#user-grades tr.odd td.overridden {background-color:#EFD9A4;}
.grade-report-grader table#user-grades tr.odd td.overridden {
background-color:#EFD9A4;
}
.grade-report-grader table#user-grades tr td.ajaxoverridden {background-color:#FFE3A0;}
.grade-report-grader table#user-grades tr.odd td.ajaxoverridden {background-color:#FFDA83;}
.grade-report-grader table#user-grades tr.even td.excluded {
background-color:#EABFFF;
@ -53,7 +47,8 @@ font-weight:700;
color:#006400;
}
.grade-report-grader table#user-grades td.cat,.grade-report-grader table#user-grades td.course {
.grade-report-grader table#user-grades td.cat,
.grade-report-grader table#user-grades td.course {
font-weight:700;
}
@ -133,22 +128,14 @@ border-style:solid;
border-width:0 0 1px 1px;
}
.grade-report-grader table#user-grades th.categoryitem,.grade-report-grader table#user-grades th.courseitem,.grade-report-grader table#user-grades td.topleft {
.grade-report-grader table#user-grades th.categoryitem,
.grade-report-grader table#user-grades th.courseitem,
.grade-report-grader table#user-grades td.topleft {
vertical-align:top;
border-style:solid;
border-width:0 1px;
}
/* we don't want 25px height - at all
* This causes the columns to fall out of line if Static Students Column is enabled
.grade-report-grader table#user-grades th.category,
.grade-report-grader table#user-grades th.item,
.grade-report-grader table#user-grades th.categoryitem,
.grade-report-grader table#user-grades th.courseitem {
height: 25px;
}
*/
.grade-report-grader td,.grade-report-grader th {
border-color:#CECECE;
}
@ -201,7 +188,8 @@ border:#000 1px dashed;
text-align:right;
}
.grade-report-grader table#user-grades .hidden,.grade-report-grader table#user-grades .hidden a {
.grade-report-grader table#user-grades .hidden,
.grade-report-grader table#user-grades .hidden a {
color:#aaa;
}
@ -243,7 +231,8 @@ border-width:0 0 1px;
border-top:1px solid #cecece;
}
.grade-report-grader table#user-grades tr.heading th.categoryitem,.grade-report-grader table#user-grades tr.heading th.courseitem {
.grade-report-grader table#user-grades tr.heading th.categoryitem,
.grade-report-grader table#user-grades tr.heading th.courseitem {
border-width:0 0 0 1px;
}
@ -259,7 +248,9 @@ margin:0;
padding:0;
}
.grade-report-grader table#user-grades th.categoryitem,.grade-report-grader table#user-grades th.courseitem,.grade-report-grader table td.topleft {
.grade-report-grader table#user-grades th.categoryitem,
.grade-report-grader table#user-grades th.courseitem,
.grade-report-grader table td.topleft {
vertical-align:top;
border-color:#cecece #cecece #000;
border-style:solid;
@ -397,11 +388,21 @@ clear:none;
overflow-x:scroll;
}
.grade-report-grader table tr.avg,.grade-report-grader table tr.groupavg td,.grade-report-grader table tr.avg td,.grade-report-grader table tr.groupavg th,.grade-report-grader table tr.avg th,.grade-report-grader table tr.controls_row,.grade-report-grader table tr.controls_row th,.grade-report-grader table tr.range_row,.grade-report-grader table tr.range_row th,div.right_scroller tr {
.grade-report-grader table tr.avg,
.grade-report-grader table tr.groupavg td,
.grade-report-grader table tr.avg td,
.grade-report-grader table tr.groupavg th,
.grade-report-grader table tr.avg th,
.grade-report-grader table tr.controls_row,
.grade-report-grader table tr.controls_row th,
.grade-report-grader table tr.range_row,
.grade-report-grader table tr.range_row th,
div.right_scroller tr {
height:2em;
}
.grade-report-grader table#user-grades tr.groupavg td.cell,.grade-report-grader tr.groupavg th.header {
.grade-report-grader table#user-grades tr.groupavg td.cell,
.grade-report-grader tr.groupavg th.header {
background-color:#efffef;
}
@ -439,7 +440,15 @@ font-size:86%;
padding:0;
}
.grade-report-grader tr.avg,tr.controls,td.controls,th.controls,.grade-report-grader tr.groupavg,tr.range,th.range,td.range,tr.heading th.range {
.grade-report-grader tr.avg,
.grade-report-grader tr.controls,
.grade-report-grader td.controls,
.grade-report-grader th.controls,
.grade-report-grader tr.groupavg,
.grade-report-grader tr.range,
.grade-report-grader th.range,
.grade-report-grader td.range,
.grade-report-grader tr.heading th.range {
height:2em!important;
white-space:nowrap;
}
@ -458,15 +467,26 @@ heading_name_row th span {
float:right;
}
.gradestable th.user,.gradestable th.range,.grade-report-grader .flexible th,.grade-report-grader .flexible td,.grade-report-grader .flexible th a,.grade-report-grader .flexible td a,.grade-report-grader .gradestable th.range,.grade-report-grader td {
.gradestable th.user,
.gradestable th.range,
.grade-report-grader .flexible th,
.grade-report-grader .flexible td,
.grade-report-grader .flexible th a,
.grade-report-grader .flexible td a,
.grade-report-grader .gradestable th.range,
.grade-report-grader td {
white-space:nowrap;
}
.grade-report-grader table#user-grades .catlevel1,.grade-report-grader .r1,.grade-report-grader table tr.even td.cell,.grade-report-grader table tr.even th {
.grade-report-grader table#user-grades .catlevel1,
.grade-report-grader .r1,
.grade-report-grader table tr.even td.cell,
.grade-report-grader table tr.even th {
background-color:#fff;
}
.grade-report-grader table#user-grades .catlevel3,.grade-report-grader table tr.odd td.cell {
.grade-report-grader table#user-grades .catlevel3,
.grade-report-grader table tr.odd td.cell {
background-color:#efefef;
}
@ -475,42 +495,67 @@ background-color:#efefef;
background-color:#efefef;
}
.grade-report-grader table#user-grades td.vmarked,.grade-report-grader table#user-grades tr.odd td.vmarked,.grade-report-grader table#user-grades td.vmarked,.grade-report-grader table#user-grades tr.odd td.vmarked,.grade-report-grader table#user-grades tr.even td.vmarked {
.grade-report-grader table#user-grades td.vmarked,
.grade-report-grader table#user-grades tr.odd td.vmarked,
.grade-report-grader table#user-grades td.vmarked,
.grade-report-grader table#user-grades tr.odd td.vmarked,
.grade-report-grader table#user-grades tr.even td.vmarked {
background-color:#fc3;
}
.grade-report-grader table#user-grades td.hmarked,.grade-report-grader table#user-grades tr.odd td.hmarked,.grade-report-grader table#user-grades td.hmarked,.grade-report-grader table#user-grades tr.odd td.hmarked,.grade-report-grader table#user-grades tr.even td.hmarked {
.grade-report-grader table#user-grades td.hmarked,
.grade-report-grader table#user-grades tr.odd td.hmarked,
.grade-report-grader table#user-grades td.hmarked,
.grade-report-grader table#user-grades tr.odd td.hmarked,
.grade-report-grader table#user-grades tr.even td.hmarked {
background-color:#ff9;
}
.grade-report-grader table#user-grades td.hmarked.vmarked,.grade-report-grader table#user-grades tr.odd td.hmarked.vmarked,.grade-report-grader table#user-grades td.hmarked.vmarked,.grade-report-grader table#user-grades tr.even td.hmarked.vmarked,.grade-report-grader table#user-grades tr.odd td.hmarked.vmarked {
.grade-report-grader table#user-grades td.hmarked.vmarked,
.grade-report-grader table#user-grades tr.odd td.hmarked.vmarked,
.grade-report-grader table#user-grades td.hmarked.vmarked,
.grade-report-grader table#user-grades tr.even td.hmarked.vmarked,
.grade-report-grader table#user-grades tr.odd td.hmarked.vmarked {
background-color:#fc9;
}
.grade-report-grader table#user-grades tr.heading,.grade-report-grader table#user-grades .heading td {
.grade-report-grader table#user-grades tr.heading,
.grade-report-grader table#user-grades .heading td {
border-style:solid;
border-width:0;
}
.grade-report-grader table#user-grades td.useridnumber,.grade-report-grader table#user-grades th,.grade-report-grader div.gradeparent,.ie6 form,.grade-report-grader table#user-grades td.ajax {
.grade-report-grader table#user-grades td.useridnumber,
.grade-report-grader table#user-grades th,
.grade-report-grader div.gradeparent,
.ie6 form,.grade-report-grader table#user-grades td.ajax {
text-align:left;
}
.grade-report-grader table tr.avg td.cell,.grade-report-grader table#user-grades td.controls,.grade-report-grader table tr.avg,.grade-report-grader table tr.avg td,.grade-report-grader table tr.avg th {
.grade-report-grader table tr.avg td.cell,
.grade-report-grader table#user-grades td.controls,
.grade-report-grader table tr.avg,
.grade-report-grader table tr.avg td,
.grade-report-grader table tr.avg th {
background-color:#f3ead8;
}
.grade-report-grader div.left_scroller tr,.grade-report-grader div.right_scroller tr,.grade-report-grader div.left_scroller td,.grade-report-grader div.right_scroller td,.grade-report-grader div.left_scroller th,.grade-report-grader div.right_scroller th {
.grade-report-grader div.left_scroller tr,
.grade-report-grader div.right_scroller tr,
.grade-report-grader div.left_scroller td,
.grade-report-grader div.right_scroller td,
.grade-report-grader div.left_scroller th,
.grade-report-grader div.right_scroller th {
height:4.5em;
font-size:10px;
}
.grade-report-grader table th.user,.grade-report-grader table td.useridnumber {
.grade-report-grader table th.user,
.grade-report-grader table td.useridnumber {
text-align:left;
vertical-align:middle;
}
/*
.grade-report-grader .yui-overlay {
background-color: #FFEE69;
border-color: #D4C237 #A6982B #A6982B;
@ -520,7 +565,6 @@ vertical-align:middle;
padding: 2px 5px;
font-size: 0.7em;
}
*/
.grade-report-grader .yui-overlay .fullname {
color: #5F3E00;
@ -577,4 +621,4 @@ position:absolute;
.ie6 .excludedfloater {
font-size:7px;
}
}

View File

@ -1,5 +1,10 @@
<?PHP // $Id$
<?php
$string['ajaxchoosescale'] = 'Choose';
$string['ajaxclicktoclose'] = 'Click this box to remove it';
$string['ajaxerror'] = 'Error';
$string['ajaxfailedupdate'] = 'Unable to update [1] for [2]';
$string['ajaxfieldchanged'] = 'The field you are currently editing has changed, would you like to use the updated value?';
$string['modulename'] = 'Grader report';
$string['grader:manage'] = 'Manage the grader report';
$string['grader:view'] = 'View the grader report';

View File

@ -2008,10 +2008,12 @@ class core_renderer extends renderer_base {
if (!($cell instanceof html_table_cell)) {
$mycell = new html_table_cell();
$mycell->text = $cell;
$this->prepare_event_handlers($mycell);
$cell = $mycell;
}
// Prepare all events handlers for this cell
$this->prepare_event_handlers($cell);
if (isset($table->colclasses[$key])) {
$cell->add_classes(array_unique(html_component::clean_classes($table->colclasses[$key])));
}
@ -2060,7 +2062,7 @@ class core_renderer extends renderer_base {
* @param string $id The target name from the corresponding $PAGE->requires->skip_link_to($target) call.
* @return string the HTML to output.
*/
public function skip_link_target($id = '') {
public function skip_link_target($id = null) {
return html_writer::tag('span', array('id' => $id), '');
}
@ -2072,7 +2074,7 @@ class core_renderer extends renderer_base {
* @param string $id An optional ID
* @return string the HTML to output.
*/
public function heading($text, $level = 2, $classes = 'main', $id = '') {
public function heading($text, $level = 2, $classes = 'main', $id = null) {
$level = (integer) $level;
if ($level < 1 or $level > 6) {
throw new coding_exception('Heading level must be an integer between 1 and 6.');
@ -2088,7 +2090,7 @@ class core_renderer extends renderer_base {
* @param string $id An optional ID
* @return string the HTML to output.
*/
public function box($contents, $classes = 'generalbox', $id = '') {
public function box($contents, $classes = 'generalbox', $id = null) {
return $this->box_start($classes, $id) . $contents . $this->box_end();
}
@ -2098,7 +2100,7 @@ class core_renderer extends renderer_base {
* @param string $id An optional ID
* @return string the HTML to output.
*/
public function box_start($classes = 'generalbox', $id = '') {
public function box_start($classes = 'generalbox', $id = null) {
$this->opencontainers->push('box', html_writer::end_tag('div'));
return html_writer::start_tag('div', array('id' => $id,
'class' => 'box ' . renderer_base::prepare_classes($classes)));
@ -2119,7 +2121,7 @@ class core_renderer extends renderer_base {
* @param string $id An optional ID
* @return string the HTML to output.
*/
public function container($contents, $classes = '', $id = '') {
public function container($contents, $classes = null, $id = null) {
return $this->container_start($classes, $id) . $contents . $this->container_end();
}
@ -2129,7 +2131,7 @@ class core_renderer extends renderer_base {
* @param string $id An optional ID
* @return string the HTML to output.
*/
public function container_start($classes = '', $id = '') {
public function container_start($classes = null, $id = null) {
$this->opencontainers->push('container', html_writer::end_tag('div'));
return html_writer::start_tag('div', array('id' => $id,
'class' => renderer_base::prepare_classes($classes)));
@ -2286,7 +2288,7 @@ class core_renderer_cli extends core_renderer {
* @param string $id An optional ID
* @return string A template fragment for a heading
*/
public function heading($text, $level, $classes = 'main', $id = '') {
public function heading($text, $level, $classes = 'main', $id = null) {
$text .= "\n";
switch ($level) {
case 1: