]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/web/opac/common/js/utils.js
treating arrays different than objects in grep iterator
[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         if( sel.selectedIndex < 0 ) return null;
203         var o = sel.options[sel.selectedIndex];
204         var v = o.value; 
205         if(v == null) v = o.innerHTML;
206         return v;
207 }
208
209 function getSelectorName( sel ) {
210         var o = sel.options[sel.selectedIndex];
211         var v = o.name;
212         if(v == null || v == undefined || v == "") v = o.innerHTML;
213         return v;
214 }
215
216 function setSelectorByName( sel, name ) {
217         for( var o in sel.options ) {
218                 var opt = sel.options[o];
219                 if( opt.name == name || opt.innerHTML == name ) {
220                         sel.selectedIndex = o;
221                         opt.selected = true;
222                 }
223         }
224 }
225
226 function findSelectorOptByValue( sel, val ) {
227         for( var i = 0; i < sel.options.length; i++ ) {
228                 var opt = sel.options[i];
229                 if( opt.value == val ) return opt;
230         }
231         return null;
232 }
233
234 function debugSelector(sel) {
235         var s = 'Selector\n';
236         for( var i = 0; i != sel.options.length; i++ ) {
237                 var o = sel.options[i];
238                 s += "\t" + o.innerHTML + "\n";
239         }
240         return s;
241 }
242
243 function findParentByNodeName(node, name) {
244         while( ( node = node.parentNode) ) 
245                 if (node.nodeName == name) return node;
246         return null;
247 }
248
249 /* returns only elements in nodes childNodes list, not sub-children */
250 function getElementsByTagNameFlat( node, name ) {
251         var elements = [];
252         for( var e in node.childNodes ) {
253                 var n = node.childNodes[e];
254                 if( n && n.nodeName == name ) elements.push(n);
255         }
256         return elements;
257 }
258
259 /* expects a tree with a id() method on each node and a 
260 children() method to get to each node */
261 function findTreeItemById( tree, id ) {
262         if( tree.id() == id ) return tree;
263         for( var c in tree.children() ) {
264                 var found = findTreeItemById( tree.children()[c], id );
265                 if(found) return found;
266         }
267         return null;
268 }
269
270 /* returns null if none of the tests are true.  returns sub-array of 
271 matching array items otherwise */
272 function grep( arr, func ) {
273         var results = [];
274         if(!arr) return null;
275         if( arr.constructor == Array ) {
276                 for( var i = 0; i < arr.length; i++ ) {
277                         if( func(arr[i]) ) 
278                                 results.push(arr[i]);
279                 }
280         } else {
281                 for( var i in arr ) {
282                         if( func(arr[i]) ) 
283                                 results.push(arr[i]);
284                 }
285         }
286         if(results.length > 0) return results;
287         return null;
288 }
289
290 function doSelectorActions(sel) {
291         if(IE && sel) { 
292                 sel.onchange = function() {
293                         var o = sel.options[sel.selectedIndex];
294                         if(o && o.onclick) o.onclick()
295                 }
296         }
297 }
298
299 /* if index < 0, the item is pushed onto the end */
300 function insertSelectorVal( selector, index, name, value, action, indent ) {
301         if( index < 0 ) index = selector.options.length;
302         var a = [];
303         for( var i = selector.options.length; i != index; i-- ) 
304                 a[i] = selector.options[i-1];
305
306         var opt = setSelectorVal( selector, index, name, value, action, indent );
307
308         for( var i = index + 1; i < a.length; i++ ) 
309                 selector.options[i] = a[i];
310
311         return opt;
312 }
313
314 /* changes the value of the option at the specified index */
315 function setSelectorVal( selector, index, name, value, action, indent ) {
316         if(!indent || indent < 0) indent = 0;
317         indent = parseInt(indent);
318
319         var option;
320
321         if(IE) {
322                 var pre = elem("pre");
323                 for( var i = 0; i != indent; i++ )
324                         pre.appendChild(text("   "));
325
326                 pre.appendChild(text(name));
327                 option = new Option("", value);
328                 selector.options[index] = option;
329                 option.appendChild(pre);
330         
331         } else {
332                 indent = indent * 14;
333                 option= new Option(name, value);
334                 option.setAttribute("style", "padding-left: "+indent+'px;');
335                 selector.options[index] = option;
336                 if(action) option.onclick = action;
337         }
338
339         if(action) option.onclick = action;
340         return option;
341 }
342
343
344 /* split on spaces.  capitalize the first /\w/ character in
345    each substring */
346 function normalize(val) {
347
348    if(!val) return ""; 
349
350    var newVal = '';
351    try {val = val.split(' ');} catch(E) {return val;}
352    var reg = /\w/;
353
354    for( var c = 0; c < val.length; c++) {
355
356       var string = val[c];
357       var cap = false; 
358       for(var x = 0; x != string.length; x++) {
359
360          if(!cap) {
361             var ch = string.charAt(x);
362             if(reg.exec(ch + "")) {
363                newVal += string.charAt(x).toUpperCase();
364                cap = true;
365                continue;
366             }
367          }
368
369          newVal += string.charAt(x).toLowerCase();
370       }
371       if(c < (val.length-1)) newVal += " ";
372    }
373
374    newVal = newVal.replace(/\s*\.\s*$/,'');
375    newVal = newVal.replace(/\s*\/\s*\/\s*$/,' / ');
376    newVal = newVal.replace(/\s*\/\s*$/,'');
377
378    return newVal;
379 }
380
381
382 /* returns true if n is null or stringifies to 'undefined' */
383 function isNull(n) {
384         if( n == null || n == undefined || n.toString().toLowerCase() == "undefined" 
385                 || n.toString().toLowerCase() == "null" )
386                 return true;
387         return false;
388 }
389
390
391 /* find nodes with an attribute of 'name' that equals nodeName */
392
393 function $n( root, nodeName ) { return findNodeByName(root,nodeName); }
394
395 function findNodeByName(root, nodeName) {
396         if( !root || !nodeName) return null;
397
398         if(root.nodeType != 1) return null;
399
400         if(root.getAttribute("name") == nodeName || root.name == nodeName ) 
401                 return root;
402
403         var children = root.childNodes;
404
405         for( var i = 0; i != children.length; i++ ) {
406                 var n = findNodeByName(children[i], nodeName);
407                 if(n) return n;
408         }
409
410         return null;
411 }
412
413
414 /* truncates the string at 'size' characters and appends a '...' to the end */
415 function truncate(string, size) {
416         if(string && size != null && 
417                         size > -1 && string.length > size) 
418                 return string.substr(0, size) + "... "; 
419         return string;
420 }
421
422
423 /* style sheets must have a 'name' attribute for these functions to work */
424 function setActivateStyleSheet(name) {
425         var i, a, main;
426         for (i = 0; (a = document.getElementsByTagName ("link")[i]); i++) {
427                 if (a.getAttribute ("rel").indexOf ("style") != -1 && a.getAttribute ("name")) {
428                         a.disabled = true;
429                         if (a.getAttribute ("name").indexOf(name) != -1)
430                                 a.disabled = false;
431                 }
432         }
433 }
434
435
436 /* ----------------------------------------------------- */
437 var currentFontSize;
438 function scaleFonts(type) {
439
440         var size                = "";
441         var ssize       = "";
442         var size2       = "";
443         var a;
444         
445         if(!currentFontSize) currentFontSize = 'regular';
446         if(currentFontSize == 'regular' && type == 'regular' ) return;
447         if( currentFontSize == type ) return;
448         currentFontSize = type;
449
450         switch(type) {
451                 case "large":  /* these are arbitrary.. but they seem to work ok in FF/IE */
452                         size = "142%"; 
453                         size2 = "107%"; 
454                         ssize = "94%";
455                         break;
456         }
457
458         document.getElementsByTagName('body')[0].style.fontSize = size;
459         for (i = 0; (a = document.getElementsByTagName ("td")[i]); i++) a.style.fontSize = size;;
460         for (i = 0; (a = document.getElementsByTagName ("div")[i]); i++) a.style.fontSize = ssize;
461         for (i = 0; (a = document.getElementsByTagName ("option")[i]); i++) a.style.fontSize = ssize;
462         for (i = 0; (a = document.getElementsByTagName ("li")[i]); i++) a.style.fontSize = ssize;
463         for (i = 0; (a = document.getElementsByTagName ("span")[i]); i++) a.style.fontSize = ssize;
464         for (i = 0; (a = document.getElementsByTagName ("select")[i]); i++) a.style.fontSize = ssize;
465         for (i = 0; (a = document.getElementsByTagName ("a")[i]); i++) a.style.fontSize = size2;
466 }
467
468
469 function sortWordsIgnoreCase(a, b) {
470         a = a.toLowerCase();
471         b = b.toLowerCase();
472         if(a>b) return 1;
473         if(a<b) return -1;
474         return 0;
475 }
476
477
478 function getSelectedList(sel) {
479         if(!sel) return [];
480         var vals = [];
481         for( var i = 0; i != sel.options.length; i++ ) {
482                 if(sel.options[i].selected)
483                         vals.push(sel.options[i].value);
484         }
485         return vals;
486 }
487
488
489 function setEnterFunc(node, func) {
490         if(!(node && func)) return;
491         node.onkeydown = function(evt) {
492                 if( userPressedEnter(evt)) func();
493         }
494 }
495
496 function iterate( arr, callback ) {
497         for( var i = 0; i < arr.length; i++ ) 
498                 callback(arr[i]);
499 }
500
501
502
503
504 /* taken directly from the JSAN util.date library */
505 /* but changed from the util.date.interval_to_seconds invocation, 
506 because JSAN will assume the whole library is already loaded if 
507 it sees that, and the staff client uses both this file and the
508 JSAN library*/
509 function interval_to_seconds( $interval ) {
510
511         $interval = $interval.replace( /and/, ',' );
512         $interval = $interval.replace( /,/, ' ' );
513         
514         var $amount = 0;
515         var results = $interval.match( /\s*\+?\s*(\d+)\s*(\w{1})\w*\s*/g);  
516         for( var i = 0; i < results.length; i++ ) {
517                 if(!results[i]) continue;
518                 var result = results[i].match( /\s*\+?\s*(\d+)\s*(\w{1})\w*\s*/ );
519                 if (result[2] == 's') $amount += result[1] ;
520                 if (result[2] == 'm') $amount += 60 * result[1] ;
521                 if (result[2] == 'h') $amount += 60 * 60 * result[1] ;
522                 if (result[2] == 'd') $amount += 60 * 60 * 24 * result[1] ;
523                 if (result[2] == 'w') $amount += 60 * 60 * 24 * 7 * result[1] ;
524                 if (result[2] == 'M') $amount += ((60 * 60 * 24 * 365)/12) * result[1] ;
525                 if (result[2] == 'y') $amount += 60 * 60 * 24 * 365 * result[1] ;
526         }
527         return $amount;
528 }
529
530
531 function openWindow( data ) {
532         if( isXUL() ) {
533                 var data = window.escape(
534                         '<html><head><title></title></head><body>' + data + '</body></html>');
535
536                 xulG.window_open(
537                         'data:text/html,' + data,
538                         '', 
539                         'chrome,resizable,width=700,height=500'); 
540
541         } else {
542                 win = window.open('','', 'resizable,width=700,height=500,scrollbars=1'); 
543                 win.document.body.innerHTML = data;
544         }
545 }
546
547
548 /* alerts the innerhtml of the node with the given id */
549 function alertId(id) {
550         var node = $(id);
551         if(node) alert(node.innerHTML);
552 }
553
554 function confirmId(id) {
555         var node = $(id);
556         if(node) return confirm(node.innerHTML);
557 }
558
559
560 function goBack() { history.back(); }
561 function goForward() { history.forward(); }
562
563
564 function uniquify(arr) {
565         if(!arr) return [];
566         var newarr = [];
567         for( var i = 0; i < arr.length; i++ ) {
568                 var item = arr[i];
569                 if( ! grep( newarr, function(x) {return (x == item);}))
570                         newarr.push(item);
571         }
572         return newarr;
573 }
574
575 function contains(arr, item) {
576         for( var i = 0; i < arr.length; i++ ) 
577                 if( arr[i] == item ) return true;
578         return false;
579 }
580
581 function isTrue(i) {
582         return (i && !(i+'').match(/f/i) );
583 }
584
585
586 /* builds a JS date object with the given info.  The given data
587         has to be valid (e.g. months == 30 is not valid).  Returns NULL on 
588         invalid date 
589         Months are 1-12 (unlike the JS date object)
590         */
591
592 function buildDate( year, month, day, hours, minutes, seconds ) {
593
594         if(!year) year = 0;
595         if(!month) month = 1;
596         if(!day) day = 1;
597         if(!hours) hours = 0;
598         if(!minutes) minutes = 0;
599         if(!seconds) seconds = 0;
600
601         var d = new Date(year, month - 1, day, hours, minutes, seconds);
602         
603         _debug('created date with ' +
604                 (d.getYear() + 1900) +'-'+
605                 (d.getMonth() + 1) +'-'+
606                 d.getDate()+' '+
607                 d.getHours()+':'+
608                 d.getMinutes()+':'+
609                 d.getSeconds());
610
611
612         if( 
613                 (d.getYear() + 1900) == year &&
614                 d.getMonth()    == (month - 1) &&
615                 d.getDate()             == new Number(day) &&
616                 d.getHours()    == new Number(hours) &&
617                 d.getMinutes() == new Number(minutes) &&
618                 d.getSeconds() == new Number(seconds) ) {
619                 return d;
620         }
621
622         return null;
623 }
624
625