]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/dojo/openils/Util.js
Provide a handy method for dojo-based interfaces to correctly show timestamps
[working/Evergreen.git] / Open-ILS / web / js / dojo / openils / Util.js
1 /* ---------------------------------------------------------------------------
2  * Copyright (C) 2008  Georgia Public Library Service
3  * Bill Erickson <erickson@esilibrary.com>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * ---------------------------------------------------------------------------
15  */
16
17
18 /**
19  * General purpose, static utility functions
20  */
21
22 if(!dojo._hasResource["openils.Util"]) {
23     dojo._hasResource["openils.Util"] = true;
24     dojo.provide("openils.Util");
25     dojo.require("dojo.date.locale");
26     dojo.require("dojo.date.stamp");
27     dojo.require('openils.Event');
28     dojo.declare('openils.Util', null, {});
29
30
31     /**
32      * Returns a locale-appropriate representation of a timestamp when the
33      * timestamp (first argument) is actually a string as provided by
34      * fieldmapper objects.
35      * The second argument is an optional argument that will be provided
36      * as the second argument to dojo.date.locale.format()
37      */
38     openils.Util.timeStamp = function(s, opts) {
39         if (typeof(opts) == "undefined") opts = {};
40
41         return dojo.date.locale.format(
42             dojo.date.stamp.fromISOString(
43                 s.replace(
44                     /^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[\+-]\d{2})(\d{2})$/,
45                     "$1:$2"
46                 )
47             ), opts
48         );
49     };
50
51     /**
52      * Wrapper for dojo.addOnLoad that verifies a valid login session is active
53      * before adding the function to the onload set
54      */
55     openils.Util.addOnLoad = function(func, noSes) {
56         if(func) {
57             if(!noSes) {
58                 dojo.require('openils.User');
59                 if(!openils.User.authtoken) 
60                     return;
61             }
62             console.log("adding onload " + func.name);
63             dojo.addOnLoad(func);
64         }
65     };
66
67     /**
68      * Returns true if the provided array contains the specified value
69      */
70     openils.Util.arrayContains = function(arr, val) {
71         for(var i = 0; arr && i < arr.length; i++) {
72             if(arr[i] == val)
73                 return true;
74         }
75         return false;
76     };
77
78     /**
79      * Given a HTML select object, returns the currently selected value
80      */
81     openils.Util.selectorValue = function(sel) {
82         if(!sel) return null;
83         var idx = sel.selectedIndex;
84         if(idx < 0) return null;
85         var o = sel.options[idx];
86         var v = o.value; 
87         if(v == null) v = o.innerHTML;
88         return v;
89     }
90
91     /**
92      * Returns the character code of the provided (or current window) event
93      */
94     openils.Util.getCharCode = function(evt) {
95         evt = (evt) ? evt : ((window.event) ? event : null); 
96         if(evt) {
97             return (evt.charCode ? evt.charCode : 
98                 ((evt.which) ? evt.which : evt.keyCode ));
99         } else { return -1; }
100     }
101
102
103     /**
104      * Registers a handler for when the Enter key is pressed while 
105      * the provided DOM node has focus.
106      */
107     openils.Util.registerEnterHandler = function(domNode, func) {
108             if(!(domNode && func)) return;
109             domNode.onkeydown = function(evt) {
110             var code = openils.Util.getCharCode(evt);
111             if(code == 13 || code == 3) 
112                 func();
113         }
114         }
115
116
117     /**
118      * Parses opensrf response objects to see if they contain 
119      * data and/or an ILS event.  This only calls request.recv()
120      * once, so in a streaming context, it's necessary to loop on
121      * this method. 
122      * @param r The OpenSRF Request object
123      * @param eventOK If true, any found events will be returned as responses.  
124      * If false, they will be treated as error conditions and their content will
125      * be alerted if openils.Util.alertEvent is set to true.  Also, if eventOk is
126      * false, the response content will be null when an event is encountered.
127      * @param isList If true, assume the response will be a list of data and
128      * check the 1st item in the list for event-ness instead of the list itself.
129      */
130     openils.Util.alertEvent = true;
131     openils.Util.readResponse = function(r, eventOk, isList) {
132         var msg = r.recv();
133         if(msg == null) return msg;
134         var val = msg.content();
135         var testval = val;
136         if(isList && dojo.isArray(val))
137             testval = val[0];
138         if(e = openils.Event.parse(testval)) {
139             if(eventOk) return e;
140             console.log(e.toString());
141             if(openils.Util.alertEvent)
142                 alert(e);
143             return null;
144         }
145         return val;
146     };
147
148
149     /**
150      * Given a DOM node, adds the provided class to the node 
151      */
152     openils.Util.addCSSClass = function(node, cls) {
153         if(!(node && cls)) return; 
154         var className = node.className;
155
156         if(!className) {
157             node.className = cls;
158             return;
159         }
160
161         var classList = className.split(/\s+/);
162         var newName = '';
163             
164         for (var i = 0; i < classList.length; i++) {
165             if(classList[i] == cls) return;
166             if(classList[i] != null)
167                 newName += classList[i] + " ";
168         }
169
170         newName += cls;
171         node.className = newName;
172     },
173
174     /**
175      * Given a DOM node, removes the provided class from the CSS class 
176      * name list.
177      */
178     openils.Util.removeCSSClass = function(node, cls) {
179         if(!(node && cls && node.className)) return;
180         var classList = node.className.split(/\s+/);
181         var className = '';
182         for(var i = 0; i < classList.length; i++) {
183             if (typeof(cls) == "object") { /* assume regex */
184                 if (!cls.test(classList[i])) {
185                     if(i == 0)
186                         className = classList[i];
187                     else
188                         className += ' ' + classList[i];
189                 }
190             } else {
191                 if (classList[i] != cls) {
192                     if(i == 0)
193                         className = classList[i];
194                     else
195                         className += ' ' + classList[i];
196                 }
197             }
198         }
199         node.className = className;
200     }
201
202     openils.Util.objectSort = function(list, field) {
203         if(dojo.isArray(list)) {
204             if(!field) field = 'id';
205             return list.sort(
206                 function(a, b) {
207                     if(a[field]() > b[field]()) return 1;
208                     return -1;
209                 }
210             );
211         }
212         return [];
213     };
214
215     openils.Util.isTrue = function(val) {
216         return (val && val != '0' && !(val+'').match(/^f$/i));
217     };
218
219     /**
220      * Turns a list into a mapped object.
221      * @param list The list
222      * @param pkey The field to use as the map key 
223      * @param isFunc If true, the map key field is an accessor function 
224      * that will return the value of the map key
225      */
226     openils.Util.mapList = function(list, pkey, isFunc) {
227         if(!(list && pkey)) 
228             return null;
229         var map = {};
230         for(var i in list) {
231             if(isFunc)
232                 map[list[i][pkey]()] = list[i];
233             else
234                 map[list[i][pkey]] = list[i];
235         }
236         return map;
237     };
238
239     /**
240      * Assume a space-separated interval string, with optional comma
241      * E.g. "1 year, 2 days"  "3 days 6 hours"
242      */
243     openils.Util.intervalToSeconds = function(interval) {
244         var d = new Date();
245         var start = d.getTime();
246         var parts = interval.split(' ');
247         for(var i = 0; i < parts.length; i += 2)  {
248             var type = parts[i+1].replace(/s?,?$/,'');
249             switch(type) {
250                 case 'mon': // postgres
251                     type = 'month'; // dojo
252                     break;
253                 // add more as necessary
254             }
255
256             d = dojo.date.add(d, type, Number(parts[i]));
257         }
258         return Number((d.getTime() - start) / 1000);
259     };
260
261     openils.Util.hide = function(node) {
262         if(typeof node == 'string')
263             node = dojo.byId(node);
264         dojo.style(node, 'display', 'none');
265         dojo.style(node, 'visibility', 'hidden');
266     };
267
268     openils.Util.show = function(node, displayType) {
269         if(typeof node == 'string')
270             node = dojo.byId(node);
271         displayType = displayType || 'block';
272         dojo.style(node, 'display', displayType);
273         dojo.style(node, 'visibility', 'visible');
274     };
275
276     /** Toggles the display using show/hide, depending on the current value for CSS 'display' */
277     openils.Util.toggle = function(node, displayType) {
278         if(typeof node == 'string')
279             node = dojo.byId(node);
280         if(dojo.style(node, 'display') == 'none')
281             openils.Util.show(node, displayType);
282         else
283             openils.Util.hide(node);
284     };
285
286     openils.Util.appendClear = function(node, child) {
287         if(typeof node == 'string')
288             node = dojo.byId(node);
289         while(node.childNodes[0])
290             node.removeChild(node.childNodes[0]);
291         node.appendChild(child);
292     };
293
294     /**
295      * Plays a sound file via URL.  Only works with browsers
296      * that support HTML 5 <audio> element.  E.g. Firefox 3.5
297      */
298     openils.Util.playAudioUrl = function(urlString) {
299         if(!urlString) return;
300         var audio = document.createElement('audio');
301         audio.setAttribute('src', urlString);
302         audio.setAttribute('autoplay', 'true');
303         document.body.appendChild(audio);
304         document.body.removeChild(audio);
305     }
306
307     /**
308      * Return the properties of an object as a list. Saves typing.
309      */
310     openils.Util.objectProperties = function(obj) {
311         var K = [];
312         for (var k in obj) K.push(k);
313         return K;
314     }
315
316     openils.Util.uniqueElements = function(L) {
317         var o = {};
318         for (var k in L) o[L[k]] = true;
319         return openils.Util.objectProperties(o);
320     }
321
322 }
323