File:  [LON-CAPA] / loncom / homework / task_grading.js
Revision 1.1: download - view: text, annotated - select for diffs
Tue Mar 28 18:33:24 2006 UTC (18 years, 2 months ago) by albertel
Branches: MAIN
CVS tags: version_2_1_X, version_2_1_3, HEAD
- adding JS to ease Task grading

    1: // JavaScript Document
    2: 
    3: if (! Node) {
    4: 	//If the node Type constants are not set, set the ones I need
    5: 	var Node = new Object;
    6: 	Node.TEXT_NODE = 3;	
    7: }
    8: 
    9: //Detect IE
   10: var isIE = (navigator.appName.indexOf("Explorer") > -1);
   11: 
   12: //Attach to the onLoad event
   13: window.onload = setEvents;
   14: if (window.captureEvents) {
   15: 	window.captureEvents(Event.LOAD);
   16: }
   17: 
   18: /*
   19:  * Utilitity Functions
   20:  */
   21: //Generic tool for getting all tags of a specific type and class
   22: //tagName - Name of tag to search for
   23: //withClass - Name of Class to search for
   24: //expCnt - OPTIONAL max number of elements to find
   25: function myGetElementsByClass(tagName, withClass, expCnt) {
   26: 	var tags = document.getElementsByTagName(tagName);
   27: 	var rtn = new Array();	
   28: 	expCnt = expCnt || false; //Default value for expCnt
   29: 	
   30: 	//Find only the ones with the right class
   31: 	for(var i=0; i < tags.length; i++) {
   32: 		if (tags[i].className == withClass) {
   33: 			rtn.push(tags[i]);
   34: 			if (expCnt > 0 && rtn.length > expCnt) { break; }
   35: 		}
   36: 	}
   37: 	return rtn;
   38: }
   39: 
   40: //Find the first text Node under current node
   41: //Returns the node itself, not the text
   42: //NOTE: Do not call this on a node that may have multiple text Nodes 
   43: //		as children
   44: function getTextNode(node) {
   45: 	if (node.nodeType == Node.TEXT_NODE) {
   46: 		return node;
   47: 	}
   48: 	
   49: 	for(var i=0; i < node.childNodes.length; i++) {
   50: 		var rtn = getTextNode(node.childNodes[i]);
   51: 		if (rtn) { return rtn; }
   52: 	}
   53: 	return false;
   54: }
   55: 
   56: //Get object that raised event
   57: function getEventObject(e) {
   58: 	//Make sure I have the event
   59: 	if (!e) { e = window.event; }
   60: 	
   61: 	//Get the object that raised the event
   62: 	if (e.target) {
   63: 		return e.target;
   64: 	} else if (e.srcElement) {
   65: 		return e.srcElement;
   66: 	}
   67: 	return false;
   68: }
   69: 
   70: //Attach an onClick event handler to a node
   71: function attachClickEvent(node, func) {
   72: 	node.onclick = func; //Add event
   73: 	
   74: 	if (!isIE) {
   75: 		//Allow me to raise events
   76: 		node.addEventListener("onclick", func, true); //false to get it in bubble not capture
   77: 	}
   78: 	if (node.captureEvents) { node.captureEvents(Event.CLICK); }
   79: }
   80: 
   81: //Fire an event on a given node
   82: function dispatchEvent(node, eventName) {
   83: 	if (document.createEvent) {
   84: 		var evt = document.createEvent("Events"); //Simple event object
   85: 		evt.initEvent(eventName, true, true); //true for can bubble, true for cancelable
   86: 		node.dispatchEvent(evt);
   87: 	} else {
   88: 		//IE version
   89: 		var evt = document.createEventObject();
   90: 		node.fireEvent(eventName,evt);
   91: 		evt.cancelBubble = true; 
   92: 	}
   93: }
   94: 
   95: /*
   96:  * Setup Functions
   97:  */
   98: //Master setup function
   99: function setEvents() {
  100: 	setupHandin();
  101: 	setupGrading();
  102: 	setupButtons();
  103: }
  104:  
  105: //Setup the File handin list
  106: function setupHandin() {
  107: 	var handin;
  108: 	
  109: 	//Create the 'Collapse' button
  110: 	var li = document.createElement('li');
  111: 	var a = document.createElement('a');
  112: 	var txt = document.createTextNode('Collapse');
  113: 	a.setAttribute('href', '#');
  114: 	attachClickEvent(a, onSlideDrawer);
  115: 	a.appendChild(txt);
  116: 	li.appendChild(a);
  117: 	
  118: 	//Find the handin list
  119: 	var lists = myGetElementsByClass('ul', 'LC_GRADING_handininfo', 1);
  120: 	if (lists.length > 0) {
  121: 		handin = lists[0];
  122: 	} else {
  123: 		return false;
  124: 	}
  125: 	
  126: 	//Trim the displayed file paths
  127: 	for(var i=0; i < handin.childNodes.length; i++) {
  128: 		var txt = getTextNode(handin.childNodes[i]);
  129: 		if (txt) {
  130: 			var j = txt.nodeValue.indexOf('portfolio/');
  131: 			if (j > 0) {
  132: 				txt.nodeValue = txt.nodeValue.substr(j + 'portfolio/'.length);
  133: 			}
  134: 		}
  135: 	}
  136: 	
  137: 	//Add the button
  138: 	handin.insertBefore(li, handin.firstChild);
  139: 	
  140: 	//Adjust height of the list
  141: 	var item_cnt = handin.getElementsByTagName('li').length * 1.3; //Lines take about 1.3em ea.
  142: 	handin.style.height = item_cnt + 'em';
  143: }
  144: 
  145: //Add events to all grading radio buttons
  146: function setupGrading() {
  147: 	var inputs = document.getElementsByTagName('input');
  148: 	
  149: 	for (var i = 0; i < inputs.length; i++)  {
  150: 		if (inputs[i].type == "radio") {
  151: 			var val = inputs[i].value;
  152: 			if (val == "pass" || val == "fail" || val == "review") {
  153: 				attachClickEvent(inputs[i], onSetGrade); //Add event
  154: 			}
  155: 			if (inputs[i].checked) {
  156: 				dispatchEvent(inputs[i], 'onclick');
  157: 			}
  158: 		}
  159: 	}
  160: }
  161: 
  162: //Adjust the Done/Stop/Fail All button set
  163: function setupButtons() {
  164:     //Create Fail All button
  165: 	var btn = document.createElement('input');
  166: 	btn.setAttribute('type', 'button');
  167: 	btn.setAttribute('value', 'Fail Rest');
  168: 	attachClickEvent(btn, onFailRest);
  169: 
  170:     //Add the button in
  171: 	var div = myGetElementsByClass('div','LC_GRADING_maincontrols', 1);
  172:     if (div.length > 0) { div[0].appendChild(btn); }
  173: }
  174: 
  175: /*
  176:  * Events
  177:  */
  178: //Slide the Handin list up and down like a drawer
  179: function onSlideDrawer(e) {
  180: 	var obj = getEventObject(e);
  181: 	var txt = getTextNode(obj);
  182: 	txt.nodeValue = (txt.nodeValue == 'Collapse') ? 'Expand':'Collapse';
  183: 	
  184: 	var list = obj.parentNode.parentNode;
  185: 	var item_cnt = (txt.nodeValue == 'Collapse') ?  list.getElementsByTagName('li').length : 1;
  186: 	list.style.height = (item_cnt*1.3) + 'em'; //Lines take about 1.3em ea.
  187: 	return false;
  188: }
  189: 
  190: //Fail all ungraded criteria
  191: function onFailRest(e) {
  192: 	var obj = getEventObject(e);	
  193: 	var inputs = document.getElementsByTagName('input');
  194: 	
  195: 	var graded = false;
  196: 	for (var i = 0; i < inputs.length; i++)  {
  197: 		if (inputs[i].type == "radio") {
  198: 			var val = inputs[i].value;
  199: 			if (val == "ungraded" ) {
  200: 				//Flag whether this criteria is graded or not
  201: 				//I depend on 'ungraded' being the first radio button in each set
  202: 				graded = ! inputs[i].checked;
  203: 			} else if (val == "fail" && !graded) {
  204: 				inputs[i].checked = true;
  205: 				
  206: 				//Fire the onclick event to get colors
  207: 				dispatchEvent(inputs[i], 'onclick');
  208: 			}
  209: 		}
  210: 	}
  211: }
  212: 
  213: //Set bacground for grade chosen
  214: function onSetGrade( e ) {
  215: 	var obj = getEventObject(e);
  216: 	var grade;
  217: 	var gradediv;
  218: 	
  219: 	//Find the Radio button and get it's value
  220: 	if (obj.tagName == 'INPUT') {
  221: 		grade = obj.value;
  222: 	} else {
  223: 		rdo = obj.getElementsByTagName('INPUT');
  224: 		if (rdo.length > 0) { grade = rdo[0].value; }
  225: 	}
  226: 	
  227: 	//Search for parent DIV
  228: 	gradediv = obj;
  229: 	while (gradediv.tagName != 'DIV') {
  230: 		gradediv = gradediv.parentNode;
  231: 	}
  232: 
  233: 	gradediv.className = "LC_GRADING_grade LC_GRADING_" + grade;
  234: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>