]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/web/opac/common/js/utils.js
added the myopac holds batch select code/unselect UI and code. implemented batch...
[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         return val; /* disable me for now */
363
364    if(!val) return ""; 
365
366    var newVal = '';
367    try {val = val.split(' ');} catch(E) {return val;}
368    var reg = /\w/;
369
370    for( var c = 0; c < val.length; c++) {
371
372       var string = val[c];
373       var cap = false; 
374       for(var x = 0; x != string.length; x++) {
375
376          if(!cap) {
377             var ch = string.charAt(x);
378             if(reg.exec(ch + "")) {
379                newVal += string.charAt(x).toUpperCase();
380                cap = true;
381                continue;
382             }
383          }
384
385          newVal += string.charAt(x).toLowerCase();
386       }
387       if(c < (val.length-1)) newVal += " ";
388    }
389
390    newVal = newVal.replace(/\s*\.\s*$/,'');
391    newVal = newVal.replace(/\s*\/\s*\/\s*$/,' / ');
392    newVal = newVal.replace(/\s*\/\s*$/,'');
393
394    return newVal;
395 }
396
397
398 /* returns true if n is null or stringifies to 'undefined' */
399 function isNull(n) {
400         if( n == null || n == undefined || n.toString().toLowerCase() == "undefined" 
401                 || n.toString().toLowerCase() == "null" )
402                 return true;
403         return false;
404 }
405
406
407 /* find nodes with an attribute of 'name' that equals nodeName */
408
409 function $n( root, nodeName ) { return findNodeByName(root,nodeName); }
410
411 function findNodeByName(root, nodeName) {
412         if( !root || !nodeName) return null;
413
414         if(root.nodeType != 1) return null;
415
416         if(root.getAttribute("name") == nodeName || root.name == nodeName ) 
417                 return root;
418
419         var children = root.childNodes;
420
421         for( var i = 0; i != children.length; i++ ) {
422                 var n = findNodeByName(children[i], nodeName);
423                 if(n) return n;
424         }
425
426         return null;
427 }
428
429
430 /* truncates the string at 'size' characters and appends a '...' to the end */
431 function truncate(string, size) {
432         if(string && size != null && 
433                         size > -1 && string.length > size) 
434                 return string.substr(0, size) + "... "; 
435         return string;
436 }
437
438
439 /* style sheets must have a 'name' attribute for these functions to work */
440 function setActivateStyleSheet(name) {
441         var i, a, main;
442         for (i = 0; (a = document.getElementsByTagName ("link")[i]); i++) {
443                 if (a.getAttribute ("rel").indexOf ("style") != -1 && a.getAttribute ("name")) {
444                         a.disabled = true;
445                         if (a.getAttribute ("name").indexOf(name) != -1)
446                                 a.disabled = false;
447                 }
448         }
449 }
450
451
452 /* ----------------------------------------------------- */
453 var currentFontSize;
454 function scaleFonts(type) {
455
456         var size                = "";
457         var ssize       = "";
458         var size2       = "";
459         var a;
460         
461         if(!currentFontSize) currentFontSize = 'regular';
462         if(currentFontSize == 'regular' && type == 'regular' ) return;
463         if( currentFontSize == type ) return;
464         currentFontSize = type;
465
466         switch(type) {
467                 case "large":  /* these are arbitrary.. but they seem to work ok in FF/IE */
468                         size = "142%"; 
469                         size2 = "107%"; 
470                         ssize = "94%";
471                         break;
472         }
473
474         document.getElementsByTagName('body')[0].style.fontSize = size;
475         for (i = 0; (a = document.getElementsByTagName ("td")[i]); i++) a.style.fontSize = size;;
476         for (i = 0; (a = document.getElementsByTagName ("div")[i]); i++) a.style.fontSize = ssize;
477         for (i = 0; (a = document.getElementsByTagName ("option")[i]); i++) a.style.fontSize = ssize;
478         for (i = 0; (a = document.getElementsByTagName ("li")[i]); i++) a.style.fontSize = ssize;
479         for (i = 0; (a = document.getElementsByTagName ("span")[i]); i++) a.style.fontSize = ssize;
480         for (i = 0; (a = document.getElementsByTagName ("select")[i]); i++) a.style.fontSize = ssize;
481         for (i = 0; (a = document.getElementsByTagName ("a")[i]); i++) a.style.fontSize = size2;
482 }
483
484
485 function sortWordsIgnoreCase(a, b) {
486         a = a.toLowerCase();
487         b = b.toLowerCase();
488         if(a>b) return 1;
489         if(a<b) return -1;
490         return 0;
491 }
492
493
494 function getSelectedList(sel) {
495         if(!sel) return [];
496         var vals = [];
497         for( var i = 0; i != sel.options.length; i++ ) {
498                 if(sel.options[i].selected)
499                         vals.push(sel.options[i].value);
500         }
501         return vals;
502 }
503
504
505 function setEnterFunc(node, func) {
506         if(!(node && func)) return;
507         node.onkeydown = function(evt) {
508                 if( userPressedEnter(evt)) func();
509         }
510 }
511
512 function iterate( arr, callback ) {
513         for( var i = 0; arr && i < arr.length; i++ ) 
514                 callback(arr[i]);
515 }
516
517
518
519
520 /* taken directly from the JSAN util.date library */
521 /* but changed from the util.date.interval_to_seconds invocation, 
522 because JSAN will assume the whole library is already loaded if 
523 it sees that, and the staff client uses both this file and the
524 JSAN library*/
525 function interval_to_seconds( $interval ) {
526
527         $interval = $interval.replace( /and/, ',' );
528         $interval = $interval.replace( /,/, ' ' );
529         
530         var $amount = 0;
531         var results = $interval.match( /\s*\+?\s*(\d+)\s*(\w{1})\w*\s*/g);  
532         for( var i = 0; i < results.length; i++ ) {
533                 if(!results[i]) continue;
534                 var result = results[i].match( /\s*\+?\s*(\d+)\s*(\w{1})\w*\s*/ );
535                 if (result[2] == 's') $amount += result[1] ;
536                 if (result[2] == 'm') $amount += 60 * result[1] ;
537                 if (result[2] == 'h') $amount += 60 * 60 * result[1] ;
538                 if (result[2] == 'd') $amount += 60 * 60 * 24 * result[1] ;
539                 if (result[2] == 'w') $amount += 60 * 60 * 24 * 7 * result[1] ;
540                 if (result[2] == 'M') $amount += ((60 * 60 * 24 * 365)/12) * result[1] ;
541                 if (result[2] == 'y') $amount += 60 * 60 * 24 * 365 * result[1] ;
542         }
543         return $amount;
544 }
545
546
547 function openWindow( data ) {
548         if( isXUL() ) {
549                 var data = window.escape(
550                         '<html><head><title></title></head><body>' + data + '</body></html>');
551
552                 xulG.window_open(
553                         'data:text/html,' + data,
554                         '', 
555                         'chrome,resizable,width=700,height=500'); 
556
557         } else {
558                 win = window.open('','', 'resizable,width=700,height=500,scrollbars=1'); 
559                 win.document.body.innerHTML = data;
560         }
561 }
562
563
564 /* alerts the innerhtml of the node with the given id */
565 function alertId(id) {
566         var node = $(id);
567         if(node) alert(node.innerHTML);
568 }
569
570 function alertIdText(id, text) {
571         var node = $(id);
572    if(!node) return;
573    if(text)
574       alert(text + '\n\n' + node.innerHTML);
575    else 
576            alert(node.innerHTML);
577 }
578
579 function confirmId(id) {
580         var node = $(id);
581         if(node) return confirm(node.innerHTML);
582 }
583
584
585 function goBack() { history.back(); }
586 function goForward() { history.forward(); }
587
588
589 function uniquify(arr) {
590         if(!arr) return [];
591         var newarr = [];
592         for( var i = 0; i < arr.length; i++ ) {
593                 var item = arr[i];
594                 if( ! grep( newarr, function(x) {return (x == item);}))
595                         newarr.push(item);
596         }
597         return newarr;
598 }
599
600 function contains(arr, item) {
601         for( var i = 0; i < arr.length; i++ ) 
602                 if( arr[i] == item ) return true;
603         return false;
604 }
605
606 function isTrue(i) {
607         return (i && !(i+'').match(/f/i) );
608 }
609
610
611 /* builds a JS date object with the given info.  The given data
612         has to be valid (e.g. months == 30 is not valid).  Returns NULL on 
613         invalid date 
614         Months are 1-12 (unlike the JS date object)
615         */
616
617 function buildDate( year, month, day, hours, minutes, seconds ) {
618
619         if(!year) year = 0;
620         if(!month) month = 1;
621         if(!day) day = 1;
622         if(!hours) hours = 0;
623         if(!minutes) minutes = 0;
624         if(!seconds) seconds = 0;
625
626         var d = new Date(year, month - 1, day, hours, minutes, seconds);
627         
628         _debug('created date with ' +
629                 (d.getYear() + 1900) +'-'+
630                 (d.getMonth() + 1) +'-'+
631                 d.getDate()+' '+
632                 d.getHours()+':'+
633                 d.getMinutes()+':'+
634                 d.getSeconds());
635
636
637         if( 
638                 (d.getYear() + 1900) == year &&
639                 d.getMonth()    == (month - 1) &&
640                 d.getDate()             == new Number(day) &&
641                 d.getHours()    == new Number(hours) &&
642                 d.getMinutes() == new Number(minutes) &&
643                 d.getSeconds() == new Number(seconds) ) {
644                 return d;
645         }
646
647         return null;
648 }
649
650 function mkYearMonDay(date) {
651         if(!date) date = new Date();
652         var y = date.getYear() + 1900;
653         var m = (date.getMonth() + 1)+'';
654         var d = date.getDate()+'';
655         if(m.length == 1) m = '0'+m;
656         if(d.length == 1) d = '0'+d;
657         return y+'-'+m+'-'+d;
658 }
659
660
661 function debugFMObject(obj) {
662         if(typeof obj != 'object' ) return obj;
663         _debug("---------------------");
664         var keys = fmclasses[obj.classname];
665         if(!keys) { _debug(formatJSON(js2JSON(obj))); return; }
666
667         keys.sort();
668         for( var i = 0; i < keys.length; i++ ) {
669                 var key = keys[i];
670                 while( key.length < 12 ) key += ' ';
671                 var val = obj[keys[i]]();
672                 if( typeof val == 'object' ) {
673                         _debug(key+' :=\n');
674                         _debugFMObject(val);
675                 } else {
676                         _debug(key+' = ' +val);
677                 }
678
679         }
680         _debug("---------------------");
681 }
682
683
684 function getTableRows(tbody) {
685     var rows = [];
686     if(!tbody) return rows;
687
688     var children = tbody.childNodes;
689     if(!children) return rows;
690
691     for(var i = 0; i < children.length; i++) {
692         var child = children[i];
693         if(child.nodeName.match(/^tr$/i)) 
694             rows.push(child);
695     }
696     return rows;
697 }
698
699 function getObjectKeys(obj) {
700     keys = []
701     for(var k in obj)
702         keys.push(k)
703     return keys;
704 }