// 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 attachEvent(node, eventName, func) { node[eventName] = func; //Add event if (!isIE) { //Allow me to raise events node.addEventListener(eventName, func, true); //false to get it in bubble not capture } if (node.captureEvents) { var eventMap = new Object; eventMap["onclick"] = Event.CLICK; eventMap["onchange"] = Event.CHANGE; eventMap["onsubmit"] = Event.SUBMIT; if (! eventMap[eventName]) { return false; } node.captureEvents(eventMap[eventName]); } } //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', '#'); attachEvent(a, "onchange", 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" || val == "ungraded") { attachEvent(inputs[i], "onchange", onSetGrade); attachEvent(inputs[i], "onclick", onSetGrade); } if (inputs[i].checked) { dispatchEvent(inputs[i], 'onclick'); } } } } //Adjust the Done/Stop/Fail All button set function setupButtons() { //Setup the onSubmit validation var frms = document.getElementsByTagName('form'); for(var i=0; i < frms.length; i++ ) { if (frms[i].name == "lonhomework") { attachEvent(frms[i], "onsubmit", onValidate); } } } /* * 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() { 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 background for grade chosen function onSetGrade( e ) { var obj = getEventObject(e); var grade; var gradediv; //Search for parent DIV gradediv = obj; while (gradediv.tagName != 'DIV') { gradediv = gradediv.parentNode; } rdo = gradediv.getElementsByTagName('INPUT'); for(var i=0; i < rdo.length; i++) { if ( rdo[i].checked ) { grade = rdo[i].value; break; } } gradediv.className = "LC_GRADING_grade LC_GRADING_" + grade; } //Validate form before submit function onValidate(e) { var obj = getEventObject(e); var ok = true; var inputs = document.getElementsByTagName('input'); var cnt = 0; for (var i = 0; i < inputs.length; i++) { if (inputs[i].type == "radio") { var val = inputs[i].value; if (val == "ungraded" && inputs[i].checked) { cnt++; } } } if (cnt) { ok = confirm("You have " + cnt + " questions still ungraded.\nThis will return an ungraded task to the queue?"); } return ok; }