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