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');
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]) {
96 lock = !master.checked; break;
98 lock = master.checked; break;
99 case 'noitemselected':
100 lock = master.selectedIndex==-1; break;
102 lock = master.value==value; break;
104 lock = master.value!=value; break;
106 for (var ei in dependons[dependon][condition][value]) {
107 var formelement = form[dependons[dependon][condition][value][ei]];
108 formelement.disabled = lock;
116 function lockoptionsallsetup(formid) {
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'));};
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'));};
133 return lockoptionsall(formid);
137 function submitFormById(id) {
138 var theform = document.getElementById(id);
142 if(theform.tagName.toLowerCase() != 'form') {
145 if(!theform.onsubmit || theform.onsubmit()) {
146 return theform.submit();
150 function select_all_in(elTagName, elClass, elId) {
151 var inputs = document.getElementsByTagName('input');
152 inputs = filterByParent(inputs, function(el) {return findParentNode(el, elTagName, elClass, elId);});
153 for(var i = 0; i < inputs.length; ++i) {
154 if(inputs[i].type == 'checkbox' || inputs[i].type == 'radio') {
155 inputs[i].checked = 'checked';
160 function deselect_all_in(elTagName, elClass, elId) {
161 var inputs = document.getElementsByTagName('INPUT');
162 inputs = filterByParent(inputs, function(el) {return findParentNode(el, elTagName, elClass, elId);});
163 for(var i = 0; i < inputs.length; ++i) {
164 if(inputs[i].type == 'checkbox' || inputs[i].type == 'radio') {
165 inputs[i].checked = '';
170 function confirm_if(expr, message) {
174 return confirm(message);
179 findParentNode (start, elementName, elementClass, elementID)
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
186 function findParentNode(el, elName, elClass, elId) {
187 while(el.nodeName != 'BODY') {
189 (!elName || el.nodeName == elName) &&
190 (!elClass || el.className.indexOf(elClass) != -1) &&
191 (!elId || el.id == elId))
200 findChildNode (start, elementName, elementClass, elementID)
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.
205 Doesn't examine children of matches.
207 function findChildNodes(start, tagName, elementClass, elementID, elementName) {
208 var children = new Array();
209 for (var i = 0; i < start.childNodes.length; i++) {
210 var classfound = false;
211 var child = start.childNodes[i];
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){
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))
228 children = children.concat(child);
230 children = children.concat(findChildNodes(child, tagName, elementClass, elementID, elementName));
237 elementSetHide (elements, hide)
239 Adds or removes the "hide" class for the specified elements depending on boolean hide.
241 function elementShowAdvanced(elements, show) {
242 for (var elementIndex in elements){
243 element = elements[elementIndex];
244 element.className = element.className.replace(new RegExp(' ?hide'), '')
246 element.className += ' hide';
251 function showAdvancedOnClick(button, hidetext, showtext){
252 var toSet=findChildNodes(button.form, null, 'advanced');
254 if (button.form.elements['mform_showadvanced_last'].value == '0' || button.form.elements['mform_showadvanced_last'].value == '' ) {
255 elementShowAdvanced(toSet, true);
256 buttontext = hidetext;
257 button.form.elements['mform_showadvanced_last'].value = '1';
259 elementShowAdvanced(toSet, false);
260 buttontext = showtext;
261 button.form.elements['mform_showadvanced_last'].value = '0';
263 var formelements = button.form.elements;
264 for (var i in formelements){
265 if (formelements[i] && formelements[i].name && (formelements[i].name=='mform_showadvanced')){
266 formelements[i].value = buttontext;
269 //never submit the form if js is enabled.
274 elementToggleHide (element, elementFinder)
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).
280 If persistent == true, also sets a cookie for this.
282 function elementToggleHide(el, persistent, elementFinder) {
287 var obj = elementFinder(el);
289 if(obj.className.indexOf('hidden') == -1) {
290 obj.className += ' hidden';
294 obj.className = obj.className.replace(new RegExp(' ?hidden'), '')
298 if(persistent == true) {
299 new cookie('hide:' + obj.id, 1, (shown ? -1 : 356), '/').set();
304 function elementCookieHide(id) {
305 var obj = document.getElementById(id);
306 var cook = new cookie('hide:' + id).read();
308 elementToggleHide(obj, false);
312 function 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]);
320 return filteredCollection;
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.
328 function 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');
336 function fix_column_width(colName) {
337 if(column = document.getElementById(colName)) {
338 if(!column.offsetWidth) {
339 setTimeout("fix_column_width('" + colName + "')", 20);
344 var nodes = column.childNodes;
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;
354 for(i = 0; i < nodes.length; ++i) {
355 if(nodes[i].className.indexOf("sideblock") != -1 ) {
356 nodes[i].style.width = width + 'px';
364 Insert myValue at current cursor position
366 function insertAtCursor(myField, myValue) {
368 if (document.selection) {
370 sel = document.selection.createRange();
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);
380 myField.value += myValue;