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 function lockoptionsall(formid) {
87 var form = document.forms[formid];
88 var dependons = eval(formid+'items');
90 for (var dependon in dependons) {
91 // change for MooTools compatibility
92 if (!dependons.propertyIsEnumerable(dependon)) {
95 var master = form[dependon];
96 if (master === undefined) {
99 for (var condition in dependons[dependon]) {
100 for (var value in dependons[dependon][condition]) {
104 lock = !master.checked; break;
106 lock = master.checked; break;
107 case 'noitemselected':
108 lock = master.selectedIndex==-1; break;
110 lock = master.value==value; break;
112 lock = master.value!=value; break;
114 for (var ei in dependons[dependon][condition][value]) {
115 // change for MooTools compatibility
116 if (!window.webkit && (!dependons[dependon][condition][value].propertyIsEnumerable(ei))) {
119 var eltolock = dependons[dependon][condition][value][ei];
120 if (tolock[eltolock] != null){
122 lock || tolock[eltolock];
124 tolock[eltolock] = lock;
130 for (var el in tolock){
131 // change for MooTools compatibility
132 if (!tolock.propertyIsEnumerable(el)) {
135 var formelement = form[el];
136 if ((formelement === undefined) || (formelement.disabled === undefined)) {
139 formelement.disabled = tolock[el];
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)) {
152 var master = form[dependon];
153 if (master === undefined) {
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);};
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);};
170 return lockoptionsall(formid);
174 function submitFormById(id) {
175 var theform = document.getElementById(id);
179 if(theform.tagName.toLowerCase() != 'form') {
182 if(!theform.onsubmit || theform.onsubmit()) {
183 return theform.submit();
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';
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 = '';
207 function confirm_if(expr, message) {
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
223 function findParentNode(el, elName, elClass, elId) {
224 while(el.nodeName.toUpperCase() != 'BODY') {
226 (!elName || el.nodeName.toUpperCase() == elName) &&
227 (!elClass || el.className.indexOf(elClass) != -1) &&
228 (!elId || el.id == elId))
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){
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))
265 children = children.concat(child);
267 children = children.concat(findChildNodes(child, tagName, elementClass, elementID, elementName));
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'), '')
283 element.className += ' hide';
288 function showAdvancedOnClick(button, hidetext, showtext){
289 var toSet=findChildNodes(button.form, null, 'advanced');
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';
296 elementShowAdvanced(toSet, false);
297 buttontext = showtext;
298 button.form.elements['mform_showadvanced_last'].value = '0';
300 var formelements = button.form.elements;
302 for (var i = 0; i < formelements.length; i++){
303 if (formelements[i] && formelements[i].name && (formelements[i].name=='mform_showadvanced')){
304 formelements[i].value = buttontext;
307 //never submit the form if js is enabled.
311 function unmaskPassword(id) {
312 var pw = document.getElementById(id);
313 var chb = document.getElementById(id+'unmask');
316 // first try IE way - it can not set name attribute later
318 var newpw = document.createElement('<input type="text" name="'+pw.name+'">');
320 var newpw = document.createElement('<input type="password" name="'+pw.name+'">');
322 newpw.attributes['class'].nodeValue = pw.attributes['class'].nodeValue;
324 var newpw = document.createElement('input');
325 newpw.setAttribute('name', pw.name);
327 newpw.setAttribute('type', 'text');
329 newpw.setAttribute('type', 'password');
331 newpw.setAttribute('class', pw.getAttribute('class'));
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);
342 elementToggleHide (element, elementFinder)
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).
348 If persistent == true, also sets a cookie for this.
350 function elementToggleHide(el, persistent, elementFinder, strShow, strHide) {
352 var obj = el; //el:container
353 el = document.getElementById('togglehide_'+obj.id);
356 var obj = elementFinder(el); //el:button.
358 if(obj.className.indexOf('hidden') == -1) {
359 obj.className += ' hidden';
361 el.src = el.src.replace('switch_minus', 'switch_plus');
368 obj.className = obj.className.replace(new RegExp(' ?hidden'), '');
370 el.src = el.src.replace('switch_plus', 'switch_minus');
377 if(persistent == true) {
378 new cookie('hide:' + obj.id, 1, (shown ? -1 : 356), '/').set();
382 function elementCookieHide(id, strShow, strHide) {
383 var obj = document.getElementById(id);
384 var cook = new cookie('hide:' + id).read();
386 elementToggleHide(obj, false, null, strShow, strHide);
390 function filterByParent(elCollection, parentFinder) {
391 var filteredCollection = [];
392 for(var i = 0; i < elCollection.length; ++i) {
393 var findParent = parentFinder(elCollection[i]);
394 if(findParent.nodeName != 'BODY') {
395 filteredCollection.push(elCollection[i]);
398 return filteredCollection;
402 All this is here just so that IE gets to handle oversized blocks
403 in a visually pleasing manner. It does a browser detect. So sue me.
406 function fix_column_widths() {
407 var agt = navigator.userAgent.toLowerCase();
408 if ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1)) {
409 fix_column_width('left-column');
410 fix_column_width('right-column');
414 function fix_column_width(colName) {
415 if(column = document.getElementById(colName)) {
416 if(!column.offsetWidth) {
417 setTimeout("fix_column_width('" + colName + "')", 20);
422 var nodes = column.childNodes;
424 for(i = 0; i < nodes.length; ++i) {
425 if(nodes[i].className.indexOf("sideblock") != -1 ) {
426 if(width < nodes[i].offsetWidth) {
427 width = nodes[i].offsetWidth;
432 for(i = 0; i < nodes.length; ++i) {
433 if(nodes[i].className.indexOf("sideblock") != -1 ) {
434 nodes[i].style.width = width + 'px';
442 Insert myValue at current cursor position
444 function insertAtCursor(myField, myValue) {
446 if (document.selection) {
448 sel = document.selection.createRange();
451 // Mozilla/Netscape support
452 else if (myField.selectionStart || myField.selectionStart == '0') {
453 var startPos = myField.selectionStart;
454 var endPos = myField.selectionEnd;
455 myField.value = myField.value.substring(0, startPos)
456 + myValue + myField.value.substring(endPos, myField.value.length);
458 myField.value += myValue;
464 Call instead of setting window.onload directly or setting body onload=.
465 Adds your function to a chain of functions rather than overwriting anything
468 function addonload(fn) {
469 var oldhandler=window.onload;
470 window.onload=function() {
471 if(oldhandler) oldhandler();