File:  [LON-CAPA] / loncom / homework / task_grading.js
Revision 1.3: download - view: text, annotated - select for diffs
Thu Apr 20 19:20:08 2006 UTC (18 years ago) by albertel
Branches: MAIN
CVS tags: version_2_9_X, version_2_9_99_0, version_2_9_1, version_2_9_0, version_2_8_X, version_2_8_99_1, version_2_8_99_0, version_2_8_2, version_2_8_1, version_2_8_0, version_2_7_X, version_2_7_99_1, version_2_7_99_0, version_2_7_1, version_2_7_0, version_2_6_X, version_2_6_99_1, version_2_6_99_0, version_2_6_3, version_2_6_2, version_2_6_1, version_2_6_0, version_2_5_X, version_2_5_99_1, version_2_5_99_0, version_2_5_2, version_2_5_1, version_2_5_0, version_2_4_X, version_2_4_99_0, version_2_4_2, version_2_4_1, version_2_4_0, version_2_3_X, version_2_3_99_0, version_2_3_2, version_2_3_1, version_2_3_0, version_2_2_X, version_2_2_99_1, version_2_2_99_0, version_2_2_2, version_2_2_1, version_2_2_0, version_2_1_99_3, version_2_1_99_2, version_2_1_99_1, version_2_1_99_0, version_2_12_X, version_2_11_X, version_2_11_4_uiuc, version_2_11_4_msu, version_2_11_4, version_2_11_3_uiuc, version_2_11_3_msu, version_2_11_3, version_2_11_2_uiuc, version_2_11_2_msu, version_2_11_2_educog, version_2_11_2, version_2_11_1, version_2_11_0_RC3, version_2_11_0_RC2, version_2_11_0_RC1, version_2_11_0, version_2_10_X, version_2_10_1, version_2_10_0_RC2, version_2_10_0_RC1, version_2_10_0, loncapaMITrelate_1, language_hyphenation_merge, language_hyphenation, bz6209-base, bz6209, bz5969, bz2851, PRINT_INCOMPLETE_base, PRINT_INCOMPLETE, HEAD, GCI_3, GCI_2, GCI_1, BZ5971-printing-apage, BZ5434-fox, BZ4492-merge, BZ4492-feature_horizontal_radioresponse, BZ4492-feature_Support_horizontal_radioresponse, BZ4492-Support_horizontal_radioresponse
- bug fix

    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 attachEvent(node, eventName, func) {
   72: 	node[eventName] = func; //Add event
   73: 
   74: 	if (!isIE) {
   75: 		//Allow me to raise events
   76: 		node.addEventListener(eventName, func, true); //false to get it in bubble not capture
   77: 	}
   78: 	if (node.captureEvents) {
   79: 		var eventMap = new Object;
   80: 		eventMap["onclick"] = Event.CLICK;
   81: 		eventMap["onchange"] = Event.CHANGE;
   82: 		eventMap["onsubmit"] = Event.SUBMIT;
   83: 		if (! eventMap[eventName]) { return false; }
   84: 		node.captureEvents(eventMap[eventName]);
   85: 	}
   86: }
   87: 
   88: 
   89: //Fire an event on a given node
   90: function dispatchEvent(node, eventName) {
   91: 	if (document.createEvent) {
   92: 		var evt = document.createEvent("Events"); //Simple event object
   93: 		evt.initEvent(eventName, true, true); //true for can bubble, true for cancelable
   94: 		node.dispatchEvent(evt);
   95: 	} else {
   96: 		//IE version
   97: 		var evt = document.createEventObject();
   98: 		node.fireEvent(eventName,evt);
   99: 		evt.cancelBubble = true; 
  100: 	}
  101: }
  102: 
  103: /*
  104:  * Setup Functions
  105:  */
  106: //Master setup function
  107: function setEvents() {
  108: 	setupHandin();
  109: 	setupGrading();
  110: 	setupButtons();
  111: }
  112:  
  113: //Setup the File handin list
  114: function setupHandin() {
  115: 	var handin;
  116: 	
  117: 	//Create the 'Collapse' button
  118: 	var li = document.createElement('li');
  119: 	var a = document.createElement('a');
  120: 	var txt = document.createTextNode('Collapse');
  121: 	a.setAttribute('href', '#');
  122: 	attachEvent(a, "onclick", onSlideDrawer);
  123: 	a.appendChild(txt);
  124: 	li.appendChild(a);
  125: 	
  126: 	//Find the handin list
  127: 	var lists = myGetElementsByClass('ul', 'LC_GRADING_handininfo', 1);
  128: 	if (lists.length > 0) {
  129: 		handin = lists[0];
  130: 	} else {
  131: 		return false;
  132: 	}
  133: 	
  134: 	//Trim the displayed file paths
  135: 	for(var i=0; i < handin.childNodes.length; i++) {
  136: 		var txt = getTextNode(handin.childNodes[i]);
  137: 		if (txt) {
  138: 			var j = txt.nodeValue.indexOf('portfolio/');
  139: 			if (j > 0) {
  140: 				txt.nodeValue = txt.nodeValue.substr(j + 'portfolio/'.length);
  141: 			}
  142: 		}
  143: 	}
  144: 	
  145: 	//Add the button
  146: 	handin.insertBefore(li, handin.firstChild);
  147: 	
  148: 	//Adjust height of the list
  149: 	var item_cnt = handin.getElementsByTagName('li').length * 1.3; //Lines take about 1.3em ea.
  150: 	handin.style.height = item_cnt + 'em';
  151: }
  152: 
  153: //Add events to all grading radio buttons
  154: function setupGrading() {
  155: 	var inputs = document.getElementsByTagName('input');
  156: 	
  157: 	for (var i = 0; i < inputs.length; i++)  {
  158: 		if (inputs[i].type == "radio") {
  159: 			var val = inputs[i].value;
  160: 			if (val == "pass" || val == "fail" || val == "review" || val == "ungraded") {
  161: 				attachEvent(inputs[i], "onchange", onSetGrade);
  162: 				attachEvent(inputs[i], "onclick", onSetGrade);
  163: 			}
  164: 			if (inputs[i].checked) {
  165: 				dispatchEvent(inputs[i], 'onclick');
  166: 			}
  167: 		}
  168: 	}
  169: }
  170: 
  171: //Adjust the Done/Stop/Fail All button set
  172: function setupButtons() {
  173: 	//Setup the onSubmit validation
  174: 	var frms = document.getElementsByTagName('form');
  175: 	for(var i=0; i < frms.length; i++ ) {
  176: 		if (frms[i].name == "lonhomework") {
  177: 			attachEvent(frms[i], "onsubmit", onValidate);
  178: 		}
  179: 	}
  180: }
  181: 
  182: /*
  183:  * Events
  184:  */
  185: //Slide the Handin list up and down like a drawer
  186: function onSlideDrawer(e) {
  187: 	var obj = getEventObject(e);
  188: 	var txt = getTextNode(obj);
  189: 	txt.nodeValue = (txt.nodeValue == 'Collapse') ? 'Expand':'Collapse';
  190: 	
  191: 	var list = obj.parentNode.parentNode;
  192: 	var item_cnt = (txt.nodeValue == 'Collapse') ?  list.getElementsByTagName('li').length : 1;
  193: 	list.style.height = (item_cnt*1.3) + 'em'; //Lines take about 1.3em ea.
  194: 	return false;
  195: }
  196: 
  197: //Fail all ungraded criteria
  198: function onFailRest() {
  199: 	var inputs = document.getElementsByTagName('input');
  200: 	
  201: 	var graded = false;
  202: 	for (var i = 0; i < inputs.length; i++)  {
  203: 		if (inputs[i].type == "radio") {
  204: 			var val = inputs[i].value;
  205: 			if (val == "ungraded" ) {
  206: 				//Flag whether this criteria is graded or not
  207: 				//I depend on 'ungraded' being the first radio button in each set
  208: 				graded = ! inputs[i].checked;
  209: 			} else if (val == "fail" && !graded) {
  210: 				inputs[i].checked = true;
  211: 				
  212: 				//Fire the onclick event to get colors
  213: 				dispatchEvent(inputs[i], 'onclick');
  214: 			}
  215: 		}
  216: 	}
  217: }
  218: 
  219: //Set background for grade chosen
  220: function onSetGrade( e ) {
  221: 	var obj = getEventObject(e);
  222: 	var grade;
  223: 	var gradediv;
  224: 	
  225: 	//Search for parent DIV
  226: 	gradediv = obj;
  227: 	while (gradediv.tagName != 'DIV') {
  228: 		gradediv = gradediv.parentNode;
  229: 	}
  230: 	
  231: 	rdo = gradediv.getElementsByTagName('INPUT');
  232: 	for(var i=0; i < rdo.length; i++) {
  233: 		if ( rdo[i].checked ) {
  234: 			grade = rdo[i].value;
  235: 			break;
  236: 		}
  237: 	}
  238: 
  239: 	gradediv.className = "LC_GRADING_grade LC_GRADING_" + grade;
  240: }
  241: 
  242: //Validate form before submit
  243: function onValidate(e) {
  244: 	var obj = getEventObject(e);
  245: 	var ok = true;
  246: 	var inputs = document.getElementsByTagName('input');
  247: 	
  248: 	var cnt = 0;
  249: 	for (var i = 0; i < inputs.length; i++)  {
  250: 		if (inputs[i].type == "radio") {
  251: 			var val = inputs[i].value;
  252: 			if (val == "ungraded" && inputs[i].checked) {
  253: 					cnt++;
  254: 			}
  255: 		}
  256: 	}
  257: 	if (cnt) {
  258: 		ok = confirm("You have " + cnt + " questions still ungraded.\nThis will return an ungraded task to the queue?");
  259: 	}
  260: 	return ok;
  261: }

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