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 var master = form[dependon];
92 if (master == undefined) {
95 for (var condition in dependons[dependon]) {
96 for (var value in dependons[dependon][condition]) {
100 lock = !master.checked; break;
102 lock = master.checked; break;
103 case 'noitemselected':
104 lock = master.selectedIndex==-1; break;
106 lock = master.value==value; break;
108 lock = master.value!=value; break;
110 for (var ei in dependons[dependon][condition][value]) {
111 var eltolock = dependons[dependon][condition][value][ei];
112 if (tolock[eltolock] != null){
114 lock || tolock[eltolock];
116 tolock[eltolock] = lock;
122 for (var el in tolock){
123 var formelement = form[el];
124 if (formelement == undefined) {
127 formelement.disabled = tolock[el];
132 function lockoptionsallsetup(formid) {
133 var form = document.forms[formid];
134 var dependons = eval(formid+'items');
135 for (var dependon in dependons) {
136 var master = form[dependon];
137 if (master == undefined) {
140 master.formid = formid;
141 master.onclick = function() {return lockoptionsall(this.formid);};
142 master.onblur = function() {return lockoptionsall(this.formid);};
143 master.onchange = function() {return lockoptionsall(this.formid);};
145 for (var i = 0; i < form.elements.length; i++){
146 var formelement = form.elements[i];
147 if (formelement.type=='reset') {
148 formelement.formid = formid;
149 formelement.onclick = function() {this.form.reset();return lockoptionsall(this.formid);};
150 formelement.onblur = function() {this.form.reset();return lockoptionsall(this.formid);};
151 formelement.onchange = function() {this.form.reset();return lockoptionsall(this.formid);};
154 return lockoptionsall(formid);
158 function submitFormById(id) {
159 var theform = document.getElementById(id);
163 if(theform.tagName.toLowerCase() != 'form') {
166 if(!theform.onsubmit || theform.onsubmit()) {
167 return theform.submit();
171 function select_all_in(elTagName, elClass, elId) {
172 var inputs = document.getElementsByTagName('input');
173 inputs = filterByParent(inputs, function(el) {return findParentNode(el, elTagName, elClass, elId);});
174 for(var i = 0; i < inputs.length; ++i) {
175 if(inputs[i].type == 'checkbox' || inputs[i].type == 'radio') {
176 inputs[i].checked = 'checked';
181 function deselect_all_in(elTagName, elClass, elId) {
182 var inputs = document.getElementsByTagName('INPUT');
183 inputs = filterByParent(inputs, function(el) {return findParentNode(el, elTagName, elClass, elId);});
184 for(var i = 0; i < inputs.length; ++i) {
185 if(inputs[i].type == 'checkbox' || inputs[i].type == 'radio') {
186 inputs[i].checked = '';
191 function confirm_if(expr, message) {
195 return confirm(message);
200 findParentNode (start, elementName, elementClass, elementID)
202 Travels up the DOM hierarchy to find a parent element with the
203 specified tag name, class, and id. All conditions must be met,
204 but any can be ommitted. Returns the BODY element if no match
207 function findParentNode(el, elName, elClass, elId) {
208 while(el.nodeName.toUpperCase() != 'BODY') {
210 (!elName || el.nodeName.toUpperCase() == elName) &&
211 (!elClass || el.className.indexOf(elClass) != -1) &&
212 (!elId || el.id == elId))
221 findChildNode (start, elementName, elementClass, elementID)
223 Travels down the DOM hierarchy to find all child elements with the
224 specified tag name, class, and id. All conditions must be met,
225 but any can be ommitted.
226 Doesn't examine children of matches.
228 function findChildNodes(start, tagName, elementClass, elementID, elementName) {
229 var children = new Array();
230 for (var i = 0; i < start.childNodes.length; i++) {
231 var classfound = false;
232 var child = start.childNodes[i];
233 if((child.nodeType == 1) &&//element node type
234 (elementClass && (typeof(child.className)=='string'))){
235 var childClasses = child.className.split(/\s+/);
236 for (var childClassIndex in childClasses){
237 if (childClasses[childClassIndex]==elementClass){
243 if(child.nodeType == 1) { //element node type
244 if ( (!tagName || child.nodeName == tagName) &&
245 (!elementClass || classfound)&&
246 (!elementID || child.id == elementID) &&
247 (!elementName || child.name == elementName))
249 children = children.concat(child);
251 children = children.concat(findChildNodes(child, tagName, elementClass, elementID, elementName));
258 elementSetHide (elements, hide)
260 Adds or removes the "hide" class for the specified elements depending on boolean hide.
262 function elementShowAdvanced(elements, show) {
263 for (var elementIndex in elements){
264 element = elements[elementIndex];
265 element.className = element.className.replace(new RegExp(' ?hide'), '')
267 element.className += ' hide';
272 function showAdvancedOnClick(button, hidetext, showtext){
273 var toSet=findChildNodes(button.form, null, 'advanced');
275 if (button.form.elements['mform_showadvanced_last'].value == '0' || button.form.elements['mform_showadvanced_last'].value == '' ) {
276 elementShowAdvanced(toSet, true);
277 buttontext = hidetext;
278 button.form.elements['mform_showadvanced_last'].value = '1';
280 elementShowAdvanced(toSet, false);
281 buttontext = showtext;
282 button.form.elements['mform_showadvanced_last'].value = '0';
284 var formelements = button.form.elements;
285 for (var i in formelements){
286 if (formelements[i] && formelements[i].name && (formelements[i].name=='mform_showadvanced')){
287 formelements[i].value = buttontext;
290 //never submit the form if js is enabled.
294 function unmaskPassword(id) {
295 var pw = document.getElementById(id);
296 var chb = document.getElementById(id+'unmask');
299 // first try IE way - it can not set name attribute later
301 var newpw = document.createElement('<input type="text" name="'+pw.name+'">');
303 var newpw = document.createElement('<input type="password" name="'+pw.name+'">');
305 newpw.attributes['class'].nodeValue = pw.attributes['class'].nodeValue;
307 var newpw = document.createElement('input');
308 newpw.setAttribute('name', pw.name);
310 newpw.setAttribute('type', 'text');
312 newpw.setAttribute('type', 'password');
314 newpw.setAttribute('class', pw.getAttribute('class'));
317 newpw.size = pw.size;
318 newpw.onblur = pw.onblur;
319 newpw.onchange = pw.onchange;
320 newpw.value = pw.value;
321 pw.parentNode.replaceChild(newpw, pw);
325 elementToggleHide (element, elementFinder)
327 If elementFinder is not provided, toggles the "hidden" class for the specified element.
328 If elementFinder is provided, then the "hidden" class will be toggled for the object
329 returned by the function call elementFinder(element).
331 If persistent == true, also sets a cookie for this.
333 function elementToggleHide(el, persistent, elementFinder) {
338 var obj = elementFinder(el);
340 if(obj.className.indexOf('hidden') == -1) {
341 obj.className += ' hidden';
345 obj.className = obj.className.replace(new RegExp(' ?hidden'), '')
349 if(persistent == true) {
350 new cookie('hide:' + obj.id, 1, (shown ? -1 : 356), '/').set();
355 function elementCookieHide(id) {
356 var obj = document.getElementById(id);
357 var cook = new cookie('hide:' + id).read();
359 elementToggleHide(obj, false);
363 function filterByParent(elCollection, parentFinder) {
364 var filteredCollection = [];
365 for(var i = 0; i < elCollection.length; ++i) {
366 var findParent = parentFinder(elCollection[i]);
367 if(findParent.nodeName != 'BODY') {
368 filteredCollection.push(elCollection[i]);
371 return filteredCollection;
375 All this is here just so that IE gets to handle oversized blocks
376 in a visually pleasing manner. It does a browser detect. So sue me.
379 function fix_column_widths() {
380 var agt = navigator.userAgent.toLowerCase();
381 if ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1)) {
382 fix_column_width('left-column');
383 fix_column_width('right-column');
387 function fix_column_width(colName) {
388 if(column = document.getElementById(colName)) {
389 if(!column.offsetWidth) {
390 setTimeout("fix_column_width('" + colName + "')", 20);
395 var nodes = column.childNodes;
397 for(i = 0; i < nodes.length; ++i) {
398 if(nodes[i].className.indexOf("sideblock") != -1 ) {
399 if(width < nodes[i].offsetWidth) {
400 width = nodes[i].offsetWidth;
405 for(i = 0; i < nodes.length; ++i) {
406 if(nodes[i].className.indexOf("sideblock") != -1 ) {
407 nodes[i].style.width = width + 'px';
415 Insert myValue at current cursor position
417 function insertAtCursor(myField, myValue) {
419 if (document.selection) {
421 sel = document.selection.createRange();
424 // Mozilla/Netscape support
425 else if (myField.selectionStart || myField.selectionStart == '0') {
426 var startPos = myField.selectionStart;
427 var endPos = myField.selectionEnd;
428 myField.value = myField.value.substring(0, startPos)
429 + myValue + myField.value.substring(endPos, myField.value.length);
431 myField.value += myValue;
437 Call instead of setting window.onload directly or setting body onload=.
438 Adds your function to a chain of functions rather than overwriting anything
441 function addonload(fn) {
442 var oldhandler=window.onload;
443 window.onload=function() {
444 if(oldhandler) oldhandler();