Changes to the redirects.
[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}
50ef8eb9 84function lockoptionsall(formid) {
f07b9627 85 var lock = new Object();
271ffe3f 86 var items = eval(formid+'items');
f07b9627 87 var form = document.forms[formid];
50ef8eb9 88 for (var master in items){
89 var subitems=items[master].dependents;
90 var thislock;
9c03bbaa 91 if (items[master].condition=='notchecked'){
50ef8eb9 92 thislock=!form.elements[master].checked;
9c03bbaa 93 } else if (items[master].condition=='checked'){
94 thislock=form.elements[master].checked;
a23f0aaf 95 } else if (items[master].condition=='noitemselected'){
96 thislock=(form.elements[master].selectedIndex==-1);
e24b7f85 97 } else if (items[master].condition=='eq'){
98 thislock=(form.elements[master].value==items[master].value);
9c03bbaa 99 } else {
e24b7f85 100 thislock=(form.elements[master].value!=items[master].value);
101
50ef8eb9 102 }
103
104 for (var i=0; i<subitems.length; i++) {
105 if (lock[subitems[i]]!=null){
106 lock[subitems[i]] = thislock || lock[subitems[i]];
107 }else{
108 lock[subitems[i]] = thislock;
109 }
110 }
111
112 for (var item in lock) {
113 form.elements[item].disabled=lock[item];
114 }
115 }
116 return(true);
117}
118
d01a38cb 119function lockoptionsallsetup(formid) {
f07b9627 120 var varname = formid.replace(/\-/g, '_');
121 var items=eval(varname+'items');
d01a38cb 122 var form=document.forms[formid];
19110c57 123 for (var i = 0; i < form.elements.length; i++){
124 var found=false;
125 var formelement = form.elements[i];
126 if (formelement.type=='reset'){
127 formelement.onclick = function(){this.form.reset();return lockoptionsall(this.form.getAttribute('id'));};
128 formelement.onblur = function(){this.form.reset();return lockoptionsall(this.form.getAttribute('id'));};
129 formelement.onchange = function(){this.form.reset();return lockoptionsall(this.form.getAttribute('id'));};
130 } else {
131 for (var master in items){
132 if (master==formelement.name){
133 formelement.onclick = function(){return lockoptionsall(this.form.getAttribute('id'));};
134 formelement.onblur = function(){return lockoptionsall(this.form.getAttribute('id'));};
135 formelement.onchange = function(){return lockoptionsall(this.form.getAttribute('id'));};
136 break;
137 }
138 }
139 }
d01a38cb 140 }
19110c57 141
d01a38cb 142 return lockoptionsall(formid);
143}
50ef8eb9 144
7678e65c 145
146function submitFormById(id) {
147 var theform = document.getElementById(id);
148 if(!theform) {
149 return false;
150 }
d2ce367f 151 if(theform.tagName != 'form') {
7678e65c 152 return false;
153 }
154 if(!theform.onsubmit || theform.onsubmit()) {
155 return theform.submit();
156 }
157}
363cb62c 158
8ceb09e0 159function select_all_in(elTagName, elClass, elId) {
d2ce367f 160 var inputs = document.getElementsByTagName('input');
8ceb09e0 161 inputs = filterByParent(inputs, function(el) {return findParentNode(el, elTagName, elClass, elId);});
363cb62c 162 for(var i = 0; i < inputs.length; ++i) {
bee40515 163 if(inputs[i].type == 'checkbox' || inputs[i].type == 'radio') {
363cb62c 164 inputs[i].checked = 'checked';
165 }
166 }
167}
168
8ceb09e0 169function deselect_all_in(elTagName, elClass, elId) {
363cb62c 170 var inputs = document.getElementsByTagName('INPUT');
8ceb09e0 171 inputs = filterByParent(inputs, function(el) {return findParentNode(el, elTagName, elClass, elId);});
363cb62c 172 for(var i = 0; i < inputs.length; ++i) {
bee40515 173 if(inputs[i].type == 'checkbox' || inputs[i].type == 'radio') {
363cb62c 174 inputs[i].checked = '';
175 }
176 }
177}
178
179function confirm_if(expr, message) {
180 if(!expr) {
181 return true;
182 }
183 return confirm(message);
184}
47aa42e2 185
186
187/*
188 findParentNode (start, elementName, elementClass, elementID)
50ef8eb9 189
47aa42e2 190 Travels up the DOM hierarchy to find a parent element with the
191 specified tag name, class, and id. All conditions must be met,
192 but any can be ommitted. Returns the BODY element if no match
193 found.
194*/
195function findParentNode(el, elName, elClass, elId) {
196 while(el.nodeName != 'BODY') {
197 if(
198 (!elName || el.nodeName == elName) &&
199 (!elClass || el.className.indexOf(elClass) != -1) &&
200 (!elId || el.id == elId))
201 {
202 break;
203 }
204 el = el.parentNode;
205 }
206 return el;
207}
19194f82 208/*
209 findChildNode (start, elementName, elementClass, elementID)
210
211 Travels down the DOM hierarchy to find all child elements with the
212 specified tag name, class, and id. All conditions must be met,
213 but any can be ommitted.
a23f0aaf 214 Doesn't examine children of matches.
19194f82 215*/
216function findChildNodes(start, tagName, elementClass, elementID, elementName) {
217 var children = new Array();
218 for (var childIndex in start.childNodes) {
a23f0aaf 219 var classfound = false;
19194f82 220 var child = start.childNodes[childIndex];
a23f0aaf 221 if((child.nodeType == 1) &&//element node type
222 (elementClass && (typeof(child.className)=='string'))){
223 var childClasses = child.className.split(/\s+/);
224 for (var childClassIndex in childClasses){
225 if (childClasses[childClassIndex]==elementClass){
226 classfound = true;
227 break;
228 }
229 }
230 }
f07b9627 231 if(child.nodeType == 1) { //element node type
232 if ( (!tagName || child.nodeName == tagName) &&
233 (!elementClass || classfound)&&
234 (!elementID || child.id == elementID) &&
235 (!elementName || child.name == elementName))
236 {
237 children = children.concat(child);
238 } else {
239 children = children.concat(findChildNodes(child, tagName, elementClass, elementID, elementName));
240 }
19194f82 241 }
19194f82 242 }
243 return children;
244}
245/*
246 elementSetHide (elements, hide)
247
248 Adds or removes the "hide" class for the specified elements depending on boolean hide.
249*/
250function elementShowAdvanced(elements, show) {
251 for (var elementIndex in elements){
252 element = elements[elementIndex];
253 element.className = element.className.replace(new RegExp(' ?hide'), '')
254 if(!show) {
255 element.className += ' hide';
256 }
257 }
258}
259
260function showAdvancedOnClick(button, hidetext, showtext){
261 var toSet=findChildNodes(button.form, null, 'advanced');
262 var buttontext = '';
263 if (button.form.elements['mform_showadvanced_last'].value == '0') {
264 elementShowAdvanced(toSet, true);
265 buttontext = hidetext;
266 button.form.elements['mform_showadvanced_last'].value = '1';
267 } else {
268 elementShowAdvanced(toSet, false);
269 buttontext = showtext;
270 button.form.elements['mform_showadvanced_last'].value = '0';
271 }
272 var formelements = button.form.elements;
273 for (var i in formelements){
274 if (formelements[i].name=='mform_showadvanced'){
275 formelements[i].value = buttontext;
276 }
277 }
278 //never submit the form if js is enabled.
279 return false;
280}
47aa42e2 281
282/*
283 elementToggleHide (element, elementFinder)
284
285 If elementFinder is not provided, toggles the "hidden" class for the specified element.
286 If elementFinder is provided, then the "hidden" class will be toggled for the object
287 returned by the function call elementFinder(element).
288
289 If persistent == true, also sets a cookie for this.
290*/
19194f82 291function elementToggleHide(el, persistent, elementFinder) {
47aa42e2 292 if(!elementFinder) {
293 var obj = el;
294 }
295 else {
296 var obj = elementFinder(el);
297 }
298 if(obj.className.indexOf('hidden') == -1) {
299 obj.className += ' hidden';
19194f82 300 var shown = 0;
47aa42e2 301 }
302 else {
19194f82 303 obj.className = obj.className.replace(new RegExp(' ?hidden'), '')
304 var shown = 1;
47aa42e2 305 }
19194f82 306
47aa42e2 307 if(persistent == true) {
308 new cookie('hide:' + obj.id, 1, (shown ? -1 : 356), '/').set();
309 }
310}
311
312
313function elementCookieHide(id) {
314 var obj = document.getElementById(id);
315 var cook = new cookie('hide:' + id).read();
316 if(cook != null) {
317 elementToggleHide(obj, false);
318 }
319}
320
321function filterByParent(elCollection, parentFinder) {
322 var filteredCollection = [];
323 for(var i = 0; i < elCollection.length; ++i) {
324 var findParent = parentFinder(elCollection[i]);
325 if(findParent.nodeName != 'BODY') {
326 filteredCollection.push(elCollection[i]);
327 }
328 }
329 return filteredCollection;
330}
331
7979105c 332/*
333 All this is here just so that IE gets to handle oversized blocks
334 in a visually pleasing manner. It does a browser detect. So sue me.
335*/
336
337function fix_column_widths() {
338 var agt = navigator.userAgent.toLowerCase();
339 if ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1)) {
340 fix_column_width('left-column');
341 fix_column_width('right-column');
342 }
343}
344
345function fix_column_width(colName) {
346 if(column = document.getElementById(colName)) {
347 if(!column.offsetWidth) {
348 setTimeout("fix_column_width('" + colName + "')", 20);
349 return;
350 }
351
352 var width = 0;
353 var nodes = column.childNodes;
354
355 for(i = 0; i < nodes.length; ++i) {
356 if(nodes[i].className.indexOf("sideblock") != -1 ) {
357 if(width < nodes[i].offsetWidth) {
358 width = nodes[i].offsetWidth;
359 }
360 }
361 }
362
363 for(i = 0; i < nodes.length; ++i) {
364 if(nodes[i].className.indexOf("sideblock") != -1 ) {
365 nodes[i].style.width = width + 'px';
366 }
367 }
368 }
369}
d13c5938 370
371
372/*
373 Insert myValue at current cursor position
374*/
375function insertAtCursor(myField, myValue) {
376 // IE support
377 if (document.selection) {
378 myField.focus();
379 sel = document.selection.createRange();
380 sel.text = myValue;
381 }
382 // Mozilla/Netscape support
383 else if (myField.selectionStart || myField.selectionStart == '0') {
384 var startPos = myField.selectionStart;
385 var endPos = myField.selectionEnd;
386 myField.value = myField.value.substring(0, startPos)
387 + myValue + myField.value.substring(endPos, myField.value.length);
388 } else {
389 myField.value += myValue;
390 }
391}