]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/web/opac/common/js/utils.js
added utility method
[Evergreen.git] / Open-ILS / web / opac / common / js / utils.js
1 function $(id) { return getId(id); }
2 function getId(id) {
3         return document.getElementById(id);
4 }
5
6 function swapCSSClass(obj, old, newc ) {
7         removeCSSClass(obj, old );
8         addCSSClass(obj, newc );
9 }
10
11
12 function addCSSClass(e,c) {
13         if(!e || !c) return;
14
15         var css_class_string = e.className;
16         var css_class_array;
17
18         if(css_class_string)
19                 css_class_array = css_class_string.split(/\s+/);
20
21         var string_ip = ""; /*strip out nulls*/
22         for (var css_class in css_class_array) {
23                 if (css_class_array[css_class] == c) { return; }
24                 if(css_class_array[css_class] !=null)
25                         string_ip += css_class_array[css_class] + " ";
26         }
27         string_ip += c;
28         e.className = string_ip;
29 }
30
31 function removeCSSClass(e, c) {
32         if(!e || !c) return;
33
34         var css_class_string = '';
35
36         var css_class_array = e.className;
37         if( css_class_array )
38                 css_class_array = css_class_array.split(/\s+/);
39
40         var first = 1;
41         for (var css_class in css_class_array) {
42                 if (css_class_array[css_class] != c) {
43                         if (first == 1) {
44                                 css_class_string = css_class_array[css_class];
45                                 first = 0;
46                         } else {
47                                 css_class_string = css_class_string + ' ' +
48                                         css_class_array[css_class];
49                         }
50                 }
51         }
52         e.className = css_class_string;
53 }
54
55
56 /*returns the character code pressed that caused the event */
57 function grabCharCode(evt) {
58    evt = (evt) ? evt : ((window.event) ? event : null); 
59    if( evt ) {
60       return (evt.charCode ? evt.charCode : 
61          ((evt.which) ? evt.which : evt.keyCode ));
62    } else { return -1; }
63 }       
64
65
66 /* returns true if the user pressed enter */
67 function userPressedEnter(evt) {
68    var code = grabCharCode(evt);
69    if(code==13||code==3) return true;
70    return false;
71 }   
72
73
74 function goTo(url) {
75         /* setTimeout because ie sux */
76         setTimeout( function(){ location.href = url; }, 0 );
77 }
78
79
80 function removeChildren(dom) {
81         if(!dom) return;
82         while(dom.childNodes[0])
83                 dom.removeChild(dom.childNodes[0]);
84 }
85
86 function appendClear(node, child) {
87         removeChildren(node);
88         node.appendChild(child);
89 }
90
91
92 function instanceOf(object, constructorFunction) {
93
94    if(!IE) {
95       while (object != null) {
96          if (object == constructorFunction.prototype)
97             return true;
98          object = object.__proto__;
99       }
100    } else {
101       while(object != null) {
102          if( object instanceof constructorFunction )
103             return true;
104          object = object.__proto__;
105       }
106    }
107    return false;
108 }         
109
110
111 /* ------------------------------------------------------------------------------------------- */
112 /* detect my browser */
113 var isMac, NS, NS4, NS6, IE, IE4, IE4mac, IE4plus, IE5, IE5plus, IE6, IEMajor, ver4;
114 function detect_browser() {       
115
116    isMac = (navigator.appVersion.indexOf("Mac")!=-1) ? true : false;
117    NS = (navigator.appName == "Netscape") ? true : false;
118    NS4 = (document.layers) ? true : false;
119    IE = (navigator.appName == "Microsoft Internet Explorer") ? true : false;
120    IEmac = ((document.all)&&(isMac)) ? true : false;
121    IE4plus = (document.all) ? true : false;
122    IE4 = ((document.all)&&(navigator.appVersion.indexOf("MSIE 4.")!=-1)) ? true : false;
123    IE5 = ((document.all)&&(navigator.appVersion.indexOf("MSIE 5.")!=-1)) ? true : false;
124    IE6 = ((document.all)&&(navigator.appVersion.indexOf("MSIE 6.")!=-1)) ? true : false;
125    ver4 = (NS4 || IE4plus) ? true : false;
126    NS6 = (!document.layers) && (navigator.userAgent.indexOf('Netscape')!=-1)?true:false;
127
128    IE5plus = IE5 || IE6;
129    IEMajor = 0;
130
131    if (IE4plus) {
132       var start = navigator.appVersion.indexOf("MSIE");
133       var end = navigator.appVersion.indexOf(".",start);
134       IEMajor = parseInt(navigator.appVersion.substring(start+5,end));
135       IE5plus = (IEMajor>=5) ? true : false;
136    }
137 }  
138 detect_browser();
139 /* ------------------------------------------------------------------------------------------- */
140
141
142 function text(t) {
143         if(t == null) t = "";
144         return document.createTextNode(t);
145 }
146
147 function elem(name, attrs, txt) {
148     var e = document.createElement(name);
149     if (attrs) {
150         for (key in attrs) {
151                           if( key == 'id') e.id = attrs[key];
152                           else e.setAttribute(key, attrs[key]);
153         }
154     }
155     if (txt) e.appendChild(text(txt));
156     return e;
157 }                   
158
159
160 /* sel is the selector object, sets selected on the 
161         option with the given value. case does not matter...*/
162 function setSelector( sel, value ) {
163         if(sel && value != null) {
164                 for( var i = 0; i!= sel.options.length; i++ ) { 
165                         if( sel.options[i] ) {
166                                 var val = sel.options[i].value;
167                                 if( val == null || val == "" ) /* for IE */
168                                         val = sel.options[i].innerHTML;
169                                 value += ""; /* in case of number */ 
170                                 if( val && val.toLowerCase() == value.toLowerCase() ) {
171                                         sel.selectedIndex = i;
172                                         sel.options[i].selected = true;
173                                         return true;
174                                 }
175                         }
176                 }
177         }
178         return false;
179 }
180
181 function setSelectorRegex( sel, regex ) {
182         if(sel && regex != null) {
183                 for( var i = 0; i!= sel.options.length; i++ ) { 
184                         if( sel.options[i] ) {
185                                 var val = sel.options[i].value;
186                                 if( val == null || val == "" ) /* for IE */
187                                         val = sel.options[i].innerHTML;
188                                 value += ""; /* in case of number */ 
189                                 if( val && val.match(regex) ) {
190                                         sel.selectedIndex = i;
191                                         sel.options[i].selected = true;
192                                         return true;
193                                 }
194                         }
195                 }
196         }
197         return false;
198 }
199
200 function getSelectorVal( sel ) {
201         if(!sel) return null;
202         var idx = sel.selectedIndex;
203         if( idx < 0 ) return null;
204         var o = sel.options[idx];
205         var v = o.value; 
206         if(v == null) v = o.innerHTML;
207         return v;
208 }
209
210 function getSelectorName( sel ) {
211         var o = sel.options[sel.selectedIndex];
212         var v = o.name;
213         if(v == null || v == undefined || v == "") v = o.innerHTML;
214         return v;
215 }
216
217 function setSelectorByName( sel, name ) {
218         for( var o in sel.options ) {
219                 var opt = sel.options[o];
220                 if( opt.name == name || opt.innerHTML == name ) {
221                         sel.selectedIndex = o;
222                         opt.selected = true;
223                 }
224         }
225 }
226
227 function findSelectorOptByValue( sel, val ) {
228         for( var i = 0; i < sel.options.length; i++ ) {
229                 var opt = sel.options[i];
230                 if( opt.value == val ) return opt;
231         }
232         return null;
233 }
234
235 function debugSelector(sel) {
236         var s = 'Selector\n';
237         for( var i = 0; i != sel.options.length; i++ ) {
238                 var o = sel.options[i];
239                 s += "\t" + o.innerHTML + "\n";
240         }
241         return s;
242 }
243
244 function findParentByNodeName(node, name) {
245         while( ( node = node.parentNode) ) 
246                 if (node.nodeName == name) return node;
247         return null;
248 }
249
250 /* returns only elements in nodes childNodes list, not sub-children */
251 function getElementsByTagNameFlat( node, name ) {
252         var elements = [];
253         for( var e in node.childNodes ) {
254                 var n = node.childNodes[e];
255                 if( n && n.nodeName == name ) elements.push(n);
256         }
257         return elements;
258 }
259
260 /* expects a tree with a id() method on each node and a 
261 children() method to get to each node */
262 function findTreeItemById( tree, id ) {
263         if( tree.id() == id ) return tree;
264         for( var c in tree.children() ) {
265                 var found = findTreeItemById( tree.children()[c], id );
266                 if(found) return found;
267         }
268         return null;
269 }
270
271 /* returns null if none of the tests are true.  returns sub-array of 
272 matching array items otherwise */
273 function grep( arr, func ) {
274         var results = [];
275         if(!arr) return null;
276         if( arr.constructor == Array ) {
277                 for( var i = 0; i < arr.length; i++ ) {
278                         if( func(arr[i]) ) 
279                                 results.push(arr[i]);
280                 }
281         } else {
282                 for( var i in arr ) {
283                         if( func(arr[i]) ) 
284                                 results.push(arr[i]);
285                 }
286         }
287         if(results.length > 0) return results;
288         return null;
289 }
290
291 function doSelectorActions(sel) {
292         if(IE && sel) { 
293                 sel.onchange = function() {
294                         var o = sel.options[sel.selectedIndex];
295                         if(o && o.onclick) o.onclick()
296                 }
297         }
298 }
299
300 /* if index < 0, the item is pushed onto the end */
301 function insertSelectorVal( selector, index, name, value, action, indent ) {
302         if( index < 0 ) index = selector.options.length;
303         var a = [];
304         for( var i = selector.options.length; i != index; i-- ) 
305                 a[i] = selector.options[i-1];
306
307         var opt = setSelectorVal( selector, index, name, value, action, indent );
308
309         for( var i = index + 1; i < a.length; i++ ) 
310                 selector.options[i] = a[i];
311
312         return opt;
313 }
314
315 /* changes the value of the option at the specified index */
316 function setSelectorVal( selector, index, name, value, action, indent ) {
317         if(!indent || indent < 0) indent = 0;
318         indent = parseInt(indent);
319
320         var option;
321
322         if(IE) {
323                 var pre = elem("pre");
324                 for( var i = 0; i != indent; i++ )
325                         pre.appendChild(text("   "));
326
327                 pre.appendChild(text(name));
328                 option = new Option("", value);
329                 selector.options[index] = option;
330                 option.appendChild(pre);
331         
332         } else {
333                 indent = indent * 14;
334                 option= new Option(name, value);
335                 option.setAttribute("style", "padding-left: "+indent+'px;');
336                 selector.options[index] = option;
337                 if(action) option.onclick = action;
338         }
339
340         if(action) option.onclick = action;
341         return option;
342 }
343
344
345 /* split on spaces.  capitalize the first /\w/ character in
346    each substring */
347 function normalize(val) {
348
349    if(!val) return ""; 
350
351    var newVal = '';
352    try {val = val.split(' ');} catch(E) {return val;}
353    var reg = /\w/;
354
355    for( var c = 0; c < val.length; c++) {
356
357       var string = val[c];
358       var cap = false; 
359       for(var x = 0; x != string.length; x++) {
360
361          if(!cap) {
362             var ch = string.charAt(x);
363             if(reg.exec(ch + "")) {
364                newVal += string.charAt(x).toUpperCase();
365                cap = true;
366                continue;
367             }
368          }
369
370          newVal += string.charAt(x).toLowerCase();
371       }
372       if(c < (val.length-1)) newVal += " ";
373    }
374
375    newVal = newVal.replace(/\s*\.\s*$/,'');
376    newVal = newVal.replace(/\s*\/\s*\/\s*$/,' / ');
377    newVal = newVal.replace(/\s*\/\s*$/,'');
378
379    return newVal;
380 }
381
382
383 /* returns true if n is null or stringifies to 'undefined' */
384 function isNull(n) {
385         if( n == null || n == undefined || n.toString().toLowerCase() == "undefined" 
386                 || n.toString().toLowerCase() == "null" )
387                 return true;
388         return false;
389 }
390
391
392 /* find nodes with an attribute of 'name' that equals nodeName */
393
394 function $n( root, nodeName ) { return findNodeByName(root,nodeName); }
395
396 function findNodeByName(root, nodeName) {
397         if( !root || !nodeName) return null;
398
399         if(root.nodeType != 1) return null;
400
401         if(root.getAttribute("name") == nodeName || root.name == nodeName ) 
402                 return root;
403
404         var children = root.childNodes;
405
406         for( var i = 0; i != children.length; i++ ) {
407                 var n = findNodeByName(children[i], nodeName);
408                 if(n) return n;
409         }
410
411         return null;
412 }
413
414
415 /* truncates the string at 'size' characters and appends a '...' to the end */
416 function truncate(string, size) {
417         if(string && size != null && 
418                         size > -1 && string.length > size) 
419                 return string.substr(0, size) + "... "; 
420         return string;
421 }
422
423
424 /* style sheets must have a 'name' attribute for these functions to work */
425 function setActivateStyleSheet(name) {
426         var i, a, main;
427         for (i = 0; (a = document.getElementsByTagName ("link")[i]); i++) {
428                 if (a.getAttribute ("rel").indexOf ("style") != -1 && a.getAttribute ("name")) {
429                         a.disabled = true;
430                         if (a.getAttribute ("name").indexOf(name) != -1)
431                                 a.disabled = false;
432                 }
433         }
434 }
435
436
437 /* ----------------------------------------------------- */
438 var currentFontSize;
439 function scaleFonts(type) {
440
441         var size                = "";
442         var ssize       = "";
443         var size2       = "";
444         var a;
445         
446         if(!currentFontSize) currentFontSize = 'regular';
447         if(currentFontSize == 'regular' && type == 'regular' ) return;
448         if( currentFontSize == type ) return;
449         currentFontSize = type;
450
451         switch(type) {
452                 case "large":  /* these are arbitrary.. but they seem to work ok in FF/IE */
453                         size = "142%"; 
454                         size2 = "107%"; 
455                         ssize = "94%";
456                         break;
457         }
458
459         document.getElementsByTagName('body')[0].style.fontSize = size;
460         for (i = 0; (a = document.getElementsByTagName ("td")[i]); i++) a.style.fontSize = size;;
461         for (i = 0; (a = document.getElementsByTagName ("div")[i]); i++) a.style.fontSize = ssize;
462         for (i = 0; (a = document.getElementsByTagName ("option")[i]); i++) a.style.fontSize = ssize;
463         for (i = 0; (a = document.getElementsByTagName ("li")[i]); i++) a.style.fontSize = ssize;
464         for (i = 0; (a = document.getElementsByTagName ("span")[i]); i++) a.style.fontSize = ssize;
465         for (i = 0; (a = document.getElementsByTagName ("select")[i]); i++) a.style.fontSize = ssize;
466         for (i = 0; (a = document.getElementsByTagName ("a")[i]); i++) a.style.fontSize = size2;
467 }
468
469
470 function sortWordsIgnoreCase(a, b) {
471         a = a.toLowerCase();
472         b = b.toLowerCase();
473         if(a>b) return 1;
474         if(a<b) return -1;
475         return 0;
476 }
477
478
479 function getSelectedList(sel) {
480         if(!sel) return [];
481         var vals = [];
482         for( var i = 0; i != sel.options.length; i++ ) {
483                 if(sel.options[i].selected)
484                         vals.push(sel.options[i].value);
485         }
486         return vals;
487 }
488
489
490 function setEnterFunc(node, func) {
491         if(!(node && func)) return;
492         node.onkeydown = function(evt) {
493                 if( userPressedEnter(evt)) func();
494         }
495 }
496
497 function iterate( arr, callback ) {
498         for( var i = 0; arr && i < arr.length; i++ ) 
499                 callback(arr[i]);
500 }
501
502
503
504
505 /* taken directly from the JSAN util.date library */
506 /* but changed from the util.date.interval_to_seconds invocation, 
507 because JSAN will assume the whole library is already loaded if 
508 it sees that, and the staff client uses both this file and the
509 JSAN library*/
510 function interval_to_seconds( $interval ) {
511
512         $interval = $interval.replace( /and/, ',' );
513         $interval = $interval.replace( /,/, ' ' );
514         
515         var $amount = 0;
516         var results = $interval.match( /\s*\+?\s*(\d+)\s*(\w{1})\w*\s*/g);  
517         for( var i = 0; i < results.length; i++ ) {
518                 if(!results[i]) continue;
519                 var result = results[i].match( /\s*\+?\s*(\d+)\s*(\w{1})\w*\s*/ );
520                 if (result[2] == 's') $amount += result[1] ;
521                 if (result[2] == 'm') $amount += 60 * result[1] ;
522                 if (result[2] == 'h') $amount += 60 * 60 * result[1] ;
523                 if (result[2] == 'd') $amount += 60 * 60 * 24 * result[1] ;
524                 if (result[2] == 'w') $amount += 60 * 60 * 24 * 7 * result[1] ;
525                 if (result[2] == 'M') $amount += ((60 * 60 * 24 * 365)/12) * result[1] ;
526                 if (result[2] == 'y') $amount += 60 * 60 * 24 * 365 * result[1] ;
527         }
528         return $amount;
529 }
530
531
532 function openWindow( data ) {
533         if( isXUL() ) {
534                 var data = window.escape(
535                         '<html><head><title></title></head><body>' + data + '</body></html>');
536
537                 xulG.window_open(
538                         'data:text/html,' + data,
539                         '', 
540                         'chrome,resizable,width=700,height=500'); 
541
542         } else {
543                 win = window.open('','', 'resizable,width=700,height=500,scrollbars=1'); 
544                 win.document.body.innerHTML = data;
545         }
546 }
547
548
549 /* alerts the innerhtml of the node with the given id */
550 function alertId(id) {
551         var node = $(id);
552         if(node) alert(node.innerHTML);
553 }
554
555 function confirmId(id) {
556         var node = $(id);
557         if(node) return confirm(node.innerHTML);
558 }
559
560
561 function goBack() { history.back(); }
562 function goForward() { history.forward(); }
563
564
565 function uniquify(arr) {
566         if(!arr) return [];
567         var newarr = [];
568         for( var i = 0; i < arr.length; i++ ) {
569                 var item = arr[i];
570                 if( ! grep( newarr, function(x) {return (x == item);}))
571                         newarr.push(item);
572         }
573         return newarr;
574 }
575
576 function contains(arr, item) {
577         for( var i = 0; i < arr.length; i++ ) 
578                 if( arr[i] == item ) return true;
579         return false;
580 }
581
582 function isTrue(i) {
583         return (i && !(i+'').match(/f/i) );
584 }
585
586
587 /* builds a JS date object with the given info.  The given data
588         has to be valid (e.g. months == 30 is not valid).  Returns NULL on 
589         invalid date 
590         Months are 1-12 (unlike the JS date object)
591         */
592
593 function buildDate( year, month, day, hours, minutes, seconds ) {
594
595         if(!year) year = 0;
596         if(!month) month = 1;
597         if(!day) day = 1;
598         if(!hours) hours = 0;
599         if(!minutes) minutes = 0;
600         if(!seconds) seconds = 0;
601
602         var d = new Date(year, month - 1, day, hours, minutes, seconds);
603         
604         _debug('created date with ' +
605                 (d.getYear() + 1900) +'-'+
606                 (d.getMonth() + 1) +'-'+
607                 d.getDate()+' '+
608                 d.getHours()+':'+
609                 d.getMinutes()+':'+
610                 d.getSeconds());
611
612
613         if( 
614                 (d.getYear() + 1900) == year &&
615                 d.getMonth()    == (month - 1) &&
616                 d.getDate()             == new Number(day) &&
617                 d.getHours()    == new Number(hours) &&
618                 d.getMinutes() == new Number(minutes) &&
619                 d.getSeconds() == new Number(seconds) ) {
620                 return d;
621         }
622
623         return null;
624 }
625
626 function mkYearMonDay(date) {
627         if(!date) date = new Date();
628         var y = date.getYear() + 1900;
629         var m = (date.getMonth() + 1)+'';
630         var d = date.getDate()+'';
631         if(m.length == 1) m = '0'+m;
632         if(d.length == 1) d = '0'+d;
633         return y+'-'+m+'-'+d;
634 }
635