timeline: if a section is set to hidden and the user is not capable of editing a...
[moodle-blog-course-format.git] / lib / javascript-static.js
blob584186406fc4ecc7ec83c93ebae802f4d9354531
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)
6 {alert(msg);}
7 else {
8 testwindow.close();
13 function popUpProperties(inobj) {
14 /// Legacy function
15 var op = window.open();
16 op.document.open('text/plain');
17 for (objprop in inobj) {
18 op.document.write(objprop + ' => ' + inobj[objprop] + '\n');
20 op.document.close();
23 function fillmessagebox(text) {
24 /// Legacy function
25 document.form.message.value = text;
28 function copyrichtext(textname) {
29 /// Legacy stub for old editor - to be removed soon
30 return true;
34 function checkall() {
35 var el = document.getElementsByTagName('input');
36 for(var i=0; i<el.length; i++) {
37 if(el[i].type == 'checkbox') {
38 el[i].checked = true;
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]);
63 } else {
64 for (i=0; i<subitems.length; i++) {
65 lockoption(form, subitems[i]);
68 return(true);
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");
85 /**
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];
97 if (!element) {
98 return null;
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++) {
106 var el = element[j];
107 if (el.checked) {
108 return el.value;
111 return null;
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];
127 if (!element) {
128 return;
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++) {
136 var el = element[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];
153 if (!element) {
154 return;
156 if (element.tagName) {
157 var el = findParentNode(element, 'DIV', 'fitem', false);
158 if (el!=null) {
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);
166 if (el!=null) {
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');
176 var tolock = [];
177 var tohide = [];
178 for (var dependon in dependons) {
179 // change for MooTools compatibility
180 if (!dependons.propertyIsEnumerable(dependon)) {
181 continue;
183 if (!form[dependon]) {
184 continue;
186 for (var condition in dependons[dependon]) {
187 for (var value in dependons[dependon][condition]) {
188 var lock;
189 var hide = false;
190 switch (condition) {
191 case 'notchecked':
192 lock = !form[dependon].checked; break;
193 case 'checked':
194 lock = form[dependon].checked; break;
195 case 'noitemselected':
196 lock = form[dependon].selectedIndex == -1; break;
197 case 'eq':
198 lock = get_form_element_value(form, dependon) == value; break;
199 case 'hide':
200 // hide as well as disable
201 hide = true; break;
202 default:
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];
207 if (hide) {
208 tohide[eltolock] = true;
210 if (tolock[eltolock] != null) {
211 tolock[eltolock] = lock || tolock[eltolock];
212 } else {
213 tolock[eltolock] = lock;
219 for (var el in tolock) {
220 // change for MooTools compatibility
221 if (!tolock.propertyIsEnumerable(el)) {
222 continue;
224 set_form_element_disabled(form, el, tolock[el]);
225 if (tohide.propertyIsEnumerable(el)) {
226 set_form_element_hidden(form, el, tolock[el]);
229 return true;
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)) {
238 continue;
240 var masters = form[dependon];
241 if (!masters) {
242 continue;
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.
247 masters = [masters];
249 for (var j = 0; j < masters.length; j++) {
250 master = masters[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);
272 if(!theform) {
273 return false;
275 if(theform.tagName.toLowerCase() != 'form') {
276 return false;
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) {
304 if(!expr) {
305 return true;
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
317 found.
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))
326 break;
328 el = el.parentNode;
330 return el;
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) {
350 classfound = true;
351 break;
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);
362 } else {
363 children = children.concat(findChildNodes(child, tagName, elementClass, elementID, elementName));
367 return children;
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'), '')
378 if(!show) {
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 = {
390 hideLabel: hideText,
391 showLabel: showText
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');
402 var buttontext = '';
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';
407 } else {
408 elementShowAdvanced(toSet, false);
409 buttontext = button.moodle.showLabel;
410 button.form.elements['mform_showadvanced_last'].value = '0';
412 var formelements = button.form.elements;
413 // Fixed MDL-10506
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.
420 return false;
423 function unmaskPassword(id) {
424 var pw = document.getElementById(id);
425 var chb = document.getElementById(id+'unmask');
427 try {
428 // first try IE way - it can not set name attribute later
429 if (chb.checked) {
430 var newpw = document.createElement('<input type="text" name="'+pw.name+'">');
431 } else {
432 var newpw = document.createElement('<input type="password" name="'+pw.name+'">');
434 newpw.attributes['class'].nodeValue = pw.attributes['class'].nodeValue;
435 } catch (e) {
436 var newpw = document.createElement('input');
437 newpw.setAttribute('name', pw.name);
438 if (chb.checked) {
439 newpw.setAttribute('type', 'text');
440 } else {
441 newpw.setAttribute('type', 'password');
443 newpw.setAttribute('class', pw.getAttribute('class'));
445 newpw.id = pw.id;
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) {
463 if(!elementFinder) {
464 var obj = el; //el:container
465 el = document.getElementById('togglehide_'+obj.id);
467 else {
468 var obj = elementFinder(el); //el:button.
470 if(obj.className.indexOf('hidden') == -1) {
471 obj.className += ' hidden';
472 if (el.src) {
473 el.src = el.src.replace('switch_minus', 'switch_plus');
474 el.alt = strShow;
475 el.title = strShow;
477 var shown = 0;
479 else {
480 obj.className = obj.className.replace(new RegExp(' ?hidden'), '');
481 if (el.src) {
482 el.src = el.src.replace('switch_plus', 'switch_minus');
483 el.alt = strHide;
484 el.title = strHide;
486 var shown = 1;
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();
497 if(cook != null) {
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);
530 return;
533 var width = 0;
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) {
557 // IE support
558 if (document.selection) {
559 myField.focus();
560 sel = document.selection.createRange();
561 sel.text = myValue;
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);
569 } else {
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
578 that exists.
580 function addonload(fn) {
581 var oldhandler=window.onload;
582 window.onload=function() {
583 if(oldhandler) oldhandler();
584 fn();