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;
301 for (var i in formelements){
302 if (formelements[i] && formelements[i].name && (formelements[i].name=='mform_showadvanced')){
303 formelements[i].value = buttontext;
306 //never submit the form if js is enabled.
310 function unmaskPassword(id) {
311 var pw = document.getElementById(id);
312 var chb = document.getElementById(id+'unmask');
315 // first try IE way - it can not set name attribute later
317 var newpw = document.createElement('<input type="text" name="'+pw.name+'">');
319 var newpw = document.createElement('<input type="password" name="'+pw.name+'">');
321 newpw.attributes['class'].nodeValue = pw.attributes['class'].nodeValue;
323 var newpw = document.createElement('input');
324 newpw.setAttribute('name', pw.name);
326 newpw.setAttribute('type', 'text');
328 newpw.setAttribute('type', 'password');
330 newpw.setAttribute('class', pw.getAttribute('class'));
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) {
354 var obj = elementFinder(el);
356 if(obj.className.indexOf('hidden') == -1) {
357 obj.className += ' hidden';
361 obj.className = obj.className.replace(new RegExp(' ?hidden'), '')
365 if(persistent == true) {
366 new cookie('hide:' + obj.id, 1, (shown ? -1 : 356), '/').set();
371 function elementCookieHide(id) {
372 var obj = document.getElementById(id);
373 var cook = new cookie('hide:' + id).read();
375 elementToggleHide(obj, false);
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]);
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');
403 function fix_column_width(colName) {
404 if(column = document.getElementById(colName)) {
405 if(!column.offsetWidth) {
406 setTimeout("fix_column_width('" + colName + "')", 20);
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;
421 for(i = 0; i < nodes.length; ++i) {
422 if(nodes[i].className.indexOf("sideblock") != -1 ) {
423 nodes[i].style.width = width + 'px';
431 Insert myValue at current cursor position
433 function insertAtCursor(myField, myValue) {
435 if (document.selection) {
437 sel = document.selection.createRange();
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);
447 myField.value += myValue;
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
457 function addonload(fn) {
458 var oldhandler=window.onload;
459 window.onload=function() {
460 if(oldhandler) oldhandler();