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