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)
13 function popUpProperties(inobj) {
15 var op = window.open();
16 op.document.open('text/plain');
17 for (objprop in inobj) {
18 op.document.write(objprop + ' => ' + inobj[objprop] + '\n');
23 function fillmessagebox(text) {
25 document.form.message.value = text;
28 function copyrichtext(textname) {
29 /// Legacy stub for old editor - to be removed soon
35 var el
= document
.getElementsByTagName('input');
36 for(var i
=0; i
<el
.length
; i
++) {
37 if(el
[i
].type
== 'checkbox') {
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;
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
]);
64 for (i
=0; i
<subitems
.length
; i
++) {
65 lockoption(form
, subitems
[i
]);
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");
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");
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.
91 * @param form a HTML form.
92 * @param master the name of an element in that form.
93 * @return the value of that element.
95 function get_form_element_value(form
, name
) {
96 var element
= form
[name
];
100 if (element
.tagName
) {
101 // Ordinarly thing like a select box.
102 return element
.value
;
104 // Array of things, like radio buttons.
105 for (var j
= 0; j
< element
.length
; j
++) {
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.
125 function set_form_element_disabled(form
, name
, disabled
) {
126 var element
= form
[name
];
130 if (element
.tagName
) {
131 // Ordinarly thing like a select box.
132 element
.disabled
= disabled
;
134 // Array of things, like radio buttons.
135 for (var j
= 0; j
< element
.length
; j
++) {
137 el
.disabled
= disabled
;
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.
151 function set_form_element_hidden(form
, name
, hidden
) {
152 var element
= form
[name
];
156 if (element
.tagName
) {
157 var el
= findParentNode(element
, 'DIV', 'fitem', false);
159 el
.style
.display
= hidden
? 'none' : '';
160 el
.style
.visibility
= hidden
? 'hidden' : '';
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);
167 el
.style
.display
= hidden
? 'none' : '';
168 el
.style
.visibility
= hidden
? 'hidden' : '';
173 function lockoptionsall(formid
) {
174 var form
= document
.forms
[formid
];
175 var dependons
= eval(formid
+ 'items');
178 for (var dependon
in dependons
) {
179 // change for MooTools compatibility
180 if (!dependons
.propertyIsEnumerable(dependon
)) {
183 if (!form
[dependon
]) {
186 for (var condition
in dependons
[dependon
]) {
187 for (var value
in dependons
[dependon
][condition
]) {
192 lock
= !form
[dependon
].checked
; break;
194 lock
= form
[dependon
].checked
; break;
195 case 'noitemselected':
196 lock
= form
[dependon
].selectedIndex
== -1; break;
198 lock
= get_form_element_value(form
, dependon
) == value
; break;
200 // hide as well as disable
203 lock
= get_form_element_value(form
, dependon
) != value
; break;
205 for (var ei
in dependons
[dependon
][condition
][value
]) {
206 var eltolock
= dependons
[dependon
][condition
][value
][ei
];
208 tohide
[eltolock
] = true;
210 if (tolock
[eltolock
] != null) {
211 tolock
[eltolock
] = lock
|| tolock
[eltolock
];
213 tolock
[eltolock
] = lock
;
219 for (var el
in tolock
) {
220 // change for MooTools compatibility
221 if (!tolock
.propertyIsEnumerable(el
)) {
224 set_form_element_disabled(form
, el
, tolock
[el
]);
225 if (tohide
.propertyIsEnumerable(el
)) {
226 set_form_element_hidden(form
, el
, tolock
[el
]);
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
)) {
240 var masters
= form
[dependon
];
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.
249 for (var j
= 0; j
< masters
.length
; 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
);};
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
);};
266 return lockoptionsall(formid
);
270 function submitFormById(id
) {
271 var theform
= document
.getElementById(id
);
275 if(theform
.tagName
.toLowerCase() != 'form') {
278 if(!theform
.onsubmit
|| theform
.onsubmit()) {
279 return theform
.submit();
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';
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
= '';
303 function confirm_if(expr
, message
) {
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
319 function findParentNode(el
, elName
, elClass
, elId
) {
320 while(el
.nodeName
.toUpperCase() != 'BODY') {
322 (!elName
|| el
.nodeName
.toUpperCase() == elName
) &&
323 (!elClass
|| el
.className
.indexOf(elClass
) != -1) &&
324 (!elId
|| el
.id
== elId
))
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
) {
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
))
361 children
= children
.concat(child
);
363 children
= children
.concat(findChildNodes(child
, tagName
, elementClass
, elementID
, elementName
));
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'), '')
379 element
.className
+= ' hide';
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
= {
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');
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';
408 elementShowAdvanced(toSet
, false);
409 buttontext
= button
.moodle
.showLabel
;
410 button
.form
.elements
['mform_showadvanced_last'].value
= '0';
412 var formelements
= button
.form
.elements
;
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
;
419 //never submit the form if js is enabled.
423 function unmaskPassword(id
) {
424 var pw
= document
.getElementById(id
);
425 var chb
= document
.getElementById(id
+'unmask');
428 // first try IE way - it can not set name attribute later
430 var newpw
= document
.createElement('<input type="text" name="'+pw
.name
+'">');
432 var newpw
= document
.createElement('<input type="password" name="'+pw
.name
+'">');
434 newpw
.attributes
['class'].nodeValue
= pw
.attributes
['class'].nodeValue
;
436 var newpw
= document
.createElement('input');
437 newpw
.setAttribute('name', pw
.name
);
439 newpw
.setAttribute('type', 'text');
441 newpw
.setAttribute('type', 'password');
443 newpw
.setAttribute('class', pw
.getAttribute('class'));
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
) {
464 var obj
= el
; //el:container
465 el
= document
.getElementById('togglehide_'+obj
.id
);
468 var obj
= elementFinder(el
); //el:button.
470 if(obj
.className
.indexOf('hidden') == -1) {
471 obj
.className
+= ' hidden';
473 el
.src
= el
.src
.replace('switch_minus', 'switch_plus');
480 obj
.className
= obj
.className
.replace(new RegExp(' ?hidden'), '');
482 el
.src
= el
.src
.replace('switch_plus', 'switch_minus');
489 if(persistent
== true) {
490 new cookie('hide:' + obj
.id
, 1, (shown
? -1 : 356), '/').set();
494 function elementCookieHide(id
, strShow
, strHide
) {
495 var obj
= document
.getElementById(id
);
496 var cook
= new cookie('hide:' + id
).read();
498 elementToggleHide(obj
, false, null, strShow
, strHide
);
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
]);
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');
526 function fix_column_width(colName
) {
527 if(column
= document
.getElementById(colName
)) {
528 if(!column
.offsetWidth
) {
529 setTimeout("fix_column_width('" + colName
+ "')", 20);
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
;
544 for(i
= 0; i
< nodes
.length
; ++i
) {
545 if(nodes
[i
].className
.indexOf("sideblock") != -1 ) {
546 nodes
[i
].style
.width
= width
+ 'px';
554 Insert myValue at current cursor position
556 function insertAtCursor(myField
, myValue
) {
558 if (document
.selection
) {
560 sel
= document
.selection
.createRange();
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
);
570 myField
.value
+= myValue
;
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
580 function addonload(fn
) {
581 var oldhandler
=window
.onload
;
582 window
.onload=function() {
583 if(oldhandler
) oldhandler();