[LON-CAPA-cvs] cvs: loncom /homework task_grading.js
albertel
lon-capa-cvs@mail.lon-capa.org
Tue, 28 Mar 2006 18:33:24 -0000
albertel Tue Mar 28 13:33:24 2006 EDT
Added files:
/loncom/homework task_grading.js
Log:
- adding JS to ease Task grading
Index: loncom/homework/task_grading.js
+++ loncom/homework/task_grading.js
// JavaScript Document
if (! Node) {
//If the node Type constants are not set, set the ones I need
var Node = new Object;
Node.TEXT_NODE = 3;
}
//Detect IE
var isIE = (navigator.appName.indexOf("Explorer") > -1);
//Attach to the onLoad event
window.onload = setEvents;
if (window.captureEvents) {
window.captureEvents(Event.LOAD);
}
/*
* Utilitity Functions
*/
//Generic tool for getting all tags of a specific type and class
//tagName - Name of tag to search for
//withClass - Name of Class to search for
//expCnt - OPTIONAL max number of elements to find
function myGetElementsByClass(tagName, withClass, expCnt) {
var tags = document.getElementsByTagName(tagName);
var rtn = new Array();
expCnt = expCnt || false; //Default value for expCnt
//Find only the ones with the right class
for(var i=0; i < tags.length; i++) {
if (tags[i].className == withClass) {
rtn.push(tags[i]);
if (expCnt > 0 && rtn.length > expCnt) { break; }
}
}
return rtn;
}
//Find the first text Node under current node
//Returns the node itself, not the text
//NOTE: Do not call this on a node that may have multiple text Nodes
// as children
function getTextNode(node) {
if (node.nodeType == Node.TEXT_NODE) {
return node;
}
for(var i=0; i < node.childNodes.length; i++) {
var rtn = getTextNode(node.childNodes[i]);
if (rtn) { return rtn; }
}
return false;
}
//Get object that raised event
function getEventObject(e) {
//Make sure I have the event
if (!e) { e = window.event; }
//Get the object that raised the event
if (e.target) {
return e.target;
} else if (e.srcElement) {
return e.srcElement;
}
return false;
}
//Attach an onClick event handler to a node
function attachClickEvent(node, func) {
node.onclick = func; //Add event
if (!isIE) {
//Allow me to raise events
node.addEventListener("onclick", func, true); //false to get it in bubble not capture
}
if (node.captureEvents) { node.captureEvents(Event.CLICK); }
}
//Fire an event on a given node
function dispatchEvent(node, eventName) {
if (document.createEvent) {
var evt = document.createEvent("Events"); //Simple event object
evt.initEvent(eventName, true, true); //true for can bubble, true for cancelable
node.dispatchEvent(evt);
} else {
//IE version
var evt = document.createEventObject();
node.fireEvent(eventName,evt);
evt.cancelBubble = true;
}
}
/*
* Setup Functions
*/
//Master setup function
function setEvents() {
setupHandin();
setupGrading();
setupButtons();
}
//Setup the File handin list
function setupHandin() {
var handin;
//Create the 'Collapse' button
var li = document.createElement('li');
var a = document.createElement('a');
var txt = document.createTextNode('Collapse');
a.setAttribute('href', '#');
attachClickEvent(a, onSlideDrawer);
a.appendChild(txt);
li.appendChild(a);
//Find the handin list
var lists = myGetElementsByClass('ul', 'LC_GRADING_handininfo', 1);
if (lists.length > 0) {
handin = lists[0];
} else {
return false;
}
//Trim the displayed file paths
for(var i=0; i < handin.childNodes.length; i++) {
var txt = getTextNode(handin.childNodes[i]);
if (txt) {
var j = txt.nodeValue.indexOf('portfolio/');
if (j > 0) {
txt.nodeValue = txt.nodeValue.substr(j + 'portfolio/'.length);
}
}
}
//Add the button
handin.insertBefore(li, handin.firstChild);
//Adjust height of the list
var item_cnt = handin.getElementsByTagName('li').length * 1.3; //Lines take about 1.3em ea.
handin.style.height = item_cnt + 'em';
}
//Add events to all grading radio buttons
function setupGrading() {
var inputs = document.getElementsByTagName('input');
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].type == "radio") {
var val = inputs[i].value;
if (val == "pass" || val == "fail" || val == "review") {
attachClickEvent(inputs[i], onSetGrade); //Add event
}
if (inputs[i].checked) {
dispatchEvent(inputs[i], 'onclick');
}
}
}
}
//Adjust the Done/Stop/Fail All button set
function setupButtons() {
//Create Fail All button
var btn = document.createElement('input');
btn.setAttribute('type', 'button');
btn.setAttribute('value', 'Fail Rest');
attachClickEvent(btn, onFailRest);
//Add the button in
var div = myGetElementsByClass('div','LC_GRADING_maincontrols', 1);
if (div.length > 0) { div[0].appendChild(btn); }
}
/*
* Events
*/
//Slide the Handin list up and down like a drawer
function onSlideDrawer(e) {
var obj = getEventObject(e);
var txt = getTextNode(obj);
txt.nodeValue = (txt.nodeValue == 'Collapse') ? 'Expand':'Collapse';
var list = obj.parentNode.parentNode;
var item_cnt = (txt.nodeValue == 'Collapse') ? list.getElementsByTagName('li').length : 1;
list.style.height = (item_cnt*1.3) + 'em'; //Lines take about 1.3em ea.
return false;
}
//Fail all ungraded criteria
function onFailRest(e) {
var obj = getEventObject(e);
var inputs = document.getElementsByTagName('input');
var graded = false;
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].type == "radio") {
var val = inputs[i].value;
if (val == "ungraded" ) {
//Flag whether this criteria is graded or not
//I depend on 'ungraded' being the first radio button in each set
graded = ! inputs[i].checked;
} else if (val == "fail" && !graded) {
inputs[i].checked = true;
//Fire the onclick event to get colors
dispatchEvent(inputs[i], 'onclick');
}
}
}
}
//Set bacground for grade chosen
function onSetGrade( e ) {
var obj = getEventObject(e);
var grade;
var gradediv;
//Find the Radio button and get it's value
if (obj.tagName == 'INPUT') {
grade = obj.value;
} else {
rdo = obj.getElementsByTagName('INPUT');
if (rdo.length > 0) { grade = rdo[0].value; }
}
//Search for parent DIV
gradediv = obj;
while (gradediv.tagName != 'DIV') {
gradediv = gradediv.parentNode;
}
gradediv.className = "LC_GRADING_grade LC_GRADING_" + grade;
}