]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/xul/staff_client/server/patron/user_editor.js
lots of fixes, data wrangling.
[Evergreen.git] / Open-ILS / xul / staff_client / server / patron / user_editor.js
1
2 var cgi                                                 = null;
3 var patron                                              = null;
4 var advanced                                    = false;
5 var SC_FETCH_ALL                                = 'open-ils.circ:open-ils.circ.stat_cat.actor.retrieve.all';
6 var SC_CREATE_MAP                               = 'open-ils.circ:open-ils.circ.stat_cat.actor.user_map.create';
7 var SV_FETCH_ALL                                = 'open-ils.circ:open-ils.circ.survey.retrieve.all';
8 var FETCH_ID_TYPES                      = 'open-ils.actor:open-ils.actor.user.ident_types.retrieve';
9 var FETCH_GROUPS                                = 'open-ils.actor:open-ils.actor.groups.tree.retrieve';
10 var UPDATE_PATRON                               = 'open-ils.actor:open-ils.actor.patron.update';
11 var identTypes                                  = {};
12 var groupTree                                   = null;
13 var cachedSurveys                               = {};
14 var cachedSurveyQuestions       = {};
15 var cachedSurveyAnswers         = {};
16 var cachedStatCats                      = {};
17 var ERRORS                                              = ""; /* global set of errors */
18
19 var myPerms             = [ 'CREATE_USER', 'UPDATE_USER', 'CREATE_PATRON_STAT_CAT_ENTRY_MAP' ];
20
21 var pages               = [ 
22         'uedit_userid', 
23         'uedit_contact_info', 
24         'uedit_addresses', 
25         'uedit_groups', 
26         'uedit_stat_cats', 
27         'uedit_surveys',
28         'uedit_finalize',
29         ];
30
31 /* ID's of objects that should be focused when their page is made visible */
32 var pageFocus   = [
33         'ue_barcode',
34         'ue_email1',
35         'ue_addr_label_1',
36         'ue_profile',
37         'ue_stat_cat_selector_1',
38         'ue_survey_selector_1',
39         'ue_view_summary'
40 ];
41
42 var regexes             = {};
43 regexes.phone   = /\d{3}-\d{3}-\d{4}/;
44 regexes.email   = /\w+\@\w+\.\w+/;
45 regexes.date    = /^\d{4}-\d{2}-\d{2}/;
46 regexes.isnum   = /^\d+$/;
47
48 /* fetch the necessary data to start off */
49 function uEditInit() {
50
51         cgi             = new CGI();
52         session = cgi.param('ses');
53         if(cgi.param('adv')) advanced = true 
54         if(!session) throw "User session is not defined";
55
56         fetchUser(session);
57         $('uedit_user').appendChild(text(USER.usrname()));
58         uEditShowPage('uedit_userid');
59
60         setTimeout( 
61                 function() { 
62                         fetchHighestPermOrgs( SESSION, USER.id(), myPerms );
63                         uEditDrawUser(fetchFleshedUser(cgi.param('usr')));
64                         uEditBuildLibSelector();
65                         uEditFetchIDTypes();
66                         uEditFetchAddrs();
67                         uEditFetchGroups();
68                         uEditFetchStatCats();
69                         uEditFetchSurveys();
70                 }, 20 
71         );
72 }
73
74 /* UI code ---------------------------------------------------- */
75
76 function uEditNext() {
77         var i = _findActive();
78         if( i < (pages.length - 1)) uEditShowPage(pages[i+1]);
79 }
80
81 function uEditPrev() {
82         var i = _findActive();
83         if( i > 0 ) uEditShowPage(pages[i-1]);
84 }
85
86 function uEditFetchError(id) { if($(id)) return $(id).innerHTML + "\n"; return "";}
87
88 function uEditShowPage(id) {
89         if( id == null ) return;
90
91         for( var p in pages ) {
92                 var page = pages[p];
93                 hideMe($(page));
94                 removeCSSClass($(page+'_label'), 'label_active');
95         }
96
97         unHideMe($(id));
98         addCSSClass($(id+'_label'), 'label_active');
99         var idx = _findPageIdx(id);
100         var fpage = pageFocus[idx];
101         if(fpage) { $(fpage).focus(); try{$(fpage).select()}catch(e){} }
102
103         unHideMe($('ue_back'));
104         unHideMe($('ue_fwd'));
105
106         if(idx == 0) hideMe($('ue_back'));
107         if(idx == (pages.length-1)) hideMe($('ue_fwd'));
108 }
109
110
111 function _findActive() {
112         for( var p in pages ) {
113                 if(! $(pages[p]).className.match(/hide_me/) )
114                         return parseInt(p);
115         }
116         return null;
117 }
118 function _findPageIdx(name) {
119         for( var i in pages ) {
120                 var page = pages[i];
121                 if( page == name ) return i;
122         }
123         return -1;
124 }
125
126 function uEditAddrHighlight( node, type ) {
127         var tbody = $('ue_address_tbody');
128         for( var c in tbody.childNodes ) {
129                 var row = tbody.childNodes[c];
130                 if(row.nodeType != XML_ELEMENT_NODE ) continue;
131                 var div = $n(row,'ue_addr_'+type+'_yes').parentNode;
132                 removeCSSClass(div, 'addr_info_checked');
133         }
134         addCSSClass(node.parentNode, 'addr_info_checked');
135 }
136
137
138 /* ------------------------------------------------------------------------------ */
139 /* Fetch code
140 /* ------------------------------------------------------------------------------ */
141 function uEditFetchIDTypes() {
142         var req = new Request(FETCH_ID_TYPES);
143         req.callback(uEditDrawIDTypes);
144         req.send();
145 }
146
147 function uEditFetchStatCats() {
148         var req = new Request(SC_FETCH_ALL, SESSION);
149         req.callback(uEditDrawStatCats);
150         req.send();
151 }
152
153 function uEditFetchSurveys() {
154         var req = new Request(SV_FETCH_ALL, SESSION);
155         req.callback(uEditDrawSurveys);
156         req.send();
157 }
158
159
160 /* ------------------------------------------------------------------------------ */
161 /* Save the user
162 /* ------------------------------------------------------------------------------ */
163 var uEditExistingStatEntries;
164 var uEditExistingSurveyResponses;
165
166 function uEditSaveUser() {
167         uEditCollectData();
168
169         if(ERRORS) { 
170                 alert(ERRORS); 
171                 ERRORS = ""; 
172                 return;
173         }
174
175         //alert(js2JSON(patron));
176
177         var req = new Request(UPDATE_PATRON, SESSION, patron);
178         req.send(true);
179         var result = req.result();
180         if( checkILSEvent(result) ) alert(js2JSON(result));
181         else alert($('ue_success').innerHTML);
182
183 }
184
185 function uEditCollectData() {
186
187         var card                = null;
188
189         if(patron == null) { 
190                 patron = new au(); 
191                 patron.isnew(1);
192                 patron.id(-1);
193                 card = new ac();
194                 patron.card(-1); /* attach to the virtual id of the card */
195                 patron.cards([card]);
196
197         } else { 
198
199                 /* if this function is called again, patron will exist */
200                 if(!patron.isnew()) { 
201                         patron.ischanged(1); 
202                         patron.isnew(0);
203                         uEditExistingStatEntries = patron.stat_cat_entries();
204                         uEditExistingSurveyResponses = patron.survey_responses();
205                 }
206         }
207
208         patron.stat_cat_entries([]);
209         patron.survey_responses([]);
210
211         uEditFleshCard(card);
212         uEditAddBasicPatronInfo(patron);
213         uEditAddPhones(patron);
214         uEditAddIdents(patron);
215         uEditAddAddresses(patron);
216         uEditAddGroupsAndPerms(patron);
217         uEditReapStatCats(patron);
218         uEditReapSurveys(patron);
219
220 }
221
222
223
224 /* ------------------------------------------------------------------------------ */
225 /* Draw the user
226 /* ------------------------------------------------------------------------------ */
227 function uEditDrawUser(patron) {
228         if(!patron) {
229                 
230         }
231 }
232
233
234
235
236
237 /* ------------------------------------------------------------------------------ */
238 /* Draw the ID types
239 /* ------------------------------------------------------------------------------ */
240 function uEditDrawIDTypes(r) {
241
242         var types = r.getResultObject();
243         var pri_sel = $('ue_primary_ident_type');
244         var sec_sel = $('ue_secondary_ident_type');
245
246         var idx = 1;
247         for( var t in types ) {
248                 var type = types[t];
249                 identTypes[type.id()] = type;
250                 setSelectorVal( pri_sel, idx, type.name(), type.id() );
251                 setSelectorVal( sec_sel, idx++, type.name(), type.id() );
252         }
253 }
254
255
256
257 /* ------------------------------------------------------------------------------ */
258 /* Stat Cat handling code
259 /* ------------------------------------------------------------------------------ */
260 function uEditDrawStatCats(r) {
261         var cats = r.getResultObject();
262         var tbody = $('ue_stat_cat_tbody');
263         var templ = tbody.removeChild($('ue_stat_cat_row'));
264
265         for( var c in cats ) {
266                 var row = templ.cloneNode(true);
267                 uEditInsertCat( tbody, row, cats[c], c );
268                 tbody.appendChild(row);
269         }
270 }
271
272 /* fleshes the stat cat with entries in the dropdown */
273 function uEditInsertCat( tbody, row, cat, idx ) {
274
275         cat.entries().sort(  /* sort the entries by value */
276                 function( a, b ) { 
277                         if( a.value().toLowerCase() > b.value().toLowerCase()) return 1;
278                         if( a.value().toLowerCase() < b.value().toLowerCase()) return -1;
279                         return 0;
280                 }
281         );
282
283         cachedStatCats[cat.id()] = cat;
284
285         row.setAttribute('statcat', cat.id());
286         var newval = $n(row, 'ue_stat_cat_newval');
287         newval.onchange = function(){ 
288                 findParentByNodeName(newval,'tr').setAttribute('changed', '1'); }
289
290         var selector = $n(row, 'ue_stat_cat_selector');
291         selector.onchange = function(){ 
292                 findParentByNodeName(selector, 'tr').setAttribute('changed', '1'); 
293                 newval.value = getSelectorName(selector);
294                 newval.setAttribute('entry', getSelectorVal(selector));
295         }
296
297         if( idx == 0 ) selector.id = 'ue_stat_cat_selector_1'; 
298
299         $n(row, 'ue_stat_cat_name').appendChild(text(cat.name()));
300         $n(row, 'ue_stat_cat_owner').appendChild(
301                 text(fetchOrgUnit(cat.owner()).shortname()));
302
303         var idx = 1;
304         for( var e in cat.entries() ) {
305                 var entry = cat.entries()[e];
306                 setSelectorVal( selector, idx++, entry.value(), entry.id() );
307         }
308 }
309
310 /* finds all the changed/new stat entries and updates the patron object*/
311 function uEditReapStatCats(patron) {
312    var tbody = $('ue_stat_cat_tbody');
313         for( var r in tbody.childNodes ) {
314                 var row = tbody.childNodes[r];
315                 if( !row || row.nodeName != 'tr' ) continue;
316                 if( row.getAttribute('changed') ) {
317                         var val = $n( row, 'ue_stat_cat_newval' );
318                         if(val.value) {
319                                 uEditCreateStatEntry( patron, row.getAttribute('statcat'), 
320                                         val.value, val.getAttribute('entry') );
321                         }
322                 }
323         }
324 }
325
326
327 function uEditCreateStatEntry( patron, catid, newval, entryid ) {
328         var map = new actscecm();
329         map.isnew(1);
330
331         if( ! patron.isnew() ) {
332                 if( grep( uEditExistingStatEntries, 
333                         function(a) { return a.id() == entryid } ) )
334                         map.ischanged(1);
335         }
336
337         map.stat_cat_entry(newval);
338         map.stat_cat(catid);
339         map.target_usr(patron.id());
340         patron.stat_cat_entries().push(map);
341 }
342
343
344
345 /* ------------------------------------------------------------------------------ */
346 /* Survey handling code
347 /* ------------------------------------------------------------------------------ */
348 function uEditDrawSurveys(r) {
349
350         var surveys = r.getResultObject();
351         var div = $('uedit_surveys');
352         var table = div.removeChild($('ue_survey_table'));
353
354         var x = 0;
355         for( var s in surveys ) {
356                 var survey = surveys[s];
357                 cachedSurveys[survey.id()] = survey;
358                 var clone = table.cloneNode(true);
359                 uEditInsertSurvey( div, clone, survey, x++ );
360                 div.appendChild(clone);
361         }
362 }
363
364 function uEditInsertSurvey( div, table, survey, sidx ) {
365         $n(table, 'ue_survey_name').appendChild(text(survey.name()));
366         $n(table, 'ue_survey_desc').appendChild(text(survey.description()));
367         var tbody = $n(table, 'ue_survey_tbody');
368         var templ = tbody.removeChild($n(table, 'ue_survey_row'));
369
370         var polldiv             = $('ue_survey_answer_poll');
371
372         var idx = 1;
373         for( var q in survey.questions() ) {
374                 var row = templ.cloneNode(true);
375                 var quest = survey.questions()[q];
376                 cachedSurveyQuestions[quest.id()] = quest;
377                 uEditInsertSurveyQuestion( div, table, tbody, row, survey, quest, sidx );
378                 tbody.appendChild(row);
379         }
380 }
381
382 function uEditInsertSurveyQuestion( div, table, tbody, row, survey, question, sidx ) {
383
384         $n(row, 'ue_survey_question').appendChild(text(question.question()));
385
386         var selector    = $n(row, 'ue_survey_answer');
387         var polldiv             = $n(row, 'ue_survey_answer_poll');
388         var idx                 = 1;
389         var polltbody   = $n(row, 'ue_survey_answer_poll_tbody');
390         var pollrow             = polltbody.removeChild($n(polltbody, 'ue_survey_answer_poll_row'));
391
392         table.setAttribute('survey', survey.id());
393         row.setAttribute('question', question.id());
394
395         selector.onchange = function() {
396                 row.setAttribute('answer', getSelectorVal(selector));
397                 row.setAttribute('changed', '1');
398         }
399
400         if( sidx == 0 ) selector.id = 'ue_survey_selector_1'; 
401
402         for( var a in question.answers() ) {
403
404                 var answer = question.answers()[a];
405                 cachedSurveyAnswers[answer.id()] = answer;
406
407                 if( survey.poll() ) {
408
409                         unHideMe(polldiv);
410                         var prow = pollrow.cloneNode(true);
411
412
413                         $n(prow, 'ue_survey_answer_poll_answer').appendChild(text(answer.answer()));
414
415
416                         var input = elem('input', { 
417                                         type    : 'radio', 
418                                         name    : 'survey_poll_answer_'+survey.id(),
419                                         id              :  answer.id()
420                                 });
421
422                         input.onchange  = function() {
423                                 row.setAttribute('answer', answer.id());
424                                 row.setAttribute('changed', '1');
425                         }
426
427                         $n(prow, 'ue_survey_answer_poll_radio').appendChild(input);
428                         polltbody.appendChild(prow);
429
430                 } else {
431
432                         unHideMe(selector.parentNode);
433                         setSelectorVal( selector, idx++, answer.answer(), answer.id() );
434                 }
435         }
436 }
437
438
439 function uEditReapSurveys(patron) {
440
441         var div = $('uedit_surveys');
442         var tables = getElementsByTagNameFlat(div, 'table');
443
444         for( var t in tables ) {
445
446                 var table               = tables[t];
447                 var survey              = cachedSurveys[table.getAttribute('survey')];
448                 var tbody               = getElementsByTagNameFlat( table, 'tbody' )[0];
449                 var rows                        = getElementsByTagNameFlat( tbody, 'tr' );
450
451                 for( var r in rows ) {
452                         var row = rows[r];
453                         if(!row.getAttribute('changed')) continue;
454
455                         var resp        = new asvr();
456                         resp.isnew(1);
457                         resp.survey(survey.id());
458                         resp.usr(patron.id());
459                         resp.question(row.getAttribute('question'));
460                         resp.answer(row.getAttribute('answer'));
461                         patron.survey_responses().push( resp );
462                 }
463         }
464 }
465
466
467
468
469
470
471 /* returns true if an error occurred */
472 function uEditSetVal( obj, func, val, regxtype, errtype ) {
473
474         var error = uEditFetchError(errtype);
475         var iserr = false;
476
477         while(1) {
478
479                 if( val == null ) { iserr = true; break; }
480
481                 if(!instanceOf(val, String)) {
482                         try { val = val.value; } catch(e) { return; }
483                 }
484
485                 if(val == "" ) { iserr = true; break; }
486
487                 if(regxtype && regexes[regxtype] 
488                         && !val.match(regexes[regxtype]) ) { iserr = true; break; }
489
490                 try { obj[func](val); } catch(e) {
491                         alert("Error running function: " +func);
492                 }
493
494                 break;
495         }
496
497         if(iserr) { ERRORS += error; return true; }
498         return false;
499 }
500
501
502 function uEditAddBasicPatronInfo(patron) {
503
504
505
506         /* make sure passwords match */
507         var p1 = $('ue_password1').value;
508         var p2 = $('ue_password1').value;
509         if( p1 != p2 || uEditSetVal( patron, "passwd", p1 )) 
510                 ERRORS += uEditFetchError('ue_bad_password');
511
512         uEditSetVal(patron, "usrname", $('ue_username'), null, 'ue_bad_username' );
513         uEditSetVal(patron, "first_given_name", $('ue_firstname'), null, 'ue_bad_firstname' );
514         uEditSetVal(patron, "second_given_name", $('ue_middlename'), null, 'ue_bad_middlename' ); 
515         uEditSetVal(patron, "family_name", $('ue_lastname'), null, 'ue_bad_lastname' ); 
516         uEditSetVal(patron, "dob", $('ue_dob'), 'date', 'ue_bad_dob' );
517
518         patron.suffix($('ue_suffix').value); /* suffis isn't required */
519
520
521         /* make sure emails match */
522         var email       = $('ue_email1').value;
523         var email2      = $('ue_email2').value;
524         if( email != email2 || uEditSetVal(patron, "email", email, 'email' ))
525                 ERRORS += uEditFetchError('ue_bad_email');
526
527         patron.home_ou(getSelectorVal($('ue_org_selector')));
528 }
529
530 function uEditAddPhones(patron) {
531
532
533         /* verifies the phone numbers are formatted correctly */
534         var verify = function(n1, n2, n3) {
535                 var a = n1.value;
536                 var p = n2.value;
537                 var s = n3.value;
538                 if( !a || !p || !s ) return false;
539                 return a + '-' + p + '-' + s;
540         }
541
542
543         var er = 'ue_bad_phone'
544
545         uEditSetVal( patron, "day_phone", 
546                 verify($('ue_day_phone_area'), 
547                 $('ue_day_phone_prefix'), 
548                 $('ue_day_phone_suffix')), 'phone', er );
549
550         uEditSetVal( patron, "evening_phone", 
551                 verify($('ue_night_phone_area'), 
552                 $('ue_night_phone_prefix'), 
553                 $('ue_night_phone_suffix')), 'phone', er );
554
555         uEditSetVal( patron, "other_phone", 
556                 verify($('ue_other_phone_area'), 
557                 $('ue_other_phone_prefix'), 
558                 $('ue_other_phone_suffix')), 'phone', er );
559
560 }
561
562 function uEditFleshCard(card) {
563         if(!card) return "";
564
565         if(uEditSetVal( card, "barcode", $('ue_barcode'), null, 'ue_bad_barcode' ))
566                 return; 
567
568         card.id(-1);
569         card.active(1);
570         return "";
571 }
572
573 function uEditAddIdents(patron) {
574
575         var err = 'ue_no_ident';
576
577         uEditSetVal( patron, "ident_type", 
578                 getSelectorVal($('ue_primary_ident_type')), 'isnum', err );
579
580         uEditSetVal( patron, "ident_type2", 
581                 getSelectorVal($('ue_secondary_ident_type')), 'isnum', err );
582
583         uEditSetVal( patron, "ident_value", 
584                 $('ue_primary_ident'), null, err );
585
586         uEditSetVal( patron, "ident_value2", 
587                 $('ue_secondary_ident'), null, err );
588
589 }
590
591
592 function uEditBuildLibSelector( node, depth, selector ) {
593         if(!selector) selector = $('ue_org_selector');
594         if(!node) { depth = 0; node = globalOrgTree; }
595         
596         var opt = insertSelectorVal( selector, -1, node.name(), node.id(), null, depth++ );
597
598         /* allow these orgs to be selectable via permission? */
599         if(!findOrgType(node.ou_type()).can_have_vols()) opt.disabled = true; 
600
601         if( node.id() == USER.home_ou() ) setSelector(selector, node.id());
602         for( var c in node.children() ) 
603                 uEditBuildLibSelector(node.children()[c], depth, selector);
604 }
605
606 function uEditFetchGroups() {
607         var req = new Request(FETCH_GROUPS);
608         req.callback(uEditDrawGroups);
609         req.send();
610 }
611
612 function uEditDrawGroups(r, tree, depth, selector) {
613
614         if(!tree) {
615                 tree = r.getResultObject();     
616                 depth = 0;
617                 groupTree = tree;
618                 selector = $('ue_profile');
619         }
620
621         insertSelectorVal( selector, -1, tree.name(), tree.id(), null, depth++ );       
622         for( var c in tree.children() ) 
623                 uEditDrawGroups( null, tree.children()[c], depth, selector );
624 }
625
626
627
628 function uEditAddGroupsAndPerms(patron) {
629
630         uEditSetVal( patron, "profile", 
631                 getSelectorVal($('ue_profile')), 'isnum', 'ue_no_profile');
632
633         var expire = $('ue_expire').value;
634         if(expire) 
635                 uEditSetVal( patron, "expire_date", expire, 'date', 'ue_bad_expire' );
636
637         if($('ue_active').checked) patron.active(1);
638         if($('ue_barred').checked) patron.barred(1);
639         if($('ue_group_lead').checked) patron.master_account(1);
640
641         uEditSetVal( patron, "claims_returned_count", 
642                 $('ue_claims_returned'), 'isnum', 'ue_bad_claims_returned');
643
644         if($('ue_alert_message').value) 
645                 uEditSetVal(patron, "alert_message", $('ue_alert_message'));
646 }
647
648
649
650 function uEditAddAddresses(patron) {
651         var tbody = $('ue_address_tbody');      
652         patron.addresses([]);
653
654         /* shove the addresses living in the page into the patron */
655         for( var r in tbody.childNodes ) {
656                 var row = tbody.childNodes[r];
657                 if(!(row && row.nodeName == 'tr')) continue;
658                 patron.addresses().push( uEditBuildAddress( patron, tbody, row ));      
659         }
660 }
661
662 /* extracts a single address from the page */
663 var uEditVirtualAddrId = -1;
664 function uEditBuildAddress( patron, tbody, row ) {
665
666         var addr = new aua();
667         var id = row.getAttribute('exists');
668
669         if(id) {
670                 addr.id(id)
671                 addr.ischanged(1);
672                 addr.isnew(0);
673         } else {
674                 addr.id(uEditVirtualAddrId--);
675                 addr.isnew(1);
676         }
677
678         if($n(row, 'ue_addr_mailing_yes').checked) patron.mailing_address(addr.id());
679         if($n(row, 'ue_addr_billing_yes').checked) patron.billing_address(addr.id());
680         if($n(row, 'ue_addr_valid_yes').checked) addr.valid(1);
681         if($n(row, 'ue_addr_street2').value) addr.street2($n(row, 'ue_addr_street2').value);
682
683         uEditSetVal(addr, "address_type",       $n(row, 'ue_addr_label'),                       null, 'ue_bad_addr_label' );
684         uEditSetVal(addr, "street1",                    $n(row, 'ue_addr_street1'),             null, 'ue_bad_addr_street' );
685         uEditSetVal(addr, "city",                               $n(row, 'ue_addr_city'),                        null, 'ue_bad_addr_city' );
686         uEditSetVal(addr, "county",                     $n(row, 'ue_addr_county'),                      null, 'ue_bad_addr_county' );
687         uEditSetVal(addr, "state",                              $n(row, 'ue_addr_state'),                       null, 'ue_bad_addr_state' );
688         uEditSetVal(addr, "post_code",          $n(row, 'ue_addr_zip'),                         null, 'ue_bad_addr_zip' );
689         uEditSetVal(addr, "country",                    $n(row, 'ue_addr_country'),             null, 'ue_bad_addr_country' );
690
691         return addr;
692 }
693
694
695 var uEditAddrTemplate;
696 var uEditOrigAddrRow;
697 function uEditFetchAddrs() {
698
699         var tbody = $('ue_address_tbody');
700         uEditAddrTemplate = tbody.removeChild($('ue_address_template'));
701
702         $('ue_address_new').onclick = 
703                 function() { 
704                         /* we have to retain the mailing/billing radio input values */
705                         var rows = getElementsByTagNameFlat(tbody,'tr');
706                         var mailrow;
707                         var billrow;
708                         for( var r in rows ) {
709                                 var row = rows[r];
710                                 if($n(row,'ue_addr_mailing_yes').checked) mailrow = row;
711                                 if($n(row,'ue_addr_billing_yes').checked) billrow = row;
712                         }
713                         var newrow = uEditAddrTemplate.cloneNode(true);
714                         tbody.appendChild(newrow); 
715                         $n(newrow, 'ue_addr_label').focus();
716                         if(mailrow) $n(mailrow,'ue_addr_mailing_yes').checked = true;
717                         if(billrow) $n(billrow,'ue_addr_billing_yes').checked = true;
718                 }
719
720         /* go ahead and add a blank addr */
721         if(!patron) {
722                 var row = uEditAddrTemplate.cloneNode(true);
723                 uEditOrigAddrRow = row;
724                 $n( row, 'ue_addr_label').id = 'ue_addr_label_1';
725                 tbody.appendChild(row); 
726                 return;
727         }
728 }
729
730
731 function uEditShowSummary() {
732         uEditCollectData();
733         var table = $('ue_summary_table').cloneNode(true);;
734         uEditFleshSummaryTable(table);
735         var win = window.open("", $('ue_summary_window').innerHTML );   
736         win.document.body.innerHTML = "";
737         win.document.body.appendChild(table);
738 }
739
740 function uEditFleshSummaryTable(table) {
741
742         var yes = $('yes').innerHTML;
743         var no = $('no').innerHTML;
744
745         var identt1 = "";
746         var identt2 = "";
747         var homeorg = "";
748         var profile     = "";
749
750         if( patron.ident_type() != null) 
751                 identt1 = identTypes[patron.ident_type()].name();
752         if( patron.ident_type2() != null ) 
753                 identt2 = identTypes[patron.ident_type2()].name();
754         if( patron.home_ou() != null )
755                 homeorg = findOrgUnit(patron.home_ou()).name();
756         if( patron.profile() != null )
757                 profile = findTreeItemById(groupTree, patron.profile()).name();
758
759
760         $n(table, 'ue_summary_username').appendChild(text(patron.usrname()));
761         $n(table, 'ue_summary_firstname').appendChild(text(patron.first_given_name()));
762         $n(table, 'ue_summary_middlename').appendChild(text(patron.second_given_name()));
763         $n(table, 'ue_summary_lastname').appendChild(text(patron.family_name()));
764         $n(table, 'ue_summary_suffix').appendChild(text(patron.suffix()));
765         $n(table, 'ue_summary_dob').appendChild(text(patron.dob()));
766         $n(table, 'ue_summary_primary_ident_type').appendChild(text(identt1));
767         $n(table, 'ue_summary_primary_ident').appendChild(text(patron.ident_value()));
768         $n(table, 'ue_summary_secondary_ident_type').appendChild(text(identt2));
769         $n(table, 'ue_summary_secondary_ident').appendChild(text(patron.ident_value2()));
770         $n(table, 'ue_summary_email').appendChild(text(patron.email()));
771         $n(table, 'ue_summary_dayphone').appendChild(text(patron.day_phone()));
772         $n(table, 'ue_summary_nightphone').appendChild(text(patron.evening_phone()));
773         $n(table, 'ue_summary_otherphone').appendChild(text(patron.other_phone()));
774         $n(table, 'ue_summary_home_lib').appendChild(text(homeorg));
775         $n(table, 'ue_summary_profile').appendChild(text(profile));
776         $n(table, 'ue_summary_expire').appendChild(text(patron.expire_date()));
777         $n(table, 'ue_summary_family_lead').appendChild(text( (patron.master_account()) ? yes : no ));
778         $n(table, 'ue_summary_claims_returned').appendChild(text(patron.claims_returned_count()));
779         $n(table, 'ue_summary_alert_message').appendChild(text(patron.alert_message()));
780
781         uEditFleshSummaryAddresses( table, patron );
782         uEditFleshSummaryStatCats( table, patron );
783         uEditFleshSummarySurveys( table, patron );
784         uEditFleshSummaryErrors( table );
785
786
787 }
788
789 function uEditFleshSummaryAddresses( table, patron ) {
790
791         var addrtbody = $n(table, 'ue_summary_addr_tbody');
792         var rowtmpl = addrtbody.removeChild($n(addrtbody, 'ue_summary_addr_row'));
793         var yes = $('yes').innerHTML;
794         var no = $('no').innerHTML;
795
796         for( var a in patron.addresses() ) {
797
798                 var address = patron.addresses()[a];
799                 var row = rowtmpl.cloneNode(true);
800
801                 $n(row, 'label').appendChild(text(address.address_type()));
802                 $n(row, 'street1').appendChild(text(address.street1()));
803                 $n(row, 'street2').appendChild(text(address.street2()));
804                 $n(row, 'city').appendChild(text(address.city()));
805                 $n(row, 'county').appendChild(text(address.county()));
806                 $n(row, 'state').appendChild(text(address.state()));
807                 $n(row, 'country').appendChild(text(address.country()));
808                 $n(row, 'zip').appendChild(text(address.post_code()));
809                 $n(row, 'valid').appendChild(text( (address.valid()) ? yes : no ));
810
811                 $n(row, 'mailing').appendChild(text( 
812                         (patron.mailing_address() == address.id()) ? yes : no ));
813
814                 $n(row, 'billing').appendChild(text( 
815                         (patron.billing_address() == address.id()) ? yes : no ));
816
817                 addrtbody.appendChild(row);
818         }
819 }
820
821
822 function uEditFleshSummaryStatCats( table, patron ) {
823         var tbody = $n(table, 'ue_summary_stats_tbody');
824         var rowtmpl = tbody.removeChild($n(tbody, 'ue_summary_stats_row'));
825         for( var s in patron.stat_cat_entries() ) {
826                 unHideMe($n(table, 'ue_summary_stat_cat_td'));
827                 row = rowtmpl.cloneNode(true);
828                 var entry = patron.stat_cat_entries()[s];
829                 var cat = cachedStatCats[entry.stat_cat()];
830                 $n(row, 'ue_summary_stat_name').appendChild(text(cat.name()));
831                 $n(row, 'ue_summary_stat_value').appendChild(text(entry.stat_cat_entry()));
832                 tbody.appendChild(row);
833         }
834 }
835
836
837 function uEditFleshSummarySurveys( table, patron ) {
838         var tbody       = $n(table, 'ue_summary_survey_tbody');
839         var rowtmpl = tbody.removeChild($n(tbody, 'ue_summary_survey_row'));
840         for( var r in patron.survey_responses() ) {
841                 unHideMe($n(table, 'ue_summary_survey_td'));
842                 var row         = rowtmpl.cloneNode(rowtmpl);
843                 var resp                = patron.survey_responses()[r];
844                 var survey      = cachedSurveys[resp.survey()];
845                 var quest       = cachedSurveyQuestions[resp.question()];
846                 var answer      = cachedSurveyAnswers[resp.answer()];
847                 $n(row, 'ue_summary_survey_name').appendChild(text(survey.name()));
848                 $n(row, 'ue_summary_survey_question').appendChild(text(quest.question()));
849                 $n(row, 'ue_summary_survey_answer').appendChild(text(answer.answer()));
850                 tbody.appendChild(row);
851         }
852 }
853
854
855 function uEditFleshSummaryErrors( table ) {
856         if(ERRORS) {
857                 unHideMe($n(table, 'ue_summary_errors_row'));
858                 var errors = ERRORS.replace(/\n/g, "<br/>");
859                 $n(table, 'ue_summary_errors').innerHTML += errors;
860         }
861 }