Fixing authdb->close() in some places. Credir goes to Seiti. MDL-9212
[moodle.git] / lib / javascript-static.js
CommitLineData
47aa42e2 1// Miscellaneous core Javascript functions for Moodle
2
b48fd7b5 3function 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();
9 }
10}
11
d2ce367f 12/*
63d28811 13function popUpProperties(inobj) {
d2ce367f 14/// Legacy function
15 var op = window.open();
63d28811 16 op.document.open('text/plain');
17 for (objprop in inobj) {
18 op.document.write(objprop + ' => ' + inobj[objprop] + '\n');
19 }
20 op.document.close();
21}
22
23function fillmessagebox(text) {
d2ce367f 24/// Legacy function
63d28811 25 document.form.message.value = text;
26}
27
28function copyrichtext(textname) {
29/// Legacy stub for old editor - to be removed soon
30 return true;
31}
d2ce367f 32*/
63d28811 33
34function checkall() {
d2ce367f 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;
39 }
40 }
63d28811 41}
42
03f9425f 43function checknone() {
d2ce367f 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;
48 }
49 }
03f9425f 50}
51
d2ce367f 52function lockoptions(formid, master, subitems) {
027d0485 53 // Subitems is an array of names of sub items.
54 // Optionally, each item in subitems may have a
63d28811 55 // companion hidden item in the form with the
027d0485 56 // same name but prefixed by "h".
d2ce367f 57 var form = document.forms[formid];
58
59 if (eval("form."+master+".checked")) {
63d28811 60 for (i=0; i<subitems.length; i++) {
61 unlockoption(form, subitems[i]);
62 }
63 } else {
64 for (i=0; i<subitems.length; i++) {
65 lockoption(form, subitems[i]);
66 }
67 }
68 return(true);
69}
70
f07b9627 71function lockoption(form,item) {
d2ce367f 72 eval("form."+item+".disabled=true");/* IE thing */
73 if(form.elements['h'+item]) {
74 eval("form.h"+item+".value=1");
f07b9627 75 }
76}
77
78function unlockoption(form,item) {
d2ce367f 79 eval("form."+item+".disabled=false");/* IE thing */
80 if(form.elements['h'+item]) {
81 eval("form.h"+item+".value=0");
f07b9627 82 }
83}
dd07bbac 84
85
50ef8eb9 86function lockoptionsall(formid) {
dd07bbac 87 var form = document.forms[formid];
88 var dependons = eval(formid+'items');
89 for (var dependon in dependons) {
90 var master = form[dependon];
91 for (var condition in dependons[dependon]) {
92 for (var value in dependons[dependon][condition]) {
93 var lock;
94 switch (condition) {
95 case 'notchecked':
96 lock = !master.checked; break;
97 case 'checked':
98 lock = master.checked; break;
99 case 'noitemselected':
100 lock = master.selectedIndex==-1; break;
101 case 'eq':
102 lock = master.value==value; break;
103 default:
104 lock = master.value!=value; break;
105 }
106 for (var ei in dependons[dependon][condition][value]) {
107 var formelement = form[dependons[dependon][condition][value][ei]];
108 formelement.disabled = lock;
109 }
110 }
50ef8eb9 111 }
dd07bbac 112 }
113 return true;
50ef8eb9 114}
115
d01a38cb 116function lockoptionsallsetup(formid) {
dd07bbac 117 var form = document.forms[formid];
118 var dependons = eval(formid+'items');
119 for (var dependon in dependons) {
120 var master = form[dependon];
121 master.onclick = function() {return lockoptionsall(this.form.getAttribute('id'));};
122 master.onblur = function() {return lockoptionsall(this.form.getAttribute('id'));};
123 master.onchange = function() {return lockoptionsall(this.form.getAttribute('id'));};
124 }
125 for (var i = 0; i < form.elements.length; i++){
126 var formelement = form.elements[i];
127 if (formelement.type=='reset') {
128 formelement.onclick = function() {this.form.reset();return lockoptionsall(this.form.getAttribute('id'));};
129 formelement.onblur = function() {this.form.reset();return lockoptionsall(this.form.getAttribute('id'));};
130 formelement.onchange = function() {this.form.reset();return lockoptionsall(this.form.getAttribute('id'));};
131 }
132 }
133 return lockoptionsall(formid);
d01a38cb 134}
50ef8eb9 135
7678e65c 136
137function submitFormById(id) {
138 var theform = document.getElementById(id);
139 if(!theform) {
140 return false;
141 }
bb006c95 142 if(theform.tagName.toLowerCase() != 'form') {
7678e65c 143 return false;
144 }
145 if(!theform.onsubmit || theform.onsubmit()) {
146 return theform.submit();
147 }
148}
363cb62c 149
8ceb09e0 150function select_all_in(elTagName, elClass, elId) {
d2ce367f 151 var inputs = document.getElementsByTagName('input');
8ceb09e0 152 inputs = filterByParent(inputs, function(el) {return findParentNode(el, elTagName, elClass, elId);});
363cb62c 153 for(var i = 0; i < inputs.length; ++i) {
bee40515 154 if(inputs[i].type == 'checkbox' || inputs[i].type == 'radio') {
363cb62c 155 inputs[i].checked = 'checked';
156 }
157 }
158}
159
8ceb09e0 160function deselect_all_in(elTagName, elClass, elId) {
363cb62c 161 var inputs = document.getElementsByTagName('INPUT');
8ceb09e0 162 inputs = filterByParent(inputs, function(el) {return findParentNode(el, elTagName, elClass, elId);});
363cb62c 163 for(var i = 0; i < inputs.length; ++i) {
bee40515 164 if(inputs[i].type == 'checkbox' || inputs[i].type == 'radio') {
363cb62c 165 inputs[i].checked = '';
166 }
167 }
168}
169
170function confirm_if(expr, message) {
171 if(!expr) {
172 return true;
173 }
174 return confirm(message);
175}
47aa42e2 176
177
178/*
179 findParentNode (start, elementName, elementClass, elementID)
50ef8eb9 180
47aa42e2 181 Travels up the DOM hierarchy to find a parent element with the
182 specified tag name, class, and id. All conditions must be met,
183 but any can be ommitted. Returns the BODY element if no match
184 found.
185*/
186function findParentNode(el, elName, elClass, elId) {
ef4d42fd 187 while(el.nodeName.toUpperCase() != 'BODY') {
47aa42e2 188 if(
ef4d42fd 189 (!elName || el.nodeName.toUpperCase() == elName) &&
47aa42e2 190 (!elClass || el.className.indexOf(elClass) != -1) &&
191 (!elId || el.id == elId))
192 {
193 break;
194 }
195 el = el.parentNode;
196 }
197 return el;
198}
19194f82 199/*
200 findChildNode (start, elementName, elementClass, elementID)
201
202 Travels down the DOM hierarchy to find all child elements with the
203 specified tag name, class, and id. All conditions must be met,
204 but any can be ommitted.
a23f0aaf 205 Doesn't examine children of matches.
19194f82 206*/
207function findChildNodes(start, tagName, elementClass, elementID, elementName) {
208 var children = new Array();
83c9a8a2 209 for (var i = 0; i < start.childNodes.length; i++) {
a23f0aaf 210 var classfound = false;
83c9a8a2 211 var child = start.childNodes[i];
a23f0aaf 212 if((child.nodeType == 1) &&//element node type
213 (elementClass && (typeof(child.className)=='string'))){
214 var childClasses = child.className.split(/\s+/);
215 for (var childClassIndex in childClasses){
216 if (childClasses[childClassIndex]==elementClass){
217 classfound = true;
218 break;
219 }
220 }
221 }
f07b9627 222 if(child.nodeType == 1) { //element node type
223 if ( (!tagName || child.nodeName == tagName) &&
224 (!elementClass || classfound)&&
225 (!elementID || child.id == elementID) &&
226 (!elementName || child.name == elementName))
227 {
228 children = children.concat(child);
229 } else {
230 children = children.concat(findChildNodes(child, tagName, elementClass, elementID, elementName));
231 }
19194f82 232 }
19194f82 233 }
234 return children;
235}
236/*
237 elementSetHide (elements, hide)
238
239 Adds or removes the "hide" class for the specified elements depending on boolean hide.
240*/
241function elementShowAdvanced(elements, show) {
242 for (var elementIndex in elements){
243 element = elements[elementIndex];
244 element.className = element.className.replace(new RegExp(' ?hide'), '')
245 if(!show) {
246 element.className += ' hide';
247 }
248 }
249}
250
251function showAdvancedOnClick(button, hidetext, showtext){
252 var toSet=findChildNodes(button.form, null, 'advanced');
253 var buttontext = '';
74d15d35 254 if (button.form.elements['mform_showadvanced_last'].value == '0' || button.form.elements['mform_showadvanced_last'].value == '' ) {
19194f82 255 elementShowAdvanced(toSet, true);
256 buttontext = hidetext;
257 button.form.elements['mform_showadvanced_last'].value = '1';
258 } else {
259 elementShowAdvanced(toSet, false);
260 buttontext = showtext;
261 button.form.elements['mform_showadvanced_last'].value = '0';
262 }
263 var formelements = button.form.elements;
264 for (var i in formelements){
9bf930bd 265 if (formelements[i] && formelements[i].name && (formelements[i].name=='mform_showadvanced')){
19194f82 266 formelements[i].value = buttontext;
267 }
268 }
269 //never submit the form if js is enabled.
270 return false;
271}
47aa42e2 272
273/*
274 elementToggleHide (element, elementFinder)
275
276 If elementFinder is not provided, toggles the "hidden" class for the specified element.
277 If elementFinder is provided, then the "hidden" class will be toggled for the object
278 returned by the function call elementFinder(element).
279
280 If persistent == true, also sets a cookie for this.
281*/
19194f82 282function elementToggleHide(el, persistent, elementFinder) {
47aa42e2 283 if(!elementFinder) {
284 var obj = el;
285 }
286 else {
287 var obj = elementFinder(el);
288 }
289 if(obj.className.indexOf('hidden') == -1) {
290 obj.className += ' hidden';
19194f82 291 var shown = 0;
47aa42e2 292 }
293 else {
19194f82 294 obj.className = obj.className.replace(new RegExp(' ?hidden'), '')
295 var shown = 1;
47aa42e2 296 }
19194f82 297
47aa42e2 298 if(persistent == true) {
299 new cookie('hide:' + obj.id, 1, (shown ? -1 : 356), '/').set();
300 }
301}
302
303
304function elementCookieHide(id) {
305 var obj = document.getElementById(id);
306 var cook = new cookie('hide:' + id).read();
307 if(cook != null) {
308 elementToggleHide(obj, false);
309 }
310}
311
312function filterByParent(elCollection, parentFinder) {
313 var filteredCollection = [];
314 for(var i = 0; i < elCollection.length; ++i) {
315 var findParent = parentFinder(elCollection[i]);
316 if(findParent.nodeName != 'BODY') {
317 filteredCollection.push(elCollection[i]);
318 }
319 }
320 return filteredCollection;
321}
322
7979105c 323/*
324 All this is here just so that IE gets to handle oversized blocks
325 in a visually pleasing manner. It does a browser detect. So sue me.
326*/
327
328function fix_column_widths() {
329 var agt = navigator.userAgent.toLowerCase();
330 if ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1)) {
331 fix_column_width('left-column');
332 fix_column_width('right-column');
333 }
334}
335
336function fix_column_width(colName) {
337 if(column = document.getElementById(colName)) {
338 if(!column.offsetWidth) {
339 setTimeout("fix_column_width('" + colName + "')", 20);
340 return;
341 }
342
343 var width = 0;
344 var nodes = column.childNodes;
345
346 for(i = 0; i < nodes.length; ++i) {
347 if(nodes[i].className.indexOf("sideblock") != -1 ) {
348 if(width < nodes[i].offsetWidth) {
349 width = nodes[i].offsetWidth;
350 }
351 }
352 }
353
354 for(i = 0; i < nodes.length; ++i) {
355 if(nodes[i].className.indexOf("sideblock") != -1 ) {
356 nodes[i].style.width = width + 'px';
357 }
358 }
359 }
360}
d13c5938 361
362
363/*
364 Insert myValue at current cursor position
365*/
366function insertAtCursor(myField, myValue) {
367 // IE support
368 if (document.selection) {
369 myField.focus();
370 sel = document.selection.createRange();
371 sel.text = myValue;
372 }
373 // Mozilla/Netscape support
374 else if (myField.selectionStart || myField.selectionStart == '0') {
375 var startPos = myField.selectionStart;
376 var endPos = myField.selectionEnd;
377 myField.value = myField.value.substring(0, startPos)
378 + myValue + myField.value.substring(endPos, myField.value.length);
379 } else {
380 myField.value += myValue;
381 }
382}