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