allowing -'s in barcode
[Evergreen.git] / Evergreen / xul / staff_client / server / patron / ue_ui.js
1 /* -----------------------------------------------------------------------
2         UI code for the user editor.  Handles breaking up the components
3         into a wizard-like interface.
4         ----------------------------------------------------------------------- */
5
6
7 var pages = [ 
8         'uedit_userid', 
9         'uedit_contact_info', 
10         'uedit_addresses', 
11         'uedit_groups', 
12         'uedit_stat_cats', 
13         'uedit_surveys',
14         'uedit_finalize',
15         ];
16
17 /* ID's of objects that should be focused when their page is made visible */
18 var pageFocus = [
19         'ue_barcode',
20         'ue_email',
21         'ue_addr_label_1',
22         'ue_profile',
23         'ue_stat_cat_selector_1',
24         'ue_survey_selector_1',
25         'ue_view_summary'
26 ];
27
28
29 function uEditNext() {
30         var i = _findActive();
31         if( i < (pages.length - 1)) uEditShowPage(pages[i+1]);
32 }
33
34
35 function uEditPrev() {
36         var i = _findActive();
37         if( i > 0 ) uEditShowPage(pages[i-1]);
38 }
39
40 function uEditCheckErrors() {
41         var errors = uEditGetErrorStrings();
42         if(errors) unHideMe($('ue_errors'));
43         else hideMe($('ue_errors'));
44 }
45
46 /*
47 function uEditFetchError(id) { if($(id)) return $(id).innerHTML + "\n"; return "";}
48 */
49
50 function uEditShowPage(id) {
51         if( id == null ) return;
52
53         for( var p in pages ) {
54                 var page = pages[p];
55                 hideMe($(page));
56                 removeCSSClass($(page+'_label'), 'label_active');
57         }
58
59         var idx = _findPageIdx(id);
60
61         unHideMe($(id));
62         addCSSClass($(id+'_label'), 'label_active');
63         var fpage = pageFocus[idx];
64
65         var pnode = $(fpage);
66         if( id == 'uedit_addresses' ) 
67                 pnode = $n( $('ue_address_tbody').
68                         getElementsByTagName('tr')[0], 'ue_addr_label');
69
70         if(pnode) { 
71                 pnode.focus(); 
72                 try{pnode.select()}catch(e){} 
73         }
74
75         unHideMe($('ue_back'));
76         unHideMe($('ue_fwd'));
77
78         if(idx == 0) hideMe($('ue_back'));
79         if(idx == (pages.length-1)) hideMe($('ue_fwd'));
80 }
81
82 function _findActive() {
83         for( var p in pages ) {
84                 if(! $(pages[p]).className.match(/hide_me/) )
85                         return parseInt(p);
86         }
87         return null;
88 }
89
90 function _findPageIdx(name) {
91         for( var i in pages ) {
92                 var page = pages[i];
93                 if( page == name ) return i;
94         }
95         return -1;
96 }
97
98 /* ------------------------------------------------------------------------------ */
99 /* Below are the various UI components built from retrieved data */
100 /* ------------------------------------------------------------------------------ */
101
102
103 /* org selector */
104 function uEditBuildLibSelector( node, depth, selector ) {
105         if(!selector) selector = $('ue_org_selector');
106         if(!node) { depth = 0; node = globalOrgTree; }
107         var opt = insertSelectorVal( 
108                 selector, -1, node.name(), node.id(), null, depth++ );
109         if(!findOrgType(node.ou_type()).can_have_users()) opt.disabled = true; 
110         if( node.id() == USER.ws_ou() ) 
111                 setSelector(selector, node.id());
112
113         for( var c in node.children() ) 
114                 uEditBuildLibSelector(node.children()[c], depth, selector);
115 }
116
117
118 /* group tree selector */
119 function uEditDrawGroups(tree, depth, selector, drawme) {
120         if(!selector) {
121                 selector = $('ue_profile');
122                 depth = 0;
123         }
124         groupsCache[tree.id()] = tree;
125
126         /* if the staff does not have perms to access this group, 
127                 remove it from the tree and don't add it's children */
128         var perm = uEditFindGroupPerm(tree);
129         var org = PERMS[perm];
130         if( org == -1 ) drawme = false;
131
132         if( drawme ) {
133                 var opt = insertSelectorVal( selector, -1, tree.name(), tree.id(), null, depth++ );     
134                 if(!isTrue(tree.usergroup())) opt.disabled = true;
135         }
136
137         for( var c in tree.children() ) 
138                 uEditDrawGroups( tree.children()[c], depth, selector, drawme );
139 }
140
141
142 function uEditFindGroupPerm(group) {
143         if(!group) return null;
144         if( group.application_perm() ) 
145                 return group.application_perm();
146         return uEditFindGroupPerm(groupsCache[group.parent()]);
147 }
148
149
150 /* user identification types */
151 function uEditDrawIDTypes(types) {
152         var pri_sel = $('ue_primary_ident_type');
153         //var sec_sel = $('ue_secondary_ident_type');
154         var idx = 1;
155         for( var t in types ) {
156                 var type = types[t];
157                 if(!type.name()) continue;
158                 identTypesCache[type.id()] = type;
159                 setSelectorVal( pri_sel, idx, type.name(), type.id() );
160                 //setSelectorVal( sec_sel, idx++, type.name(), type.id() );
161                 idx++;
162         }
163 }
164
165 /* user statistical catagories */
166 function uEditDrawStatCats(cats) {
167         var tbody = $('ue_stat_cat_tbody');
168         var templ = tbody.removeChild($('ue_stat_cat_row'));
169
170         for( var c in cats ) {
171                 var row = templ.cloneNode(true);
172                 uEditInsertCat( row, cats[c], c );
173                 tbody.appendChild(row);
174         }
175 }
176
177
178 function uEditInsertCat( row, cat, idx ) {
179
180         cat.entries().sort(  /* sort the entries by value */
181                 function( a, b ) { 
182                         if( !a.value() ) return -1;
183                         if( !b.value() ) return 1;
184                         if( (a.value()+'').toLowerCase() > (b.value()+'').toLowerCase()) return 1;
185                         if( (a.value()+'').toLowerCase() < (b.value()+'').toLowerCase()) return -1;
186                         return 0;
187                 }
188         );
189
190         statCatsCache[cat.id()] = cat;
191
192         /* register the new map object */
193         uEditBuildSCMField(cat, row);
194
195         var newval = $n(row, 'ue_stat_cat_newval');
196         var selector = $n(row, 'ue_stat_cat_selector');
197
198         selector.onchange = function() { 
199                 newval.value = getSelectorVal(selector);
200                 if(newval.onchange) newval.onchange();
201         }
202
203         if( idx == 0 ) selector.id = 'ue_stat_cat_selector_1'; 
204
205         $n(row, 'ue_stat_cat_name').appendChild(text(cat.name()));
206         $n(row, 'ue_stat_cat_owner').appendChild(
207                 text(fetchOrgUnit(cat.owner()).shortname()));
208
209         for( var e in cat.entries() ) {
210                 var entry = cat.entries()[e];
211                 setSelectorVal( selector, 
212                         (parseInt(e)+1), entry.value(), entry.value() );
213         }
214 }
215
216 /* draw the surveys */
217 function uEditDrawSurveys(surveys) {
218
219         var div = $('uedit_surveys');
220         var table = div.removeChild($('ue_survey_table'));
221         if( surveys.length == 0 ) unHideMe($('uedit_no_surveys'));
222
223         for( var s in surveys ) {
224                 var survey = surveys[s];
225                 surveysCache[survey.id()] = survey;
226                 var clone = table.cloneNode(true);
227                 uEditInsertSurvey( div, clone, survey, s );
228                 div.appendChild(clone);
229         }
230 }
231
232 /* insert the servey then insert each of that surveys questions */
233 function uEditInsertSurvey( div, table, survey, sidx ) {
234
235         $n(table, 'ue_survey_name').appendChild(text(survey.name()));
236         $n(table, 'ue_survey_desc').appendChild(text(survey.description()));
237
238         var tbody = $n(table, 'ue_survey_tbody');
239         var templ = tbody.removeChild($n(table, 'ue_survey_row'));
240
241         for( var q in survey.questions() ) {
242                 var row = templ.cloneNode(true);
243                 var quest = survey.questions()[q];
244                 uEditInsertSurveyQuestion( row, survey, quest );
245                 tbody.appendChild(row);
246         }
247 }
248
249 function uEditInsertSurveyQuestion( row, survey, question ) {
250
251         var selector = $n(row, 'ue_survey_answer');
252         row.setAttribute('question', question.id());
253         $n(row, 'ue_survey_question').appendChild(text(question.question()));
254
255         for( var a in question.answers() ) {
256                 var answer = question.answers()[a];
257                 surveyAnswersCache[answer.id()] = answer;
258                 insertSelectorVal(selector, -1, answer.answer(), answer.id() );
259         }
260
261         surveyQuestionsCache[question.id()] = question;
262
263         if( patron.isnew() && isTrue(survey.required()) ) 
264                 addCSSClass(selector, 'invalid_value');
265
266         selector.onchange = function() {
267
268                 /* remove any existing responses for this survey */
269                 patron.survey_responses(
270                         grep( patron.survey_responses(),
271                                 function(item) {
272                                         return (item.survey() != survey.id());
273                                 }
274                         )
275                 );
276
277
278                 if(!patron.survey_responses())
279                         patron.survey_responses([]);
280
281                 var val = getSelectorVal(selector);
282
283                 if( patron.isnew() && isTrue(survey.required()) ) {
284                         if(val)
285                                 removeCSSClass(selector, 'invalid_value');
286                         else 
287                                 addCSSClass(selector, 'invalid_value');
288                         uEditCheckErrors();
289                 }
290
291                 if(!val) return;
292
293                 var resp        = new asvr();
294                 resp.isnew(1);
295                 resp.survey(survey.id());
296                 resp.usr(patron.id());
297                 resp.question(row.getAttribute('question'));
298                 resp.answer(val);
299                 patron.survey_responses().push( resp );
300         }
301 }
302
303
304
305
306
307 /* -----------------------------------------------------------------------
308         Spit out the patron info to the summary display tables...
309         ----------------------------------------------------------------------- */
310
311 function uEditShowSummary() {
312         hideMe($('main_div_container'));
313         unHideMe($('summary_div_container'));
314
315         for( var f in dataFields ) {
316
317                 var field = dataFields[f];
318                 if( field.object == patron ) {
319
320                         var val = uEditNodeVal(field);
321
322                         if(     field.key == 'profile'          ||
323                                         field.key == 'home_ou'          ||
324                                         field.key == 'ident_type'       ||
325                                         field.key == 'ident_type2') {
326
327                                 val = getSelectorName($(field.widget.id));
328                         }
329
330                         var node = $('ue_summary_'+field.key);
331                         if(node) appendClear(node, text(val));
332                 }
333
334                 if( field.object == patron.card() )
335                         appendClear($('ue_summary_barcode'), text(uEditNodeVal(field)));
336
337         }
338
339         var table = $('ue_summary_table');
340         uEditFleshSummaryAddresses( table, patron );
341         uEditFleshSummaryStatCats( table, patron );
342         uEditFleshSummarySurveys( table, patron );
343 }
344
345
346
347 var uEditSummaryAddrRow;
348 function uEditFleshSummaryAddresses( table, patron ) {
349
350         var addrtbody = $n(table, 'ue_summary_addr_tbody');
351         if(!uEditSummaryAddrRow)
352                 uEditSummaryAddrRow = 
353                         addrtbody.removeChild($n(addrtbody, 'ue_summary_addr_row'));
354         var rowtmpl = uEditSummaryAddrRow;
355         removeChildren(addrtbody);
356
357         for( var a in patron.addresses() ) {
358                 var address = patron.addresses()[a];
359                 var row = rowtmpl.cloneNode(true);
360                 uEditFleshSummaryAddr( address, patron, row );
361                 addrtbody.appendChild(row);
362                 if(address.isdeleted()) addCSSClass(row, 'deleted');
363         }
364 }
365
366
367 function uEditFleshSummaryAddr( address, patron, row ) {
368         var yes = $('yes').innerHTML;
369         var no = $('no').innerHTML;
370
371         $n(row, 'label').appendChild(text(address.address_type()));
372         $n(row, 'street1').appendChild(text(address.street1()));
373         $n(row, 'street2').appendChild(text(address.street2()));
374         $n(row, 'city').appendChild(text(address.city()));
375         $n(row, 'county').appendChild(text(address.county()));
376         $n(row, 'state').appendChild(text(address.state()));
377         $n(row, 'country').appendChild(text(address.country()));
378         $n(row, 'zip').appendChild(text(address.post_code()));
379         $n(row, 'valid').appendChild(text( (isTrue(address.valid())) ? yes : no ));
380         $n(row, 'incorporated').appendChild(text( (isTrue(address.within_city_limits())) ? yes : no ));
381
382         var mid = patron.mailing_address();
383         if( typeof patron.mailing_address() == 'object' ) 
384                 mid = patron.mailing_address().id();
385         $n(row, 'mailing').appendChild(text((mid == address.id()) ? yes : no ));
386
387         var bid = patron.billing_address();
388         if( typeof patron.billing_address() == 'object' ) 
389                 bid = patron.billing_address().id();
390         $n(row, 'billing').appendChild(text((bid == address.id()) ? yes : no ));
391 }
392
393
394
395 var uEditSummaryStatCatRow;
396 function uEditFleshSummaryStatCats( table, patron ) {
397         var tbody = $n(table, 'ue_summary_stats_tbody');
398
399         if(!uEditSummaryStatCatRow)
400                 uEditSummaryStatCatRow = 
401                         tbody.removeChild($n(tbody, 'ue_summary_stats_row'));
402         var rowtmpl = uEditSummaryStatCatRow;
403         removeChildren(tbody);
404
405         for( var s in patron.stat_cat_entries() ) {
406                 row = rowtmpl.cloneNode(true);
407                 var entry = patron.stat_cat_entries()[s];
408                 var cat = statCatsCache[entry.stat_cat()];
409                 $n(row, 'ue_summary_stat_name').appendChild(text(cat.name()));
410                 $n(row, 'ue_summary_stat_value').appendChild(text(entry.stat_cat_entry()));
411                 row.setAttribute('statcat', entry.stat_cat());
412                 if( entry.isdeleted() ) addCSSClass(row, 'deleted'); 
413                 tbody.appendChild(row);
414         }
415
416         if( ! getElementsByTagNameFlat( tbody, 'tr' )[0] )
417                 hideMe(tbody.parentNode);
418         else
419                 unHideMe(tbody.parentNode);
420 }
421
422
423
424 var uEditSummarySurveyRow;
425 function uEditFleshSummarySurveys( table, patron ) {
426
427         var tbody       = $n(table, 'ue_summary_survey_tbody');
428         if(!uEditSummarySurveyRow)
429                 uEditSummarySurveyRow = 
430                         tbody.removeChild($n(tbody, 'ue_summary_survey_row'));
431         var rowtmpl = uEditSummarySurveyRow;
432
433         removeChildren(tbody);
434
435         for( var r in patron.survey_responses() ) {
436                 var row         = rowtmpl.cloneNode(true);
437                 var resp                = patron.survey_responses()[r];
438                 var survey      = surveysCache[resp.survey()];
439                 var quest       = surveyQuestionsCache[resp.question()];
440                 var answer      = surveyAnswersCache[resp.answer()];
441                 $n(row, 'ue_summary_survey_name').appendChild(text(survey.name()));
442                 $n(row, 'ue_summary_survey_question').appendChild(text(quest.question()));
443                 $n(row, 'ue_summary_survey_answer').appendChild(text(answer.answer()));
444                 tbody.appendChild(row);
445         }
446
447         if( ! getElementsByTagNameFlat(tbody, 'tr')[0])
448                 hideMe(tbody.parentNode);
449         else
450                 unHideMe(tbody.parentNode);
451 }
452
453
454 function uEditDrawNetLevels(netLevels) {
455         var sel = $('ue_net_level');
456         iterate( netLevels, 
457                 function(i) {
458                         insertSelectorVal( sel, -1, i.name(), i.id() );
459                 }
460         );
461 }
462
463
464
465