MDL-12635 - Manual grading report does not check capabilites - also, only show the...
[moodle.git] / lib / javascript-static.js
CommitLineData
47aa42e2 1// Miscellaneous core Javascript functions for Moodle
2
b48fd7b5 3function popupchecker(msg) {
4 var testwindow = window.open('itestwin.html', '', 'width=1,height=1,left=0,top=0,scrollbars=no');
5 if (testwindow == null)
6 {alert(msg);}
7 else {
8 testwindow.close();
9 }
10}
11
d2ce367f 12/*
63d28811 13function popUpProperties(inobj) {
d2ce367f 14/// Legacy function
15 var op = window.open();
63d28811 16 op.document.open('text/plain');
17 for (objprop in inobj) {
18 op.document.write(objprop + ' => ' + inobj[objprop] + '\n');
19 }
20 op.document.close();
21}
22
23function fillmessagebox(text) {
d2ce367f 24/// Legacy function
63d28811 25 document.form.message.value = text;
26}
27
28function copyrichtext(textname) {
29/// Legacy stub for old editor - to be removed soon
30 return true;
31}
d2ce367f 32*/
63d28811 33
34function checkall() {
d2ce367f 35 var el = document.getElementsByTagName('input');
36 for(var i=0; i<el.length; i++) {
37 if(el[i].type == 'checkbox') {
38 el[i].checked = true;
39 }
40 }
63d28811 41}
42
03f9425f 43function checknone() {
d2ce367f 44 var el = document.getElementsByTagName('input');
45 for(var i=0; i<el.length; i++) {
46 if(el[i].type == 'checkbox') {
47 el[i].checked = false;
48 }
49 }
03f9425f 50}
51
d2ce367f 52function lockoptions(formid, master, subitems) {
027d0485 53 // Subitems is an array of names of sub items.
54 // Optionally, each item in subitems may have a
63d28811 55 // companion hidden item in the form with the
027d0485 56 // same name but prefixed by "h".
d2ce367f 57 var form = document.forms[formid];
58
59 if (eval("form."+master+".checked")) {
63d28811 60 for (i=0; i<subitems.length; i++) {
61 unlockoption(form, subitems[i]);
62 }
63 } else {
64 for (i=0; i<subitems.length; i++) {
65 lockoption(form, subitems[i]);
66 }
67 }
68 return(true);
69}
70
f07b9627 71function lockoption(form,item) {
d2ce367f 72 eval("form."+item+".disabled=true");/* IE thing */
73 if(form.elements['h'+item]) {
74 eval("form.h"+item+".value=1");
f07b9627 75 }
76}
77
78function unlockoption(form,item) {
d2ce367f 79 eval("form."+item+".disabled=false");/* IE thing */
80 if(form.elements['h'+item]) {
81 eval("form.h"+item+".value=0");
f07b9627 82 }
83}
dd07bbac 84
85
50ef8eb9 86function lockoptionsall(formid) {
dd07bbac 87 var form = document.forms[formid];
88 var dependons = eval(formid+'items');
632b88d5 89 var tolock = Array();
dd07bbac 90 for (var dependon in dependons) {
d63ef3b8 91 // change for MooTools compatibility
92 if (!dependons.propertyIsEnumerable(dependon)) {
93 continue;
94 }
dd07bbac 95 var master = form[dependon];
d63ef3b8 96 if (master === undefined) {
4bc24867 97 continue;
98 }
dd07bbac 99 for (var condition in dependons[dependon]) {
100 for (var value in dependons[dependon][condition]) {
101 var lock;
102 switch (condition) {
103 case 'notchecked':
104 lock = !master.checked; break;
105 case 'checked':
106 lock = master.checked; break;
107 case 'noitemselected':
108 lock = master.selectedIndex==-1; break;
109 case 'eq':
110 lock = master.value==value; break;
111 default:
112 lock = master.value!=value; break;
113 }
114 for (var ei in dependons[dependon][condition][value]) {
d63ef3b8 115 // change for MooTools compatibility
116 if (!window.webkit && (!dependons[dependon][condition][value].propertyIsEnumerable(ei))) {
117 continue;
118 }
632b88d5 119 var eltolock = dependons[dependon][condition][value][ei];
120 if (tolock[eltolock] != null){
121 tolock[eltolock] =
122 lock || tolock[eltolock];
123 } else {
124 tolock[eltolock] = lock;
125 }
dd07bbac 126 }
127 }
50ef8eb9 128 }
dd07bbac 129 }
632b88d5 130 for (var el in tolock){
d63ef3b8 131 // change for MooTools compatibility
132 if (!tolock.propertyIsEnumerable(el)) {
133 continue;
134 }
632b88d5 135 var formelement = form[el];
d63ef3b8 136 if ((formelement === undefined) || (formelement.disabled === undefined)) {
4bc24867 137 continue;
138 }
632b88d5 139 formelement.disabled = tolock[el];
140 }
dd07bbac 141 return true;
50ef8eb9 142}
143
d01a38cb 144function lockoptionsallsetup(formid) {
dd07bbac 145 var form = document.forms[formid];
146 var dependons = eval(formid+'items');
147 for (var dependon in dependons) {
d63ef3b8 148 // change for MooTools compatibility
149 if (!dependons.propertyIsEnumerable(dependon)) {
150 continue;
151 }
dd07bbac 152 var master = form[dependon];
d63ef3b8 153 if (master === undefined) {
4bc24867 154 continue;
155 }
c0056e22 156 master.formid = formid;
157 master.onclick = function() {return lockoptionsall(this.formid);};
158 master.onblur = function() {return lockoptionsall(this.formid);};
159 master.onchange = function() {return lockoptionsall(this.formid);};
dd07bbac 160 }
161 for (var i = 0; i < form.elements.length; i++){
162 var formelement = form.elements[i];
163 if (formelement.type=='reset') {
c0056e22 164 formelement.formid = formid;
165 formelement.onclick = function() {this.form.reset();return lockoptionsall(this.formid);};
166 formelement.onblur = function() {this.form.reset();return lockoptionsall(this.formid);};
167 formelement.onchange = function() {this.form.reset();return lockoptionsall(this.formid);};
dd07bbac 168 }
169 }
170 return lockoptionsall(formid);
d01a38cb 171}
50ef8eb9 172
7678e65c 173
174function submitFormById(id) {
175 var theform = document.getElementById(id);
176 if(!theform) {
177 return false;
178 }
bb006c95 179 if(theform.tagName.toLowerCase() != 'form') {
7678e65c 180 return false;
181 }
182 if(!theform.onsubmit || theform.onsubmit()) {
183 return theform.submit();
184 }
185}
363cb62c 186
8ceb09e0 187function select_all_in(elTagName, elClass, elId) {
d2ce367f 188 var inputs = document.getElementsByTagName('input');
8ceb09e0 189 inputs = filterByParent(inputs, function(el) {return findParentNode(el, elTagName, elClass, elId);});
363cb62c 190 for(var i = 0; i < inputs.length; ++i) {
bee40515 191 if(inputs[i].type == 'checkbox' || inputs[i].type == 'radio') {
363cb62c 192 inputs[i].checked = 'checked';
193 }
194 }
195}
196
8ceb09e0 197function deselect_all_in(elTagName, elClass, elId) {
363cb62c 198 var inputs = document.getElementsByTagName('INPUT');
8ceb09e0 199 inputs = filterByParent(inputs, function(el) {return findParentNode(el, elTagName, elClass, elId);});
363cb62c 200 for(var i = 0; i < inputs.length; ++i) {
bee40515 201 if(inputs[i].type == 'checkbox' || inputs[i].type == 'radio') {
363cb62c 202 inputs[i].checked = '';
203 }
204 }
205}
206
207function confirm_if(expr, message) {
208 if(!expr) {
209 return true;
210 }
211 return confirm(message);
212}
47aa42e2 213
214
215/*
216 findParentNode (start, elementName, elementClass, elementID)
50ef8eb9 217
47aa42e2 218 Travels up the DOM hierarchy to find a parent element with the
219 specified tag name, class, and id. All conditions must be met,
220 but any can be ommitted. Returns the BODY element if no match
221 found.
222*/
223function findParentNode(el, elName, elClass, elId) {
ef4d42fd 224 while(el.nodeName.toUpperCase() != 'BODY') {
47aa42e2 225 if(
ef4d42fd 226 (!elName || el.nodeName.toUpperCase() == elName) &&
47aa42e2 227 (!elClass || el.className.indexOf(elClass) != -1) &&
228 (!elId || el.id == elId))
229 {
230 break;
231 }
232 el = el.parentNode;
233 }
234 return el;
235}
19194f82 236/*
237 findChildNode (start, elementName, elementClass, elementID)
238
239 Travels down the DOM hierarchy to find all child elements with the
240 specified tag name, class, and id. All conditions must be met,
241 but any can be ommitted.
a23f0aaf 242 Doesn't examine children of matches.
19194f82 243*/
244function findChildNodes(start, tagName, elementClass, elementID, elementName) {
245 var children = new Array();
83c9a8a2 246 for (var i = 0; i < start.childNodes.length; i++) {
a23f0aaf 247 var classfound = false;
83c9a8a2 248 var child = start.childNodes[i];
a23f0aaf 249 if((child.nodeType == 1) &&//element node type
250 (elementClass && (typeof(child.className)=='string'))){
251 var childClasses = child.className.split(/\s+/);
252 for (var childClassIndex in childClasses){
253 if (childClasses[childClassIndex]==elementClass){
254 classfound = true;
255 break;
256 }
257 }
258 }
f07b9627 259 if(child.nodeType == 1) { //element node type
260 if ( (!tagName || child.nodeName == tagName) &&
261 (!elementClass || classfound)&&
262 (!elementID || child.id == elementID) &&
263 (!elementName || child.name == elementName))
264 {
265 children = children.concat(child);
266 } else {
267 children = children.concat(findChildNodes(child, tagName, elementClass, elementID, elementName));
268 }
19194f82 269 }
19194f82 270 }
271 return children;
272}
273/*
274 elementSetHide (elements, hide)
275
276 Adds or removes the "hide" class for the specified elements depending on boolean hide.
277*/
278function elementShowAdvanced(elements, show) {
279 for (var elementIndex in elements){
280 element = elements[elementIndex];
281 element.className = element.className.replace(new RegExp(' ?hide'), '')
282 if(!show) {
283 element.className += ' hide';
284 }
285 }
286}
287
288function showAdvancedOnClick(button, hidetext, showtext){
289 var toSet=findChildNodes(button.form, null, 'advanced');
290 var buttontext = '';
74d15d35 291 if (button.form.elements['mform_showadvanced_last'].value == '0' || button.form.elements['mform_showadvanced_last'].value == '' ) {
19194f82 292 elementShowAdvanced(toSet, true);
293 buttontext = hidetext;
294 button.form.elements['mform_showadvanced_last'].value = '1';
295 } else {
296 elementShowAdvanced(toSet, false);
297 buttontext = showtext;
298 button.form.elements['mform_showadvanced_last'].value = '0';
299 }
300 var formelements = button.form.elements;
4ea054ec 301 // Fixed MDL-10506
302 for (var i = 0; i < formelements.length; i++){
9bf930bd 303 if (formelements[i] && formelements[i].name && (formelements[i].name=='mform_showadvanced')){
19194f82 304 formelements[i].value = buttontext;
305 }
306 }
307 //never submit the form if js is enabled.
308 return false;
309}
47aa42e2 310
54bb33eb 311function unmaskPassword(id) {
239ade45 312 var pw = document.getElementById(id);
54bb33eb 313 var chb = document.getElementById(id+'unmask');
239ade45 314
315 try {
316 // first try IE way - it can not set name attribute later
317 if (chb.checked) {
318 var newpw = document.createElement('<input type="text" name="'+pw.name+'">');
319 } else {
320 var newpw = document.createElement('<input type="password" name="'+pw.name+'">');
321 }
eba8cd63 322 newpw.attributes['class'].nodeValue = pw.attributes['class'].nodeValue;
239ade45 323 } catch (e) {
324 var newpw = document.createElement('input');
325 newpw.setAttribute('name', pw.name);
326 if (chb.checked) {
327 newpw.setAttribute('type', 'text');
328 } else {
329 newpw.setAttribute('type', 'password');
330 }
eba8cd63 331 newpw.setAttribute('class', pw.getAttribute('class'));
239ade45 332 }
333 newpw.id = pw.id;
334 newpw.size = pw.size;
335 newpw.onblur = pw.onblur;
336 newpw.onchange = pw.onchange;
337 newpw.value = pw.value;
338 pw.parentNode.replaceChild(newpw, pw);
339}
340
47aa42e2 341/*
342 elementToggleHide (element, elementFinder)
343
344 If elementFinder is not provided, toggles the "hidden" class for the specified element.
345 If elementFinder is provided, then the "hidden" class will be toggled for the object
346 returned by the function call elementFinder(element).
347
348 If persistent == true, also sets a cookie for this.
349*/
19194f82 350function elementToggleHide(el, persistent, elementFinder) {
47aa42e2 351 if(!elementFinder) {
352 var obj = el;
353 }
354 else {
355 var obj = elementFinder(el);
356 }
357 if(obj.className.indexOf('hidden') == -1) {
358 obj.className += ' hidden';
19194f82 359 var shown = 0;
47aa42e2 360 }
361 else {
19194f82 362 obj.className = obj.className.replace(new RegExp(' ?hidden'), '')
363 var shown = 1;
47aa42e2 364 }
19194f82 365
47aa42e2 366 if(persistent == true) {
367 new cookie('hide:' + obj.id, 1, (shown ? -1 : 356), '/').set();
368 }
369}
370
371
372function elementCookieHide(id) {
373 var obj = document.getElementById(id);
374 var cook = new cookie('hide:' + id).read();
375 if(cook != null) {
376 elementToggleHide(obj, false);
377 }
378}
379
380function filterByParent(elCollection, parentFinder) {
381 var filteredCollection = [];
382 for(var i = 0; i < elCollection.length; ++i) {
383 var findParent = parentFinder(elCollection[i]);
384 if(findParent.nodeName != 'BODY') {
385 filteredCollection.push(elCollection[i]);
386 }
387 }
388 return filteredCollection;
389}
390
7979105c 391/*
392 All this is here just so that IE gets to handle oversized blocks
393 in a visually pleasing manner. It does a browser detect. So sue me.
394*/
395
396function fix_column_widths() {
397 var agt = navigator.userAgent.toLowerCase();
398 if ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1)) {
399 fix_column_width('left-column');
400 fix_column_width('right-column');
401 }
402}
403
404function fix_column_width(colName) {
405 if(column = document.getElementById(colName)) {
406 if(!column.offsetWidth) {
407 setTimeout("fix_column_width('" + colName + "')", 20);
408 return;
409 }
410
411 var width = 0;
412 var nodes = column.childNodes;
413
414 for(i = 0; i < nodes.length; ++i) {
415 if(nodes[i].className.indexOf("sideblock") != -1 ) {
416 if(width < nodes[i].offsetWidth) {
417 width = nodes[i].offsetWidth;
418 }
419 }
420 }
421
422 for(i = 0; i < nodes.length; ++i) {
423 if(nodes[i].className.indexOf("sideblock") != -1 ) {
424 nodes[i].style.width = width + 'px';
425 }
426 }
427 }
428}
d13c5938 429
430
431/*
9f439b17 432 Insert myValue at current cursor position
433 */
d13c5938 434function insertAtCursor(myField, myValue) {
9f439b17 435 // IE support
436 if (document.selection) {
437 myField.focus();
438 sel = document.selection.createRange();
439 sel.text = myValue;
440 }
441 // Mozilla/Netscape support
442 else if (myField.selectionStart || myField.selectionStart == '0') {
443 var startPos = myField.selectionStart;
444 var endPos = myField.selectionEnd;
445 myField.value = myField.value.substring(0, startPos)
446 + myValue + myField.value.substring(endPos, myField.value.length);
447 } else {
448 myField.value += myValue;
449 }
d13c5938 450}
7470d6de 451
452
453/*
c0056e22 454 Call instead of setting window.onload directly or setting body onload=.
455 Adds your function to a chain of functions rather than overwriting anything
456 that exists.
457*/
7470d6de 458function addonload(fn) {
459 var oldhandler=window.onload;
460 window.onload=function() {
461 if(oldhandler) oldhandler();
c0056e22 462 fn();
7470d6de 463 }
464}