Annotation of loncom/homework/task_grading.js, revision 1.3
1.1 albertel 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
1.2 albertel 71: function attachEvent(node, eventName, func) {
72: node[eventName] = func; //Add event
73:
1.1 albertel 74: if (!isIE) {
75: //Allow me to raise events
1.2 albertel 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]);
1.1 albertel 85: }
86: }
87:
1.2 albertel 88:
1.1 albertel 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', '#');
1.3 ! albertel 122: attachEvent(a, "onclick", onSlideDrawer);
1.1 albertel 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;
1.2 albertel 160: if (val == "pass" || val == "fail" || val == "review" || val == "ungraded") {
161: attachEvent(inputs[i], "onchange", onSetGrade);
162: attachEvent(inputs[i], "onclick", onSetGrade);
1.1 albertel 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() {
1.2 albertel 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: }
1.1 albertel 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
1.2 albertel 198: function onFailRest() {
1.1 albertel 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:
1.2 albertel 219: //Set background for grade chosen
1.1 albertel 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: }
1.2 albertel 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: }
1.1 albertel 238:
239: gradediv.className = "LC_GRADING_grade LC_GRADING_" + grade;
240: }
1.2 albertel 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>