MDL-10724 Added the help buttons to the item edit form
[moodle-pu.git] / lib / javascript-static.js
blobd4477a8c3c1c5085cd8383a1aa19782263be40af
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   }
86 function lockoptionsall(formid) {
87     var form = document.forms[formid];
88     var dependons = eval(formid+'items');
89     var tolock = Array();
90     for (var dependon in dependons) {
91         // change for MooTools compatibility
92         if (!dependons.propertyIsEnumerable(dependon)) {
93             continue;
94         }
95         var master = form[dependon];
96         if (master === undefined) {
97             continue;
98         }
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]) {
115                     // change for MooTools compatibility
116                     if (!window.webkit && (!dependons[dependon][condition][value].propertyIsEnumerable(ei))) {
117                         continue;
118                     }
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                     }
126                 }
127             }
128         }
129     }
130     for (var el in tolock){
131         // change for MooTools compatibility
132         if (!tolock.propertyIsEnumerable(el)) {
133             continue;
134         }
135         var formelement = form[el];
136         if ((formelement === undefined) || (formelement.disabled === undefined)) {
137             continue;
138         }
139         formelement.disabled = tolock[el];
140     }
141     return true;
144 function lockoptionsallsetup(formid) {
145     var form = document.forms[formid];
146     var dependons = eval(formid+'items');
147     for (var dependon in dependons) {
148         // change for MooTools compatibility
149         if (!dependons.propertyIsEnumerable(dependon)) {
150             continue;
151         }
152         var master = form[dependon];
153         if (master === undefined) {
154             continue;
155         }
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);};
160     }
161     for (var i = 0; i < form.elements.length; i++){
162         var formelement = form.elements[i];
163         if (formelement.type=='reset') {
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);};
168         }
169     }
170     return lockoptionsall(formid);
174 function submitFormById(id) {
175     var theform = document.getElementById(id);
176     if(!theform) {
177         return false;
178     }
179     if(theform.tagName.toLowerCase() != 'form') {
180         return false;
181     }
182     if(!theform.onsubmit || theform.onsubmit()) {
183         return theform.submit();
184     }
187 function select_all_in(elTagName, elClass, elId) {
188     var inputs = document.getElementsByTagName('input');
189     inputs = filterByParent(inputs, function(el) {return findParentNode(el, elTagName, elClass, elId);});
190     for(var i = 0; i < inputs.length; ++i) {
191         if(inputs[i].type == 'checkbox' || inputs[i].type == 'radio') {
192             inputs[i].checked = 'checked';
193         }
194     }
197 function deselect_all_in(elTagName, elClass, elId) {
198     var inputs = document.getElementsByTagName('INPUT');
199     inputs = filterByParent(inputs, function(el) {return findParentNode(el, elTagName, elClass, elId);});
200     for(var i = 0; i < inputs.length; ++i) {
201         if(inputs[i].type == 'checkbox' || inputs[i].type == 'radio') {
202             inputs[i].checked = '';
203         }
204     }
207 function confirm_if(expr, message) {
208     if(!expr) {
209         return true;
210     }
211     return confirm(message);
216     findParentNode (start, elementName, elementClass, elementID)
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.
223 function findParentNode(el, elName, elClass, elId) {
224     while(el.nodeName.toUpperCase() != 'BODY') {
225         if(
226             (!elName || el.nodeName.toUpperCase() == elName) &&
227             (!elClass || el.className.indexOf(elClass) != -1) &&
228             (!elId || el.id == elId))
229         {
230             break;
231         }
232         el = el.parentNode;
233     }
234     return el;
237     findChildNode (start, elementName, elementClass, elementID)
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.
242     Doesn't examine children of matches.
244 function findChildNodes(start, tagName, elementClass, elementID, elementName) {
245     var children = new Array();
246     for (var i = 0; i < start.childNodes.length; i++) {
247         var classfound = false;
248         var child = start.childNodes[i];
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         }
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             }
269         }
270     }
271     return children;
274     elementSetHide (elements, hide)
276     Adds or removes the "hide" class for the specified elements depending on boolean hide.
278 function 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     }
288 function showAdvancedOnClick(button, hidetext, showtext){
289     var toSet=findChildNodes(button.form, null, 'advanced');
290     var buttontext = '';
291     if (button.form.elements['mform_showadvanced_last'].value == '0' ||  button.form.elements['mform_showadvanced_last'].value == '' ) {
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;
301     for (var i in formelements){
302         if (formelements[i] && formelements[i].name && (formelements[i].name=='mform_showadvanced')){
303             formelements[i].value = buttontext;
304         }
305     }
306     //never submit the form if js is enabled.
307     return false;
310 function unmaskPassword(id) {
311   var pw = document.getElementById(id);
312   var chb = document.getElementById(id+'unmask');
314   try {
315     // first try IE way - it can not set name attribute later
316     if (chb.checked) {
317       var newpw = document.createElement('<input type="text" name="'+pw.name+'">');
318     } else {
319       var newpw = document.createElement('<input type="password" name="'+pw.name+'">');
320     }
321     newpw.attributes['class'].nodeValue = pw.attributes['class'].nodeValue;
322   } catch (e) {
323     var newpw = document.createElement('input');
324     newpw.setAttribute('name', pw.name);
325     if (chb.checked) {
326       newpw.setAttribute('type', 'text');
327     } else {
328       newpw.setAttribute('type', 'password');
329     }
330     newpw.setAttribute('class', pw.getAttribute('class'));
331   }
332   newpw.id = pw.id;
333   newpw.size = pw.size;
334   newpw.onblur = pw.onblur;
335   newpw.onchange = pw.onchange;
336   newpw.value = pw.value;
337   pw.parentNode.replaceChild(newpw, pw);
341     elementToggleHide (element, elementFinder)
343     If elementFinder is not provided, toggles the "hidden" class for the specified element.
344     If elementFinder is provided, then the "hidden" class will be toggled for the object
345     returned by the function call elementFinder(element).
347     If persistent == true, also sets a cookie for this.
349 function elementToggleHide(el, persistent, elementFinder) {
350     if(!elementFinder) {
351         var obj = el;
352     }
353     else {
354         var obj = elementFinder(el);
355     }
356     if(obj.className.indexOf('hidden') == -1) {
357         obj.className += ' hidden';
358         var shown = 0;
359     }
360     else {
361         obj.className = obj.className.replace(new RegExp(' ?hidden'), '')
362         var shown = 1;
363     }
365     if(persistent == true) {
366         new cookie('hide:' + obj.id, 1, (shown ? -1 : 356), '/').set();
367     }
371 function elementCookieHide(id) {
372     var obj  = document.getElementById(id);
373     var cook = new cookie('hide:' + id).read();
374     if(cook != null) {
375         elementToggleHide(obj, false);
376     }
379 function filterByParent(elCollection, parentFinder) {
380     var filteredCollection = [];
381     for(var i = 0; i < elCollection.length; ++i) {
382         var findParent = parentFinder(elCollection[i]);
383         if(findParent.nodeName != 'BODY') {
384             filteredCollection.push(elCollection[i]);
385         }
386     }
387     return filteredCollection;
391     All this is here just so that IE gets to handle oversized blocks
392     in a visually pleasing manner. It does a browser detect. So sue me.
395 function fix_column_widths() {
396     var agt = navigator.userAgent.toLowerCase();
397     if ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1)) {
398         fix_column_width('left-column');
399         fix_column_width('right-column');
400     }
403 function fix_column_width(colName) {
404     if(column = document.getElementById(colName)) {
405         if(!column.offsetWidth) {
406             setTimeout("fix_column_width('" + colName + "')", 20);
407             return;
408         }
410         var width = 0;
411         var nodes = column.childNodes;
413         for(i = 0; i < nodes.length; ++i) {
414             if(nodes[i].className.indexOf("sideblock") != -1 ) {
415                 if(width < nodes[i].offsetWidth) {
416                     width = nodes[i].offsetWidth;
417                 }
418             }
419         }
421         for(i = 0; i < nodes.length; ++i) {
422             if(nodes[i].className.indexOf("sideblock") != -1 ) {
423                 nodes[i].style.width = width + 'px';
424             }
425         }
426     }
431    Insert myValue at current cursor position
432  */
433 function insertAtCursor(myField, myValue) {
434     // IE support
435     if (document.selection) {
436         myField.focus();
437         sel = document.selection.createRange();
438         sel.text = myValue;
439     }
440     // Mozilla/Netscape support
441     else if (myField.selectionStart || myField.selectionStart == '0') {
442         var startPos = myField.selectionStart;
443         var endPos = myField.selectionEnd;
444         myField.value = myField.value.substring(0, startPos)
445             + myValue + myField.value.substring(endPos, myField.value.length);
446     } else {
447         myField.value += myValue;
448     }
453         Call instead of setting window.onload directly or setting body onload=.
454         Adds your function to a chain of functions rather than overwriting anything
455         that exists.
457 function addonload(fn) {
458     var oldhandler=window.onload;
459     window.onload=function() {
460         if(oldhandler) oldhandler();
461             fn();
462     }