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 showAdvancedInit(addBefore, nameAttr, buttonLabel, hideText, showText) {
289 var showHideButton = document.createElement("input");
290 showHideButton.type = 'button';
291 showHideButton.value = buttonLabel;
292 showHideButton.name = nameAttr;
293 showHideButton.moodle = {
297 YAHOO.util.Event.addListener(showHideButton, 'click', showAdvancedOnClick);
298 el = document.getElementById(addBefore);
299 el.parentNode.insertBefore(showHideButton, el);
302 function showAdvancedOnClick(e) {
303 var button = e.target ? e.target : e.srcElement;
305 var toSet=findChildNodes(button.form, null, 'advanced');
307 if (button.form.elements['mform_showadvanced_last'].value == '0' || button.form.elements['mform_showadvanced_last'].value == '' ) {
308 elementShowAdvanced(toSet, true);
309 buttontext = button.moodle.hideLabel;
310 button.form.elements['mform_showadvanced_last'].value = '1';
312 elementShowAdvanced(toSet, false);
313 buttontext = button.moodle.showLabel;
314 button.form.elements['mform_showadvanced_last'].value = '0';
316 var formelements = button.form.elements;
318 for (var i = 0; i < formelements.length; i++){
319 if (formelements[i] && formelements[i].name && (formelements[i].name=='mform_showadvanced')){
320 formelements[i].value = buttontext;
323 //never submit the form if js is enabled.
327 function unmaskPassword(id) {
328 var pw = document.getElementById(id);
329 var chb = document.getElementById(id+'unmask');
332 // first try IE way - it can not set name attribute later
334 var newpw = document.createElement('<input type="text" name="'+pw.name+'">');
336 var newpw = document.createElement('<input type="password" name="'+pw.name+'">');
338 newpw.attributes['class'].nodeValue = pw.attributes['class'].nodeValue;
340 var newpw = document.createElement('input');
341 newpw.setAttribute('name', pw.name);
343 newpw.setAttribute('type', 'text');
345 newpw.setAttribute('type', 'password');
347 newpw.setAttribute('class', pw.getAttribute('class'));
350 newpw.size = pw.size;
351 newpw.onblur = pw.onblur;
352 newpw.onchange = pw.onchange;
353 newpw.value = pw.value;
354 pw.parentNode.replaceChild(newpw, pw);
358 elementToggleHide (element, elementFinder)
360 If elementFinder is not provided, toggles the "hidden" class for the specified element.
361 If elementFinder is provided, then the "hidden" class will be toggled for the object
362 returned by the function call elementFinder(element).
364 If persistent == true, also sets a cookie for this.
366 function elementToggleHide(el, persistent, elementFinder, strShow, strHide) {
368 var obj = el; //el:container
369 el = document.getElementById('togglehide_'+obj.id);
372 var obj = elementFinder(el); //el:button.
374 if(obj.className.indexOf('hidden') == -1) {
375 obj.className += ' hidden';
377 el.src = el.src.replace('switch_minus', 'switch_plus');
384 obj.className = obj.className.replace(new RegExp(' ?hidden'), '');
386 el.src = el.src.replace('switch_plus', 'switch_minus');
393 if(persistent == true) {
394 new cookie('hide:' + obj.id, 1, (shown ? -1 : 356), '/').set();
398 function elementCookieHide(id, strShow, strHide) {
399 var obj = document.getElementById(id);
400 var cook = new cookie('hide:' + id).read();
402 elementToggleHide(obj, false, null, strShow, strHide);
406 function filterByParent(elCollection, parentFinder) {
407 var filteredCollection = [];
408 for(var i = 0; i < elCollection.length; ++i) {
409 var findParent = parentFinder(elCollection[i]);
410 if(findParent.nodeName != 'BODY') {
411 filteredCollection.push(elCollection[i]);
414 return filteredCollection;
418 All this is here just so that IE gets to handle oversized blocks
419 in a visually pleasing manner. It does a browser detect. So sue me.
422 function fix_column_widths() {
423 var agt = navigator.userAgent.toLowerCase();
424 if ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1)) {
425 fix_column_width('left-column');
426 fix_column_width('right-column');
430 function fix_column_width(colName) {
431 if(column = document.getElementById(colName)) {
432 if(!column.offsetWidth) {
433 setTimeout("fix_column_width('" + colName + "')", 20);
438 var nodes = column.childNodes;
440 for(i = 0; i < nodes.length; ++i) {
441 if(nodes[i].className.indexOf("sideblock") != -1 ) {
442 if(width < nodes[i].offsetWidth) {
443 width = nodes[i].offsetWidth;
448 for(i = 0; i < nodes.length; ++i) {
449 if(nodes[i].className.indexOf("sideblock") != -1 ) {
450 nodes[i].style.width = width + 'px';
458 Insert myValue at current cursor position
460 function insertAtCursor(myField, myValue) {
462 if (document.selection) {
464 sel = document.selection.createRange();
467 // Mozilla/Netscape support
468 else if (myField.selectionStart || myField.selectionStart == '0') {
469 var startPos = myField.selectionStart;
470 var endPos = myField.selectionEnd;
471 myField.value = myField.value.substring(0, startPos)
472 + myValue + myField.value.substring(endPos, myField.value.length);
474 myField.value += myValue;
480 Call instead of setting window.onload directly or setting body onload=.
481 Adds your function to a chain of functions rather than overwriting anything
484 function addonload(fn) {
485 var oldhandler=window.onload;
486 window.onload=function() {
487 if(oldhandler) oldhandler();