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