[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;
}