Fixes to the PaintWeb cron task.
[moodle/mihaisucan.git] / lib / javascript-static.js
blob584186406fc4ecc7ec83c93ebae802f4d9354531
1 // Miscellaneous core Javascript functions for Moodle
3 function 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     }
13 function popUpProperties(inobj) {
14 /// Legacy function
15   var op = window.open();
16   op.document.open('text/plain');
17   for (objprop in inobj) {
18     op.document.write(objprop + ' => ' + inobj[objprop] + '\n');
19   }
20   op.document.close();
23 function fillmessagebox(text) {
24 /// Legacy function
25   document.form.message.value = text;
28 function copyrichtext(textname) {
29 /// Legacy stub for old editor - to be removed soon
30   return true;
34 function checkall() {
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   }
43 function checknone() {
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   }
52 function lockoptions(formid, master, subitems) {
53   // Subitems is an array of names of sub items.
54   // Optionally, each item in subitems may have a
55   // companion hidden item in the form with the
56   // same name but prefixed by "h".
57   var form = document.forms[formid];
59   if (eval("form."+master+".checked")) {
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);
71 function lockoption(form,item) {
72   eval("form."+item+".disabled=true");/* IE thing */
73   if(form.elements['h'+item]) {
74     eval("form.h"+item+".value=1");
75   }
78 function unlockoption(form,item) {
79   eval("form."+item+".disabled=false");/* IE thing */
80   if(form.elements['h'+item]) {
81     eval("form.h"+item+".value=0");
82   }
85 /**
86  * Get the value of the 'virtual form element' with a particular name. That is,
87  * abstracts away the difference between a normal form element, like a select
88  * which is a single HTML element with a .value property, and a set of radio
89  * buttons, which is several HTML elements.
90  *
91  * @param form a HTML form.
92  * @param master the name of an element in that form.
93  * @return the value of that element.
94  */
95 function get_form_element_value(form, name) {
96     var element = form[name];
97     if (!element) {
98         return null;
99     }
100     if (element.tagName) {
101         // Ordinarly thing like a select box.
102         return element.value;
103     }
104     // Array of things, like radio buttons.
105     for (var j = 0; j < element.length; j++) {
106         var el = element[j];
107         if (el.checked) {
108             return el.value;
109         }
110     }
111     return null;
116  * Set the disabled state of the 'virtual form element' with a particular name.
117  * This abstracts away the difference between a normal form element, like a select
118  * which is a single HTML element with a .value property, and a set of radio
119  * buttons, which is several HTML elements.
121  * @param form a HTML form.
122  * @param master the name of an element in that form.
123  * @param disabled the disabled state to set.
124  */
125 function set_form_element_disabled(form, name, disabled) {
126     var element = form[name];
127     if (!element) {
128         return;
129     }
130     if (element.tagName) {
131         // Ordinarly thing like a select box.
132         element.disabled = disabled;
133     }
134     // Array of things, like radio buttons.
135     for (var j = 0; j < element.length; j++) {
136         var el = element[j];
137         el.disabled = disabled;
138     }
142  * Set the hidden state of the 'virtual form element' with a particular name.
143  * This abstracts away the difference between a normal form element, like a select
144  * which is a single HTML element with a .value property, and a set of radio
145  * buttons, which is several HTML elements.
147  * @param form a HTML form.
148  * @param master the name of an element in that form.
149  * @param hidden the hidden state to set.
150  */
151 function set_form_element_hidden(form, name, hidden) {
152     var element = form[name];
153     if (!element) {
154         return;
155     }
156     if (element.tagName) {
157         var el = findParentNode(element, 'DIV', 'fitem', false);
158         if (el!=null) {
159             el.style.display = hidden ? 'none' : '';
160             el.style.visibility = hidden ? 'hidden' : '';
161         }
162     }
163     // Array of things, like radio buttons.
164     for (var j = 0; j < element.length; j++) {
165         var el = findParentNode(element[j], 'DIV', 'fitem', false);
166         if (el!=null) {
167             el.style.display = hidden ? 'none' : '';
168             el.style.visibility = hidden ? 'hidden' : '';
169         }
170     }
173 function lockoptionsall(formid) {
174     var form = document.forms[formid];
175     var dependons = eval(formid + 'items');
176     var tolock = [];
177     var tohide = [];
178     for (var dependon in dependons) {
179         // change for MooTools compatibility
180         if (!dependons.propertyIsEnumerable(dependon)) {
181             continue;
182         }
183         if (!form[dependon]) {
184             continue;
185         }
186         for (var condition in dependons[dependon]) {
187             for (var value in dependons[dependon][condition]) {
188                 var lock;
189                 var hide = false;
190                 switch (condition) {
191                   case 'notchecked':
192                       lock = !form[dependon].checked; break;
193                   case 'checked':
194                       lock = form[dependon].checked; break;
195                   case 'noitemselected':
196                       lock = form[dependon].selectedIndex == -1; break;
197                   case 'eq':
198                       lock = get_form_element_value(form, dependon) == value; break;
199                   case 'hide':
200                       // hide as well as disable
201                       hide = true; break;
202                   default:
203                       lock = get_form_element_value(form, dependon) != value; break;
204                 }
205                 for (var ei in dependons[dependon][condition][value]) {
206                     var eltolock = dependons[dependon][condition][value][ei];
207                     if (hide) {
208                         tohide[eltolock] = true;
209                     }
210                     if (tolock[eltolock] != null) {
211                         tolock[eltolock] = lock || tolock[eltolock];
212                     } else {
213                         tolock[eltolock] = lock;
214                     }
215                 }
216             }
217         }
218     }
219     for (var el in tolock) {
220         // change for MooTools compatibility
221         if (!tolock.propertyIsEnumerable(el)) {
222             continue;
223         }
224         set_form_element_disabled(form, el, tolock[el]);
225         if (tohide.propertyIsEnumerable(el)) {
226             set_form_element_hidden(form, el, tolock[el]);
227         }
228     }
229     return true;
232 function lockoptionsallsetup(formid) {
233     var form = document.forms[formid];
234     var dependons = eval(formid+'items');
235     for (var dependon in dependons) {
236         // change for MooTools compatibility
237         if (!dependons.propertyIsEnumerable(dependon)) {
238             continue;
239         }
240         var masters = form[dependon];
241         if (!masters) {
242             continue;
243         }
244         if (masters.tagName) {
245             // If master is radio buttons, we get an array, otherwise we don't.
246             // Convert both cases to an array for convinience.
247             masters = [masters];
248         }
249         for (var j = 0; j < masters.length; j++) {
250             master = masters[j];
251             master.formid = formid;
252             master.onclick  = function() {return lockoptionsall(this.formid);};
253             master.onblur   = function() {return lockoptionsall(this.formid);};
254             master.onchange = function() {return lockoptionsall(this.formid);};
255         }
256     }
257     for (var i = 0; i < form.elements.length; i++) {
258         var formelement = form.elements[i];
259         if (formelement.type=='reset') {
260             formelement.formid = formid;
261             formelement.onclick  = function() {this.form.reset();return lockoptionsall(this.formid);};
262             formelement.onblur   = function() {this.form.reset();return lockoptionsall(this.formid);};
263             formelement.onchange = function() {this.form.reset();return lockoptionsall(this.formid);};
264         }
265     }
266     return lockoptionsall(formid);
270 function submitFormById(id) {
271     var theform = document.getElementById(id);
272     if(!theform) {
273         return false;
274     }
275     if(theform.tagName.toLowerCase() != 'form') {
276         return false;
277     }
278     if(!theform.onsubmit || theform.onsubmit()) {
279         return theform.submit();
280     }
283 function select_all_in(elTagName, elClass, elId) {
284     var inputs = document.getElementsByTagName('input');
285     inputs = filterByParent(inputs, function(el) {return findParentNode(el, elTagName, elClass, elId);});
286     for(var i = 0; i < inputs.length; ++i) {
287         if(inputs[i].type == 'checkbox' || inputs[i].type == 'radio') {
288             inputs[i].checked = 'checked';
289         }
290     }
293 function deselect_all_in(elTagName, elClass, elId) {
294     var inputs = document.getElementsByTagName('INPUT');
295     inputs = filterByParent(inputs, function(el) {return findParentNode(el, elTagName, elClass, elId);});
296     for(var i = 0; i < inputs.length; ++i) {
297         if(inputs[i].type == 'checkbox' || inputs[i].type == 'radio') {
298             inputs[i].checked = '';
299         }
300     }
303 function confirm_if(expr, message) {
304     if(!expr) {
305         return true;
306     }
307     return confirm(message);
312     findParentNode (start, elementName, elementClass, elementID)
314     Travels up the DOM hierarchy to find a parent element with the
315     specified tag name, class, and id. All conditions must be met,
316     but any can be ommitted. Returns the BODY element if no match
317     found.
319 function findParentNode(el, elName, elClass, elId) {
320     while(el.nodeName.toUpperCase() != 'BODY') {
321         if(
322             (!elName || el.nodeName.toUpperCase() == elName) &&
323             (!elClass || el.className.indexOf(elClass) != -1) &&
324             (!elId || el.id == elId))
325         {
326             break;
327         }
328         el = el.parentNode;
329     }
330     return el;
333     findChildNode (start, elementName, elementClass, elementID)
335     Travels down the DOM hierarchy to find all child elements with the
336     specified tag name, class, and id. All conditions must be met,
337     but any can be ommitted.
338     Doesn't examine children of matches.
340 function findChildNodes(start, tagName, elementClass, elementID, elementName) {
341     var children = new Array();
342     for (var i = 0; i < start.childNodes.length; i++) {
343         var classfound = false;
344         var child = start.childNodes[i];
345         if((child.nodeType == 1) &&//element node type
346                   (elementClass && (typeof(child.className)=='string'))) {
347             var childClasses = child.className.split(/\s+/);
348             for (var childClassIndex in childClasses) {
349                 if (childClasses[childClassIndex]==elementClass) {
350                     classfound = true;
351                     break;
352                 }
353             }
354         }
355         if(child.nodeType == 1) { //element node type
356             if  ( (!tagName || child.nodeName == tagName) &&
357                 (!elementClass || classfound)&&
358                 (!elementID || child.id == elementID) &&
359                 (!elementName || child.name == elementName))
360             {
361                 children = children.concat(child);
362             } else {
363                 children = children.concat(findChildNodes(child, tagName, elementClass, elementID, elementName));
364             }
365         }
366     }
367     return children;
370     elementSetHide (elements, hide)
372     Adds or removes the "hide" class for the specified elements depending on boolean hide.
374 function elementShowAdvanced(elements, show) {
375     for (var elementIndex in elements) {
376         element = elements[elementIndex];
377         element.className = element.className.replace(new RegExp(' ?hide'), '')
378         if(!show) {
379             element.className += ' hide';
380         }
381     }
384 function showAdvancedInit(addBefore, nameAttr, buttonLabel, hideText, showText) {
385     var showHideButton = document.createElement("input");
386     showHideButton.type = 'button';
387     showHideButton.value = buttonLabel;
388     showHideButton.name = nameAttr;
389     showHideButton.moodle = {
390         hideLabel: hideText,
391         showLabel: showText
392     };
393     YAHOO.util.Event.addListener(showHideButton, 'click', showAdvancedOnClick);
394     el = document.getElementById(addBefore);
395     el.parentNode.insertBefore(showHideButton, el);
398 function showAdvancedOnClick(e) {
399     var button = e.target ? e.target : e.srcElement;
401     var toSet=findChildNodes(button.form, null, 'advanced');
402     var buttontext = '';
403     if (button.form.elements['mform_showadvanced_last'].value == '0' ||  button.form.elements['mform_showadvanced_last'].value == '' ) {
404         elementShowAdvanced(toSet, true);
405         buttontext = button.moodle.hideLabel;
406         button.form.elements['mform_showadvanced_last'].value = '1';
407     } else {
408         elementShowAdvanced(toSet, false);
409         buttontext = button.moodle.showLabel;
410         button.form.elements['mform_showadvanced_last'].value = '0';
411     }
412     var formelements = button.form.elements;
413     // Fixed MDL-10506
414     for (var i = 0; i < formelements.length; i++) {
415         if (formelements[i] && formelements[i].name && (formelements[i].name=='mform_showadvanced')) {
416             formelements[i].value = buttontext;
417         }
418     }
419     //never submit the form if js is enabled.
420     return false;
423 function unmaskPassword(id) {
424   var pw = document.getElementById(id);
425   var chb = document.getElementById(id+'unmask');
427   try {
428     // first try IE way - it can not set name attribute later
429     if (chb.checked) {
430       var newpw = document.createElement('<input type="text" name="'+pw.name+'">');
431     } else {
432       var newpw = document.createElement('<input type="password" name="'+pw.name+'">');
433     }
434     newpw.attributes['class'].nodeValue = pw.attributes['class'].nodeValue;
435   } catch (e) {
436     var newpw = document.createElement('input');
437     newpw.setAttribute('name', pw.name);
438     if (chb.checked) {
439       newpw.setAttribute('type', 'text');
440     } else {
441       newpw.setAttribute('type', 'password');
442     }
443     newpw.setAttribute('class', pw.getAttribute('class'));
444   }
445   newpw.id = pw.id;
446   newpw.size = pw.size;
447   newpw.onblur = pw.onblur;
448   newpw.onchange = pw.onchange;
449   newpw.value = pw.value;
450   pw.parentNode.replaceChild(newpw, pw);
454     elementToggleHide (element, elementFinder)
456     If elementFinder is not provided, toggles the "hidden" class for the specified element.
457     If elementFinder is provided, then the "hidden" class will be toggled for the object
458     returned by the function call elementFinder(element).
460     If persistent == true, also sets a cookie for this.
462 function elementToggleHide(el, persistent, elementFinder, strShow, strHide) {
463     if(!elementFinder) {
464         var obj = el;  //el:container
465         el = document.getElementById('togglehide_'+obj.id);
466     }
467     else {
468         var obj = elementFinder(el);  //el:button.
469     }
470     if(obj.className.indexOf('hidden') == -1) {
471         obj.className += ' hidden';
472         if (el.src) {
473             el.src = el.src.replace('switch_minus', 'switch_plus');
474             el.alt = strShow;
475             el.title = strShow;
476         }
477         var shown = 0;
478     }
479     else {
480         obj.className = obj.className.replace(new RegExp(' ?hidden'), '');
481         if (el.src) {
482             el.src = el.src.replace('switch_plus', 'switch_minus');
483             el.alt = strHide;
484             el.title = strHide;
485         }
486         var shown = 1;
487     }
489     if(persistent == true) {
490         new cookie('hide:' + obj.id, 1, (shown ? -1 : 356), '/').set();
491     }
494 function elementCookieHide(id, strShow, strHide) {
495     var obj  = document.getElementById(id);
496     var cook = new cookie('hide:' + id).read();
497     if(cook != null) {
498         elementToggleHide(obj, false, null, strShow, strHide);
499     }
502 function filterByParent(elCollection, parentFinder) {
503     var filteredCollection = [];
504     for(var i = 0; i < elCollection.length; ++i) {
505         var findParent = parentFinder(elCollection[i]);
506         if(findParent.nodeName != 'BODY') {
507             filteredCollection.push(elCollection[i]);
508         }
509     }
510     return filteredCollection;
514     All this is here just so that IE gets to handle oversized blocks
515     in a visually pleasing manner. It does a browser detect. So sue me.
518 function fix_column_widths() {
519     var agt = navigator.userAgent.toLowerCase();
520     if ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1)) {
521         fix_column_width('left-column');
522         fix_column_width('right-column');
523     }
526 function fix_column_width(colName) {
527     if(column = document.getElementById(colName)) {
528         if(!column.offsetWidth) {
529             setTimeout("fix_column_width('" + colName + "')", 20);
530             return;
531         }
533         var width = 0;
534         var nodes = column.childNodes;
536         for(i = 0; i < nodes.length; ++i) {
537             if(nodes[i].className.indexOf("sideblock") != -1 ) {
538                 if(width < nodes[i].offsetWidth) {
539                     width = nodes[i].offsetWidth;
540                 }
541             }
542         }
544         for(i = 0; i < nodes.length; ++i) {
545             if(nodes[i].className.indexOf("sideblock") != -1 ) {
546                 nodes[i].style.width = width + 'px';
547             }
548         }
549     }
554    Insert myValue at current cursor position
555  */
556 function insertAtCursor(myField, myValue) {
557     // IE support
558     if (document.selection) {
559         myField.focus();
560         sel = document.selection.createRange();
561         sel.text = myValue;
562     }
563     // Mozilla/Netscape support
564     else if (myField.selectionStart || myField.selectionStart == '0') {
565         var startPos = myField.selectionStart;
566         var endPos = myField.selectionEnd;
567         myField.value = myField.value.substring(0, startPos)
568             + myValue + myField.value.substring(endPos, myField.value.length);
569     } else {
570         myField.value += myValue;
571     }
576         Call instead of setting window.onload directly or setting body onload=.
577         Adds your function to a chain of functions rather than overwriting anything
578         that exists.
580 function addonload(fn) {
581     var oldhandler=window.onload;
582     window.onload=function() {
583         if(oldhandler) oldhandler();
584             fn();
585     }