[open-ils-commits] r1333 - conifer/branches/rel_2_0/xul/server/patron (dbs)

svn at svn.open-ils.org svn at svn.open-ils.org
Tue Apr 12 09:54:05 EDT 2011


Author: dbs
Date: 2011-04-12 09:54:03 -0400 (Tue, 12 Apr 2011)
New Revision: 1333

Removed:
   conifer/branches/rel_2_0/xul/server/patron/ue.xhtml
   conifer/branches/rel_2_0/xul/server/patron/ue_config.js
Modified:
   conifer/branches/rel_2_0/xul/server/patron/summary.js
   conifer/branches/rel_2_0/xul/server/patron/summary_overlay.xul
   conifer/branches/rel_2_0/xul/server/patron/util.js
Log:
Bring Conifer patron XUL into line with 2.0

Eliminate date of birth and net_access display elements


Modified: conifer/branches/rel_2_0/xul/server/patron/summary.js
===================================================================
--- conifer/branches/rel_2_0/xul/server/patron/summary.js	2011-04-12 13:42:03 UTC (rev 1332)
+++ conifer/branches/rel_2_0/xul/server/patron/summary.js	2011-04-12 13:54:03 UTC (rev 1333)
@@ -7,770 +7,989 @@
 if (typeof patron == 'undefined') patron = {};
 patron.summary = function (params) {
 
-	JSAN.use('util.error'); this.error = new util.error();
-	JSAN.use('util.window'); this.window = new util.window();
-	JSAN.use('util.network'); this.network = new util.network();
-	this.w = window;
+    JSAN.use('util.error'); this.error = new util.error();
+    JSAN.use('util.window'); this.window = new util.window();
+    JSAN.use('util.network'); this.network = new util.network();
+    JSAN.use('util.widgets'); JSAN.use('util.date');
+    this.w = window;
 }
 
 patron.summary.prototype = {
 
-	'init' : function( params ) {
+    'init' : function( params ) {
 
-		var obj = this;
+        var obj = this;
 
-		obj.barcode = params['barcode'];
-		obj.id = params['id'];
-		if (params['show_name']) {
-			document.getElementById('patron_name').hidden = false;
-			document.getElementById('patron_name').setAttribute('hidden','false');
-		}
+        obj.barcode = params['barcode'];
+        obj.id = params['id'];
+        if (params['show_name']) {
+            document.getElementById('patron_name').hidden = false;
+            document.getElementById('patron_name').setAttribute('hidden','false');
+        }
 
-		JSAN.use('OpenILS.data'); this.OpenILS = {}; 
-		obj.OpenILS.data = new OpenILS.data(); obj.OpenILS.data.init({'via':'stash'});
+        JSAN.use('OpenILS.data'); this.OpenILS = {}; 
+        obj.OpenILS.data = new OpenILS.data(); obj.OpenILS.data.init({'via':'stash'});
+        var obscure_dob = String( obj.OpenILS.data.hash.aous['circ.obscure_dob'] ) == 'true';
 
-		JSAN.use('util.controller'); obj.controller = new util.controller();
-		obj.controller.init(
-			{
-				control_map : {
-					'cmd_broken' : [
-						['command'],
-						function() { alert($("commonStrings").getString('common.unimplemented')); }
-					],
-					'patron_alert' : [
-						['render'],
-						function(e) {
-							return function() {
-								JSAN.use('util.widgets');
-								util.widgets.remove_children( e );
-								if (obj.patron.alert_message()) {
-									e.appendChild(
-										document.createTextNode(
-											obj.patron.alert_message()
-										)
-									);
-									e.parentNode.hidden = false;
-								} else {
-									e.parentNode.hidden = true;
-								}
-							};
-						}
-					],
-					'patron_usrname' : [
-						['render'],
-						function(e) {
-							return function() {
-								e.setAttribute('value',obj.patron.usrname());
-							};
-						}
-					],
-					'patron_profile' : [
-						['render'],
-						function(e) {
-							return function() { 
-								e.setAttribute('value',
-									obj.OpenILS.data.hash.pgt[
-										obj.patron.profile()
-									].name()
-								);
-							};
-						}
-					],
-					'patron_net_access' : [
-						['render'],
-						function(e) {
-							return function() { 
-								// not applicable to Conifer
-							};
-						}
-					],
-					'patron_standing_penalties' : [
-						['render'],
-						function(e) {
-							return function() {
-								JSAN.use('util.widgets');
-								util.widgets.remove_children(e);
-								var penalties = obj.patron.standing_penalties();
-                                if (penalties.length == 0) {
-									var row = document.createElement('row');
-									var label = document.createElement('label');
-                                    label.setAttribute('value',patronStrings.getString('staff.patron.summary.standing_penalty.none'));
-                                    addCSSClass(label,'NO_PENALTY');
-									row.appendChild(label);
-									e.appendChild(row);
-                                }
-								for (var i = 0; i < penalties.length; i++) {
+        JSAN.use('util.functional'); JSAN.use('patron.util'); JSAN.use('util.list'); 
 
-									var row = document.createElement('row');
-									var label = document.createElement('label');
+        if (document.getElementById('group_list')) {
+            obj.group_list = new util.list('group_list');
+            obj.group_list.init( {
+                'columns' : [
+                    { 'id' : 'gl_family_name', 'flex' : 1, 
+                        'label' : patronStrings.getString('staff.patron.summary.group_list.column.family_name.label'),
+                        'render' : function(my) { return my.family_name; } },
+                    { 'id' : 'gl_first_given_name', 'flex' : 1, 
+                        'label' : patronStrings.getString('staff.patron.summary.group_list.column.first_given_name.label'),
+                        'render' : function(my) { return my.first_given_name; } },
+                    { 'id' : 'gl_second_given_name', 'flex' : 1, 'hidden' : true, 
+                        'label' : patronStrings.getString('staff.patron.summary.group_list.column.second_given_name.label'),
+                        'render' : function(my) { return my.second_given_name; } },
+                    { 'id' : 'gl_home_lib', 'flex' : 1, 'hidden' : true, 
+                        'label' : patronStrings.getString('staff.patron.summary.group_list.column.home_ou.label'),
+                        'render' : function(my) { return obj.OpenILS.data.hash.aou[ my.home_ou ].shortname(); } },
+                    { 'id' : 'gl_balance_owed', 'flex' : 1, 'sort_type' : 'money',
+                        'label' : patronStrings.getString('staff.patron.summary.group_list.column.balance_owed.label'),
+                        'render' : function(my) { return my.balance_owed; } }
+                ],
+                'retrieve_row' : function(params) {
+                    var id = params.retrieve_id;
+                    var blob = patron.util.retrieve_name_via_id( ses(), id );
+                    var row = params.row; if (typeof row.my == 'undefined') { row.my = {}; }
+                    row.my.family_name = blob[0];
+                    row.my.first_given_name = blob[1];
+                    row.my.second_given_name = blob[2];
+                    row.my.home_ou = blob[3];
+                    if (obj.group_owed[ id ]) {
+                        row.my.balance_owed = obj.group_owed[ id ];
+                    }
+                    if (typeof params.on_retrieve == 'function') {
+                        params.on_retrieve(row);
+                    }
+                    return row;
+                }
+            } );
+            $('group_list_actions').appendChild( obj.group_list.render_list_actions() );
+            obj.group_list.set_list_actions();
+        }
 
-									//x.setAttribute('value',penalties[i].penalty_type());
-									label.setAttribute('value',penalties[i].standing_penalty().label());
-									row.appendChild(label);
+        if (document.getElementById('stat_cat_list')) {
+            obj.stat_cat_list = new util.list('stat_cat_list');
+            obj.stat_cat_list.init( {
+                'columns' : [].concat(
+                    obj.stat_cat_list.fm_columns( 'actsc', {
+                        'actsc_id' : { 'hidden' : true },
+                        'actsc_opac_visible' : { 'hidden' : true },
+                        'actsc_usr_summary' : { 'hidden' : true }
+                    } )
+                ).concat(
+                    obj.stat_cat_list.fm_columns( 'actscecm', {
+                        'actscecm_id' : { 'hidden' : true }
+                    } )
+                )
+            } );
+            $('stat_cat_list_actions').appendChild( obj.stat_cat_list.render_list_actions() );
+            obj.stat_cat_list.set_list_actions();
+        }
 
-    								var button = document.createElement('button');
-	    							button.setAttribute('label', patronStrings.getString('staff.patron.summary.standing_penalty.remove'));
-                                    button.setAttribute('image','/xul/server/skin/media/images/icon_delete.gif');
-	    							button.setAttribute('disabled','true');
-	    							button.setAttribute('hidden','true');
-                                    button.setAttribute('retrieve_ausp_id',penalties[i].id());
-		    						row.appendChild(button);
-
-                                    // XXX check a permission here? How to fire the remove action ??? XXX
-                                    if (penalties[i].standing_penalty().id() > 100) {
-	    							    button.setAttribute('disabled','false');
-	    							    button.setAttribute('hidden','false');
-                                        button.addEventListener(
-                                            'command',
-                                            function(ev) {
-                                                try {
-                                                    JSAN.use('util.functional');
-                                                    var id = ev.target.getAttribute('retrieve_ausp_id');
-                                                    var penalty = util.functional.find_list( obj.patron.standing_penalties(), function(o) { return o.id() == id; } );
-                                                    penalty.isdeleted(1);
-
-                                                    var req = obj.network.simple_request( 'FM_AUSP_REMOVE', [ ses(), penalty ] );
-                                                    if (typeof req.ilsevent != 'undefined' || String(req) != '1') {
-                                                        obj.error.standard_unexpected_error_alert(
-                                                            patronStrings.getFormattedString(
-                                                                'staff.patron.standing_penalty.remove_error',
-                                                                [obj.data.hash.csp[id].name()]
-                                                            ),
-                                                            req
-                                                        );
-                                                    }
-                                                    if (typeof xulG.refresh == 'function') { xulG.refresh(); }
-                                                } catch(F) {
-                                                    obj.error.standard_unexpected_error_alert(
-                                                        patronStrings.getFormattedString(
-                                                            'staff.patron.standing_penalty.remove_error',
-                                                            [ev.target.getAttribute('retrieve_ausp_id')]
-                                                        ),
-                                                        F
-                                                    );
-                                                }
-                                            },
-                                            false
-                                        );
+        JSAN.use('util.controller'); obj.controller = new util.controller();
+        obj.controller.init(
+            {
+                control_map : {
+                    'cmd_broken' : [
+                        ['command'],
+                        function() { alert($("commonStrings").getString('common.unimplemented')); }
+                    ],
+                    'radio_address' : [
+                        ['render'],
+                        function(e) {
+                            return function() {
+                                if (e.value == 'physical') { e.selectedIndex = 1; $('address_deck').selectedIndex = 1; }
+                            };
+                        }
+                    ],
+                    'group_tab' : [
+                        ['command'],
+                        function() {
+                            try {
+                                if (! obj.group_frame_loaded) {
+                                    obj.group_frame();
+                                    obj.group_frame_loaded = true;
+                                }
+                            } catch(E) {
+                                alert('Error in summary.js, group_tab: ' + E);
+                            }
+                        }
+                    ],
+                    'stat_cat_tab' : [
+                        ['command'],
+                        function() {
+                            try {
+                                var rows = $('patron_info_rows');
+                                obj.stat_cat_list.clear();
+                                var entries = obj.patron.stat_cat_entries();
+                                for (var i = 0; i < entries.length; i++) {
+                                    var stat_cat = obj.OpenILS.data.hash.my_actsc[ entries[i].stat_cat() ];
+                                    if (!stat_cat) {
+                                        stat_cat = obj.OpenILS.data.lookup('actsc',entries[i].stat_cat());
                                     }
-
-                                    if (penalties[i].standing_penalty().block_list()) {
-                                        if (penalties[i].standing_penalty().block_list().match(/RENEW/)) addCSSClass(label,'PENALTY_RENEW');
-                                        if (penalties[i].standing_penalty().block_list().match(/HOLD/)) addCSSClass(label,'PENALTY_HOLD');
-                                        if (penalties[i].standing_penalty().block_list().match(/CIRC/)) addCSSClass(label,'PENALTY_CIRC');
+                                    if (!stat_cat) { continue; }
+                                    // Every stat cat gets rendered in the Stat Cats tab
+                                    obj.stat_cat_list.append( {
+                                        'row' : {
+                                            'my' : {
+                                                'actsc' : stat_cat,
+                                                'actscecm' : entries[i],
+                                            }
+                                        }
+                                    } );
+                                    // But only a proud few share the Patron Info pane
+                                    if (rows && get_bool( stat_cat.usr_summary() )) {
+                                        var row_id = 'stat_cat_id_' + stat_cat.id();
+                                        var row; var label1; var label2;
+                                        if ($(row_id)) {
+                                            row = $(row_id);
+                                            label1 = row.firstChild;
+                                            label2 = row.lastChild;
+                                        } else {
+                                            row = document.createElement('row');
+                                            row.setAttribute('id',row_id);
+                                            label1 = document.createElement('label');
+                                            label2 = document.createElement('label');
+                                            row.appendChild(label1);
+                                            row.appendChild(label2);
+                                            rows.appendChild(row);
+                                        }
+                                        label1.setAttribute('value',stat_cat.name());
+                                        label1.setAttribute('tooltiptext','stat cat id ' + stat_cat.id());
+                                        label2.setAttribute('value',entries[i].stat_cat_entry());
                                     }
-
-									e.appendChild(row);
-								}
-							};
-						}
-					],
-					'patron_credit' : [
-						['render'],
-						function(e) {
-							return function() { 
-								JSAN.use('util.money');
-								e.setAttribute('value',
-									'$' + 
-									util.money.sanitize(
-										obj.patron.credit_forward_balance()
-									)
-								);
-							};
-						}
-					],
-					'patron_bill' : [
-						['render'],
-						function(e) {
-							return function() { 
-								e.setAttribute('value','...');
+                                }
+                            } catch(E) {
+                                alert('Error in summary.js, stat_cat_tab: ' + E);
+                            }
+                        }
+                    ],
+                    'spawn_group_interface' : [
+                        ['command'],
+                        function() {
+                            try {
+                                window.xulG.spawn_group_interface();
+                            } catch(E) {
+                                alert('Error in summary.js, spawn_group_interface: ' + E);
+                            }
+                        }
+                    ],
+                    'group_tab_retrieve_patron' : [
+                        ['command'],
+                        function() {
+                            var selected_ids = util.functional.map_list(
+                                obj.group_list.retrieve_selection(),
+                                function(o) {
+                                    return o.getAttribute('retrieve_id');
+                                }
+                            );
+                            for (var i = 0; i < selected_ids.length; i++) {
+                                try {
+                                    window.xulG.new_patron_tab(
+                                        { 'tab_name' : patronStrings.getString('staff.patron.info_group.retrieve_patron.tab_name') },
+                                        {
+                                            'id' : selected_ids[i],
+                                            'url_prefix' : xulG.url_prefix,
+                                            'new_tab' : xulG.new_tab,
+                                            'set_tab' : xulG.set_tab
+                                        }
+                                    );
+                                } catch(E) {
+                                    alert('Error in summary.js, group_tab_retrieve_patron: ' + E);
+                                }
+                            }
+                        }
+                    ],
+                    'patron_alert' : [
+                        ['render'],
+                        function(e) {
+                            return function() {
+                                util.widgets.set_text( e, obj.patron.alert_message() || '' );
+                                if (obj.patron.alert_message()) {
+                                    e.parentNode.hidden = false;
+                                } else {
+                                    e.parentNode.hidden = true;
+                                }
+                            };
+                        }
+                    ],
+                    'patron_usrname' : [
+                        ['render'],
+                        function(e) {
+                            return function() {
+                                util.widgets.set_text(e,obj.patron.usrname());
+                            };
+                        }
+                    ],
+                    'patron_profile' : [
+                        ['render'],
+                        function(e) {
+                            return function() { 
+                                util.widgets.set_text(e,
+                                    obj.OpenILS.data.hash.pgt[
+                                        obj.patron.profile()
+                                    ].name()
+                                );
+                            };
+                        }
+                    ],
+                    'patron_net_access' : [
+                        ['render'],
+                        function(e) {
+                            // not applicable to Conifer
+                        }
+                    ],
+                    'patron_credit' : [
+                        ['render'],
+                        function(e) {
+                            return function() { 
+                                JSAN.use('util.money');
+                                util.widgets.set_text(e,
+                                    '$' + 
+                                    util.money.sanitize(
+                                        obj.patron.credit_forward_balance()
+                                    )
+                                );
+                            };
+                        }
+                    ],
+                    'patron_bill' : [
+                        ['render'],
+                        function(e) {
+                            return function() { 
+                                util.widgets.set_text(e,'...');
                                 var under_btn; 
                                 if (xulG) {
                                     if (xulG.display_window) {
                                         under_btn = xulG.display_window.document.getElementById('under_bills');
-                                        if (under_btn) under_btn.setAttribute('value','...');
+                                        if (under_btn) util.widgets.set_text(under_btn,'...');
                                     }
                                 }
-								obj.network.simple_request(
-									'FM_MOUS_RETRIEVE.authoritative',
-									[ ses(), obj.patron.id() ],
-									function(req) {
-										JSAN.use('util.money');
-										var robj = req.getResultObject();
-										e.setAttribute('value', patronStrings.getFormattedString('staff.patron.summary.patron_bill.money', [util.money.sanitize( robj.balance_owed() )]));
-										if (under_btn) under_btn.setAttribute('value', 
-                                            patronStrings.getFormattedString('staff.patron.summary.patron_bill.money', [util.money.sanitize( robj.balance_owed() )]));
-									}
-								);
-								/*
-								obj.network.simple_request(
-									'FM_MBTS_IDS_RETRIEVE_ALL_HAVING_BALANCE.authoritative',
-									[ ses(), obj.patron.id() ],
-									function(req) {
-										JSAN.use('util.money');
-										var list = req.getResultObject();
-										if (typeof list.ilsevent != 'undefined') {
-											e.setAttribute('value', '??? See Bills');
-											return;
-										}
-										var sum = 0;
-										for (var i = 0; i < list.length; i++) {
-											var robj = typeof list[i] == 'object' ? list[i] : obj.network.simple_request('FM_MBTS_RETRIEVE.authoritative',[ses(),list[i]]);
-											sum += util.money.dollars_float_to_cents_integer( robj.balance_owed() );
-										} 
-										if (sum > 0) addCSSClass(document.documentElement,'PATRON_HAS_BILLS');
-										JSAN.use('util.money');
-										e.setAttribute('value', '$' + util.money.sanitize( util.money.cents_as_dollars( sum ) ));
-									}
-								);
-								*/
-							};
-						}
-					],
-					'patron_checkouts' : [
-						['render'],
-						function(e) {
-							return function() { 
-								e.setAttribute('value','...');
-								var e2 = document.getElementById( 'patron_overdue' ); if (e2) e2.setAttribute('value','...');
-								var e3 = document.getElementById( 'patron_claimed_returned' ); if (e3) e3.setAttribute('value','...');
-								var e4 = document.getElementById( 'patron_long_overdue' ); if (e4) e4.setAttribute('value','...');
-								var e5 = document.getElementById( 'patron_lost' ); if (e5) e5.setAttribute('value','...');
-								var e6 = document.getElementById( 'patron_noncat' ); if (e6) e6.setAttribute('value','...');
+                                obj.network.simple_request(
+                                    'BLOB_BALANCE_OWED_VIA_USERGROUP',
+                                    [ ses(), obj.patron.usrgroup() ],
+                                    function(req) {
+                                        try {
+                                            JSAN.use('util.money');
+                                            var robj = req.getResultObject();
+                                            if (typeof robj.ilsevent != 'undefined') { throw(robj); }
+
+                                            var sum = 0; /* in cents */
+                                            obj.group_owed = {};
+
+                                            function render_main_patron_bill_summary(bs) {
+                                                try {
+                                                    util.widgets.set_text(
+                                                        e, 
+                                                        patronStrings.getFormattedString('staff.patron.summary.patron_bill.money', [util.money.sanitize( bs.balance_owed )])
+                                                    );
+                                                    if (under_btn) {
+                                                        util.widgets.set_text(
+                                                            under_btn, 
+                                                            patronStrings.getFormattedString('staff.patron.summary.patron_bill.money', [util.money.sanitize( bs.balance_owed )])
+                                                        );
+                                                    }
+                                                    var show_billing_tab_on_bills = String( obj.OpenILS.data.hash.aous['ui.circ.show_billing_tab_on_bills'] ) == 'true';
+                                                    if (show_billing_tab_on_bills && Number(bs.balance_owed) > 0) {
+                                                        if (xulG) {
+                                                            if (xulG.display_window) {
+                                                                if (! obj.show_billing_tab_on_bills_done_once ) {
+                                                                    xulG.display_window.g.patron.skip_hide_summary = true;
+                                                                    xulG.display_window.util.widgets.dispatch('command','cmd_patron_bills');
+                                                                    obj.show_billing_tab_on_bills_done_once = 1;
+                                                                }
+                                                            }
+                                                        }
+                                                    };
+                                                    obj.bills_summary = bs;
+                                                    if (obj.holds_summary && obj.bills_summary)  {
+                                                        if (typeof window.xulG == 'object' && typeof window.xulG.stop_sign_page == 'function') {
+                                                            window.xulG.stop_sign_page( obj.patron, { 'holds_summary' : obj.holds_summary, 'bills_summary' : obj.bills_summary } ); 
+                                                        }
+                                                    }
+                                                } catch(E) {
+                                                    alert('Error in summary.js, render_main_patron_bill_summary(): ' + E);
+                                                }
+                                            }
+
+                                            var rendered_main_patron_bill_summary = false;
+                                            for (var i = 0; i < robj.length; i++) {
+                                                if (robj[i].usr == obj.patron.id()) {
+                                                    render_main_patron_bill_summary( robj[i] );
+                                                    rendered_main_patron_bill_summary = true;
+                                                } else {
+                                                    sum += util.money.dollars_float_to_cents_integer( robj[i].balance_owed );
+                                                    obj.group_owed[ robj[i].usr ] = robj[i].balance_owed;
+                                                }
+                                            }
+                                            if (!rendered_main_patron_bill_summary) {
+                                                render_main_patron_bill_summary( { balance_owed: 0.00, usr: obj.patron.id() } );
+                                            }
+                                            var tab = $('group_tab');
+                                            if (tab) {
+                                                if (sum > 0) {
+                                                    addCSSClass(tab,'balance_owed');
+                                                } else {
+                                                    removeCSSClass(tab,'balance_owed');
+                                                }
+                                                tab.setAttribute(
+                                                    'label',
+                                                    patronStrings.getFormattedString('staff.patron.summary.tab.group_list_with_total_owed.label',[ util.money.cents_as_dollars( sum ) ])
+                                                );
+                                            }
+                                        } catch(E) {
+                                            alert('Error in summary.js, patron_bill callback: ' + E);
+                                        }
+                                    }
+                                );
+                            };
+                        }
+                    ],
+                    'patron_checkouts' : [
+                        ['render'],
+                        function(e) {
+                            return function() { 
+                                util.widgets.set_text(e,'...');
+                                var e2 = document.getElementById( 'patron_overdue' ); if (e2) util.widgets.set_text(e2,'...');
+                                var e3 = document.getElementById( 'patron_claimed_returned' ); if (e3) util.widgets.set_text(e3,'...');
+                                var e4 = document.getElementById( 'patron_long_overdue' ); if (e4) util.widgets.set_text(e4,'...');
+                                var e5 = document.getElementById( 'patron_lost' ); if (e5) util.widgets.set_text(e5,'...');
+                                var e6 = document.getElementById( 'patron_noncat' ); if (e6) util.widgets.set_text(e6,'...');
                                 var under_btn; 
                                 if (xulG) {
                                     if (xulG.display_window) {
                                         under_btn = xulG.display_window.document.getElementById('under_items');
-                                        if (under_btn) under_btn.setAttribute('value','...');
+                                        if (under_btn) util.widgets.set_text(under_btn,'...');
                                     }
                                 }
-								obj.network.simple_request(
-									'FM_CIRC_COUNT_RETRIEVE_VIA_USER.authoritative',
-									[ ses(), obj.patron.id() ],
-									function(req) {
-										try {
-											var robj = req.getResultObject();
-											e.setAttribute('value', robj.out + robj.overdue + robj.claims_returned + robj.long_overdue );
-											if (e2) e2.setAttribute('value', robj.overdue	);
-											if (e3) e3.setAttribute('value', robj.claims_returned	);
-											if (e4) e4.setAttribute('value', robj.long_overdue	);
-											if (e5) e5.setAttribute('value', robj.lost	);
-                                            if (under_btn) under_btn.setAttribute('value', 
-                                                String( robj.out + robj.overdue + robj.claims_returned + robj.long_overdue) + 
-                                                ( robj.overdue > 0 || robj.claims_returned > 0 || robj.long_overdue > 0 ? '*' : '' )
+                                obj.network.simple_request(
+                                    'FM_CIRC_COUNT_RETRIEVE_VIA_USER.authoritative',
+                                    [ ses(), obj.patron.id() ],
+                                    function(req) {
+                                        try {
+                                            var robj = req.getResultObject();
+                                            var do_not_tally_claims_returned = String( obj.OpenILS.data.hash.aous['circ.do_not_tally_claims_returned'] ) == 'true';
+                                            util.widgets.set_text(e,
+                                                robj.out
+                                                + robj.overdue
+                                                + (do_not_tally_claims_returned ? 0 : robj.claims_returned)
+                                                + robj.long_overdue
                                             );
-										} catch(E) {
-											alert(E);
-										}
-									}
-								);
-								obj.network.simple_request(
-									'FM_ANCC_RETRIEVE_VIA_USER.authoritative',
-									[ ses(), obj.patron.id() ],
-									function(req) {
-										var robj = req.getResultObject();
-										if (e6) e6.setAttribute('value',robj.length);
-									}
-								);
-							};
-						}
-					],
-					'patron_overdue' : [
-						['render'],
-						function(e) {
-							return function() { 
-								/* handled by 'patron_checkouts' */
-							};
-						}
-					],
-					'patron_holds' : [
-						['render'],
-						function(e) {
-							return function() { 
-								e.setAttribute('value','...');
-								var e2 = document.getElementById('patron_holds_available');
-								if (e2) e2.setAttribute('value','...');
+                                            if (e2) util.widgets.set_text(e2, robj.overdue    );
+                                            if (e3) util.widgets.set_text(e3, robj.claims_returned    );
+                                            if (e4) util.widgets.set_text(e4, robj.long_overdue    );
+                                            if (e5) util.widgets.set_text(e5, robj.lost    );
+                                            if (under_btn) util.widgets.set_text(under_btn, 
+                                                String(
+                                                    robj.out
+                                                    + robj.overdue
+                                                    + (do_not_tally_claims_returned ? 0 : robj.claims_returned)
+                                                    + robj.long_overdue
+                                                ) 
+                                                /* + ( robj.overdue > 0 ? '*' : '' ) */
+                                            );
+                                        } catch(E) {
+                                            alert(E);
+                                        }
+                                    }
+                                );
+                                obj.network.simple_request(
+                                    'FM_ANCC_RETRIEVE_VIA_USER.authoritative',
+                                    [ ses(), obj.patron.id() ],
+                                    function(req) {
+                                        var robj = req.getResultObject();
+                                        if (e6) util.widgets.set_text(e6,robj.length);
+                                    }
+                                );
+                            };
+                        }
+                    ],
+                    'patron_overdue' : [
+                        ['render'],
+                        function(e) {
+                            return function() { 
+                                /* handled by 'patron_checkouts' */
+                            };
+                        }
+                    ],
+                    'patron_holds' : [
+                        ['render'],
+                        function(e) {
+                            return function() { 
+                                util.widgets.set_text(e,'...');
+                                var e2 = document.getElementById('patron_holds_available');
+                                if (e2) util.widgets.set_text(e2,'...');
                                 var under_btn; 
                                 if (xulG) {
                                     if (xulG.display_window) {
                                         under_btn = xulG.display_window.document.getElementById('under_holds');
-                                        if (under_btn) under_btn.setAttribute('value','...');
+                                        if (under_btn) util.widgets.set_text(under_btn,'...');
                                     }
                                 }
-								obj.network.simple_request(
-									'FM_AHR_COUNT_RETRIEVE.authoritative',
-									[ ses(), obj.patron.id() ],
-									function(req) {
-										e.setAttribute('value',
-											req.getResultObject().total
-										);
-										if (e2) e2.setAttribute('value',
-											req.getResultObject().ready
-										);
-                                        if (under_btn) under_btn.setAttribute( 'value', req.getResultObject().ready + '/' + req.getResultObject().total );
-									}
-								);
-							};
-						}
-					],
-					'patron_holds_available' : [
-						['render'],
-						function(e) {
-							return function() { 
-								/* handled by 'patron_holds' */
-							};
-						}
-					],
-					'patron_card' : [
-						['render'],
-						function(e) {
-							return function() { 
-								e.setAttribute('value',
-									obj.patron.card().barcode()
-								);
-							};
-						}
-					],
-					'patron_ident_type_1' : [
-						['render'],
-						function(e) {
-							return function() { 
-								var ident_string = '';
-								var ident = obj.OpenILS.data.hash.cit[
-									obj.patron.ident_type()
-								];
-								if (ident) ident_string = ident.name()
-								e.setAttribute('value',
-									ident_string
-								);
-							};
-						}
-					],
-					'patron_ident_value_1' : [
-						['render'],
-						function(e) {
-							return function() { 
-								var val = obj.patron.ident_value();
-								val = val.replace(/.+(\d\d\d\d)$/,'xxxx$1');
-								e.setAttribute('value', val);
-							};
-						}
-					],
-					'patron_ident_type_2' : [
-						['render'],
-						function(e) {
-							return function() { 
-								var ident_string = '';
-								var ident = obj.OpenILS.data.hash.cit[
-									obj.patron.ident_type2()
-								];
-								if (ident) ident_string = ident.name()
-								e.setAttribute('value',
-									ident_string
-								);
-							};
-						}
-					],
-					'patron_ident_value_2' : [
-						['render'],
-						function(e) {
-							return function() { 
-								var val = obj.patron.ident_value2();
-								val = val.replace(/.+(\d\d\d\d)$/,'xxxx$1');
-								e.setAttribute('value', val);
-							};
-						}
-					],
-					'patron_date_of_exp' : [
-						['render'],
-						function(e) {
-							return function() { 
-								e.setAttribute('value',
-									patronStrings.getString('staff.patron.summary.expires_on') + ' ' + (
-										obj.patron.expire_date() ?
-										obj.patron.expire_date().substr(0,10) :
-									    patronStrings.getString('staff.patron.field.unset') 
-									)
-								);
-							};
-						}
-					],
-					'patron_date_of_birth' : [
-						['render'],
-						function(e) {
-							return function() { 
-								// not applicable to Conifer
-							};
-						}
-					],
-					'patron_day_phone' : [
-						['render'],
-						function(e) {
-							return function() { 
-								e.setAttribute('value',
-									obj.patron.day_phone()
-								);
-							};
-						}
-					],
-					'patron_evening_phone' : [
-						['render'],
-						function(e) {
-							return function() { 
-								e.setAttribute('value',
-									obj.patron.evening_phone()
-								);
-							};
-						}
-					],
-					'patron_other_phone' : [
-						['render'],
-						function(e) {
-							return function() { 
-								e.setAttribute('value',
-									obj.patron.other_phone()
-								);
-							};
-						}
-					],
-					'patron_email' : [
-						['render'],
-						function(e) {
-							return function() { 
-								e.setAttribute('value',
-									obj.patron.email()
-								);
-							};
-						}
-					],
-					'patron_alias' : [
-						['render'],
-						function(e) {
-							return function() { 
-								e.setAttribute('value',
-									obj.patron.alias()
-								);
-							};
-						}
-					],
-					'patron_photo_url' : [
-						['render'],
-						function(e) {
-							return function() { 
-								e.setAttribute('src',
-									obj.patron.photo_url()
-								);
-							};
-						}
-					],
-					'patron_library' : [
-						['render'],
-						function(e) {
-							return function() { 
-								e.setAttribute('value',
-									obj.OpenILS.data.hash.aou[
-										obj.patron.home_ou()
-									].shortname()
-								);
-								e.setAttribute('tooltiptext',
-									obj.OpenILS.data.hash.aou[
-										obj.patron.home_ou()
-									].name()
-								);
-							};
-						}
-					],
-					'patron_last_library' : [
-						['render'],
-						function(e) {
-							return function() { 
-								e.setAttribute('value',
-									obj.OpenILS.data.hash.aou[
-										obj.patron.home_ou()
-									].shortname()
-								);
-								e.setAttribute('tooltiptext',
-									obj.OpenILS.data.hash.aou[
-										obj.patron.home_ou()
-									].name()
-								);
-							};
-						}
-					],
-					'patron_mailing_address_street1' : [
-						['render'],
-						function(e) {
-							return function() { 
-								e.setAttribute('value',
-									obj.patron.mailing_address().street1()
-								);
-								if (!get_bool(obj.patron.mailing_address().valid())){e.setAttribute('style','color: red');}
-							};
-						}
-					],
-					'patron_mailing_address_street2' : [
-						['render'],
-						function(e) {
-							return function() { 
-								e.setAttribute('value',
-									obj.patron.mailing_address().street2()
-								);
-								if (!get_bool(obj.patron.mailing_address().valid())){e.setAttribute('style','color: red');}
-							};
-						}
-					],
-					'patron_mailing_address_city' : [
-						['render'],
-						function(e) {
-							return function() { 
-								e.setAttribute('value',
-									obj.patron.mailing_address().city()
-								);
-								if (!get_bool(obj.patron.mailing_address().valid())){e.setAttribute('style','color: red');}
-							};
-						}
-					],
-					'patron_mailing_address_state' : [
-						['render'],
-						function(e) {
-							return function() { 
-								e.setAttribute('value',
-									obj.patron.mailing_address().state()
-								);
-								if (!get_bool(obj.patron.mailing_address().valid())){e.setAttribute('style','color: red');}
-							};
-						}
-					],
-					'patron_mailing_address_post_code' : [
-						['render'],
-						function(e) {
-							return function() { 
-								e.setAttribute('value',
-									obj.patron.mailing_address().post_code()
-								);
-								if (!get_bool(obj.patron.mailing_address().valid())){e.setAttribute('style','color: red');}
-							};
-						}
-					],
-					'patron_physical_address_street1' : [
-						['render'],
-						function(e) {
-							return function() { 
-								e.setAttribute('value',
-									obj.patron.billing_address().street1()
-								);
-								if (!get_bool(obj.patron.billing_address().valid())){e.setAttribute('style','color: red');}
-							};
-						}
-					],
-					'patron_physical_address_street2' : [
-						['render'],
-						function(e) {
-							return function() { 
-								e.setAttribute('value',
-									obj.patron.billing_address().street2()
-								);
-								if (!get_bool(obj.patron.billing_address().valid())){e.setAttribute('style','color: red');}
-							};
-						}
-					],
-					'patron_physical_address_city' : [
-						['render'],
-						function(e) {
-							return function() { 
-								e.setAttribute('value',
-									obj.patron.billing_address().city()
-								);
-								if (!get_bool(obj.patron.billing_address().valid())){e.setAttribute('style','color: red');}
-							};
-						}
-					],
-					'patron_physical_address_state' : [
-						['render'],
-						function(e) {
-							return function() { 
-								e.setAttribute('value',
-									obj.patron.billing_address().state()
-								);
-								if (!get_bool(obj.patron.billing_address().valid())){e.setAttribute('style','color: red');}
-							};
-						}
-					],
-					'patron_physical_address_post_code' : [
-						['render'],
-						function(e) {
-							return function() { 
-								e.setAttribute('value',
-									obj.patron.billing_address().post_code()
-								);
-								if (!get_bool(obj.patron.billing_address().valid())){e.setAttribute('style','color: red');}
-							};
-						}
-					]
-				}
-			}
-		);
+                                obj.network.simple_request(
+                                    'FM_AHR_COUNT_RETRIEVE.authoritative',
+                                    [ ses(), obj.patron.id() ],
+                                    function(req) {
+                                        var robj = req.getResultObject();
+                                        util.widgets.set_text(e,
+                                            robj.total
+                                        );
+                                        if (e2) util.widgets.set_text(e2,
+                                            robj.ready
+                                        );
+                                        if (under_btn) util.widgets.set_text(under_btn, req.getResultObject().ready + '/' + req.getResultObject().total );
+                                        obj.holds_summary = robj;
+                                        if (obj.holds_summary && obj.bills_summary) 
+                                            if (typeof window.xulG == 'object' && typeof window.xulG.stop_sign_page == 'function')
+                                                window.xulG.stop_sign_page( obj.patron, { 'holds_summary' : obj.holds_summary, 'bills_summary' : obj.bills_summary } ); 
+                                    }
+                                );
+                            };
+                        }
+                    ],
+                    'patron_holds_available' : [
+                        ['render'],
+                        function(e) {
+                            return function() { 
+                                /* handled by 'patron_holds' */
+                            };
+                        }
+                    ],
+                    'patron_card' : [
+                        ['render'],
+                        function(e) {
+                            return function() { 
+                                util.widgets.set_text(e,
+                                    obj.patron.card().barcode()
+                                );
+                            };
+                        }
+                    ],
+                    'patron_ident_type_1' : [
+                        ['render'],
+                        function(e) {
+                            return function() { 
+                                var ident_string = '';
+                                var ident = obj.OpenILS.data.hash.cit[
+                                    obj.patron.ident_type()
+                                ];
+                                if (ident) ident_string = ident.name()
+                                util.widgets.set_text(e,
+                                    ident_string
+                                );
+                            };
+                        }
+                    ],
+                    'patron_ident_value_1' : [
+                        ['render'],
+                        function(e) {
+                            return function() { 
+                                var val = obj.patron.ident_value();
+                                if (val) val = val.replace(/.+(\d\d\d\d)$/,'xxxx$1');   // must avoid val.replace if val is NULL
+                                util.widgets.set_text(e, val);
+                            };
+                        }
+                    ],
+                    'patron_ident_type_2' : [
+                        ['render'],
+                        function(e) {
+                            return function() { 
+                                var ident_string = '';
+                                var ident = obj.OpenILS.data.hash.cit[
+                                    obj.patron.ident_type2()
+                                ];
+                                if (ident) ident_string = ident.name()
+                                util.widgets.set_text(e,
+                                    ident_string
+                                );
+                            };
+                        }
+                    ],
+                    'patron_ident_value_2' : [
+                        ['render'],
+                        function(e) {
+                            return function() { 
+                                var val = obj.patron.ident_value2();
+                                if (val) val = val.replace(/.+(\d\d\d\d)$/,'xxxx$1');   // must avoid val.replace if val is NULL
+                                util.widgets.set_text(e, val);
+                            };
+                        }
+                    ],
+                    'patron_date_of_exp' : [
+                        ['render'],
+                        function(e) {
+                            return function() { 
+                                util.widgets.set_text(e,
+                                    patronStrings.getString('staff.patron.summary.expires_on') + ' ' + (
+                                        obj.patron.expire_date() ?
+                                        util.date.formatted_date( obj.patron.expire_date(), '%{localized_date}' ) :
+                                        patronStrings.getString('staff.patron.field.unset') 
+                                    )
+                                );
+                            };
+                        }
+                    ],
+                    'patron_hold_alias' : [
+                        ['render'],
+                        function(e) {
+                            return function() {
+                                util.widgets.set_text(e,
+                                    obj.patron.alias() ? obj.patron.alias() : ''
+                                );
+                            }
+                        }
+                    ],
+                    'patron_date_of_birth' : [
+                        ['render'],
+                        function(e) {
+                            // not applicable to Conifer
+                        }
+                    ],
+                    'patron_day_phone' : [
+                        ['render'],
+                        function(e) {
+                            return function() { 
+                                util.widgets.set_text(e,
+                                    obj.patron.day_phone()
+                                );
+                            };
+                        }
+                    ],
+                    'patron_evening_phone' : [
+                        ['render'],
+                        function(e) {
+                            return function() { 
+                                util.widgets.set_text(e,
+                                    obj.patron.evening_phone()
+                                );
+                            };
+                        }
+                    ],
+                    'patron_other_phone' : [
+                        ['render'],
+                        function(e) {
+                            return function() { 
+                                util.widgets.set_text(e,
+                                    obj.patron.other_phone()
+                                );
+                            };
+                        }
+                    ],
+                    'patron_email' : [
+                        ['render'],
+                        function(e) {
+                            return function() { 
+                                util.widgets.set_text(e,
+                                    obj.patron.email()
+                                );
+                            };
+                        }
+                    ],
+                    'patron_alias' : [
+                        ['render'],
+                        function(e) {
+                            return function() { 
+                                util.widgets.set_text(e,
+                                    obj.patron.alias()
+                                );
+                            };
+                        }
+                    ],
+                    'patron_photo_url' : [
+                        ['render'],
+                        function(e) {
+                            return function() { 
+                                e.setAttribute('src',
+                                    obj.patron.photo_url()
+                                );
+                            };
+                        }
+                    ],
+                    'patron_library' : [
+                        ['render'],
+                        function(e) {
+                            return function() { 
+                                util.widgets.set_text(e,
+                                    obj.OpenILS.data.hash.aou[
+                                        obj.patron.home_ou()
+                                    ].shortname()
+                                );
+                                e.setAttribute('tooltiptext',
+                                    obj.OpenILS.data.hash.aou[
+                                        obj.patron.home_ou()
+                                    ].name()
+                                );
+                            };
+                        }
+                    ],
+                    'patron_last_library' : [
+                        ['render'],
+                        function(e) {
+                            return function() { 
+                                util.widgets.set_text(e,
+                                    obj.OpenILS.data.hash.aou[
+                                        obj.patron.home_ou()
+                                    ].shortname()
+                                );
+                                e.setAttribute('tooltiptext',
+                                    obj.OpenILS.data.hash.aou[
+                                        obj.patron.home_ou()
+                                    ].name()
+                                );
+                            };
+                        }
+                    ],
+                    'patron_mailing_address_street1' : [
+                        ['render'],
+                        function(e) {
+                            return function() { 
+                                if (obj.patron.mailing_address()) {
+                                    util.widgets.set_text(e,
+                                        obj.patron.mailing_address().street1()
+                                    );
+                                    if (!get_bool(obj.patron.mailing_address().valid())){e.setAttribute('style','color: red');}
+                                } else {
+                                    util.widgets.set_text(e,'');
+                                }
+                            };
+                        }
+                    ],
+                    'patron_mailing_address_street2' : [
+                        ['render'],
+                        function(e) {
+                            return function() { 
+                                if (obj.patron.mailing_address()) {
+                                    util.widgets.set_text(e,
+                                        obj.patron.mailing_address().street2()
+                                    );
+                                    if (!get_bool(obj.patron.mailing_address().valid())){e.setAttribute('style','color: red');}
+                                } else {
+                                    util.widgets.set_text(e,'');
+                                }
+                            };
+                        }
+                    ],
+                    'patron_mailing_address_city' : [
+                        ['render'],
+                        function(e) {
+                            return function() { 
+                                if (obj.patron.mailing_address()) {
+                                    util.widgets.set_text(e,
+                                        obj.patron.mailing_address().city()
+                                    );
+                                    if (!get_bool(obj.patron.mailing_address().valid())){e.setAttribute('style','color: red');}
+                                } else {
+                                    util.widgets.set_text(e,'');
+                                }
+                            };
+                        }
+                    ],
+                    'patron_mailing_address_state' : [
+                        ['render'],
+                        function(e) {
+                            return function() { 
+                                if (obj.patron.mailing_address()) {
+                                    util.widgets.set_text(e,
+                                        obj.patron.mailing_address().state()
+                                    );
+                                    if (!get_bool(obj.patron.mailing_address().valid())){e.setAttribute('style','color: red');}
+                                } else {
+                                    util.widgets.set_text(e,'');
+                                }
+                            };
+                        }
+                    ],
+                    'patron_mailing_address_post_code' : [
+                        ['render'],
+                        function(e) {
+                            return function() { 
+                                if (obj.patron.mailing_address()) {
+                                    util.widgets.set_text(e,
+                                        obj.patron.mailing_address().post_code()
+                                    );
+                                    if (!get_bool(obj.patron.mailing_address().valid())){e.setAttribute('style','color: red');}
+                                } else {
+                                    util.widgets.set_text(e,'');
+                                }
+                            };
+                        }
+                    ],
+                    'patron_physical_address_street1' : [
+                        ['render'],
+                        function(e) {
+                            return function() { 
+                                if (obj.patron.billing_address()) {
+                                    util.widgets.set_text(e,
+                                        obj.patron.billing_address().street1()
+                                    );
+                                    if (!get_bool(obj.patron.billing_address().valid())){e.setAttribute('style','color: red');}
+                                } else {
+                                    util.widgets.set_text(e,'');
+                                }
+                            };
+                        }
+                    ],
+                    'patron_physical_address_street2' : [
+                        ['render'],
+                        function(e) {
+                            return function() {
+                                if (obj.patron.billing_address()) { 
+                                    util.widgets.set_text(e,
+                                        obj.patron.billing_address().street2()
+                                    );
+                                    if (!get_bool(obj.patron.billing_address().valid())){e.setAttribute('style','color: red');}
+                                } else {
+                                    util.widgets.set_text(e,'');
+                                }
+                            };
+                        }
+                    ],
+                    'patron_physical_address_city' : [
+                        ['render'],
+                        function(e) {
+                            return function() {
+                                if (obj.patron.billing_address()) { 
+                                    util.widgets.set_text(e,
+                                        obj.patron.billing_address().city()
+                                    );
+                                    if (!get_bool(obj.patron.billing_address().valid())){e.setAttribute('style','color: red');}
+                                } else {
+                                    util.widgets.set_text(e,'');
+                                }
+                            };
+                        }
+                    ],
+                    'patron_physical_address_state' : [
+                        ['render'],
+                        function(e) {
+                            return function() {
+                                if (obj.patron.billing_address()) { 
+                                    util.widgets.set_text(e,
+                                        obj.patron.billing_address().state()
+                                    );
+                                    if (!get_bool(obj.patron.billing_address().valid())){e.setAttribute('style','color: red');}
+                                } else {
+                                    util.widgets.set_text(e,'');
+                                }
+                            };
+                        }
+                    ],
+                    'patron_physical_address_post_code' : [
+                        ['render'],
+                        function(e) {
+                            return function() {
+                                if (obj.patron.billing_address()) { 
+                                    util.widgets.set_text(e,
+                                        obj.patron.billing_address().post_code()
+                                    );
+                                    if (!get_bool(obj.patron.billing_address().valid())){e.setAttribute('style','color: red');}
+                                } else {
+                                    util.widgets.set_text(e,'');
+                                }
+                            };
+                        }
+                    ]
+                }
+            }
+        );
 
-		obj.retrieve();
+        obj.retrieve();
 
-		try {
-			var caption = document.getElementById("PatronSummaryContact_caption");
-			var arrow = document.getAnonymousNodes(caption)[0];
-			var gb_content = document.getAnonymousNodes(caption.parentNode)[1];
-			arrow.addEventListener(
-				'click',
-				function() {
-					setTimeout(
-						function() {
-							//alert('setting shrink_state to ' + gb_content.hidden);
-							//caption.setAttribute('shrink_state',gb_content.hidden);
-							netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
-							JSAN.use('util.file'); var file = new util.file('patron_id_shrink');
-							file.set_object(String(gb_content.hidden)); file.close();
-						}, 0
-					);
-				}, false
-			);
-			//var shrink_state = caption.getAttribute('shrink_state');
-			var shrink_state = false;
-			netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
-			JSAN.use('util.file'); var file = new util.file('patron_id_shrink');
-			if (file._file.exists()) {
-				shrink_state = file.get_object(); file.close();
-			}
-			//alert('shrink_state retrieved as ' + shrink_state);
-			if (shrink_state != 'false' && shrink_state) {
-				JSAN.use('util.widgets');
-				//alert('clicking the widget');
-				util.widgets.click( arrow );
-			}
-		} catch(E) {
-			obj.error.sdump('D_ERROR','with shrink_state in summary.js: ' + E);
-		}
-	},
+        try {
+            var caption = document.getElementById("PatronSummaryContact_caption");
+            var arrow = document.getAnonymousNodes(caption)[0];
+            var gb_content = document.getAnonymousNodes(caption.parentNode)[1];
+            arrow.addEventListener(
+                'click',
+                function() {
+                    setTimeout(
+                        function() {
+                            //alert('setting shrink_state to ' + gb_content.hidden);
+                            //caption.setAttribute('shrink_state',gb_content.hidden);
+                            netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
+                            JSAN.use('util.file'); var file = new util.file('patron_id_shrink');
+                            file.set_object(String(gb_content.hidden)); file.close();
+                        }, 0
+                    );
+                }, false
+            );
+            //var shrink_state = caption.getAttribute('shrink_state');
+            var shrink_state = false;
+            netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
+            JSAN.use('util.file'); var file = new util.file('patron_id_shrink');
+            if (file._file.exists()) {
+                shrink_state = file.get_object(); file.close();
+            }
+            //alert('shrink_state retrieved as ' + shrink_state);
+            if (shrink_state != 'false' && shrink_state) {
+                //alert('clicking the widget');
+                util.widgets.click( arrow );
+            }
+        } catch(E) {
+            obj.error.sdump('D_ERROR','with shrink_state in summary.js: ' + E);
+        }
+    },
 
-	'retrieve' : function() {
+    'retrieve' : function() {
 
-		try {
+        try {
 
-			var obj = this;
+            var obj = this;
 
-			var chain = [];
+            var chain = [];
 
-			// Retrieve the patron
-				function blah_retrieve() {
-					try {
-						var robj;
-						if (obj.barcode && obj.barcode != 'null') {
-							robj = obj.network.simple_request(
-								'FM_AU_RETRIEVE_VIA_BARCODE.authoritative',
-								[ ses(), obj.barcode ]
-							);
-						} else if (obj.id && obj.id != 'null') {
-							robj = obj.network.simple_request(
-								'FM_AU_FLESHED_RETRIEVE_VIA_ID.authoritative',
-								[ ses(), obj.id ]
-							);
-						} else {
-							throw(patronStrings.getString('staff.patron.summary.retrieve.no_barcode'));
-						}
-						if (robj) {
+            // Retrieve the patron
+                function blah_retrieve() {
+                    try {
+                        var robj;
+                        if (obj.barcode && obj.barcode != 'null') {
+                            robj = obj.network.simple_request(
+                                'FM_AU_RETRIEVE_VIA_BARCODE.authoritative',
+                                [ ses(), obj.barcode ]
+                            );
+                        } else if (obj.id && obj.id != 'null') {
+                            robj = obj.network.simple_request(
+                                'FM_AU_FLESHED_RETRIEVE_VIA_ID',
+                                [ ses(), obj.id ]
+                            );
+                        } else {
+                            throw(patronStrings.getString('staff.patron.summary.retrieve.no_barcode'));
+                        }
+                        if (robj) {
 
-							if (instanceOf(robj,au)) {
+                            if (instanceOf(robj,au)) {
 
-								obj.patron = robj;
-								JSAN.use('patron.util');
-								document.getElementById('patron_name').setAttribute('value',
-									( obj.patron.prefix() ? obj.patron.prefix() + ' ' : '') + 
-									obj.patron.family_name() + ', ' + 
-									obj.patron.first_given_name() + ' ' +
-									( obj.patron.second_given_name() ? obj.patron.second_given_name() + ' ' : '' ) +
-									( obj.patron.suffix() ? obj.patron.suffix() : '')
-								);
-								patron.util.set_penalty_css(obj.patron);
-								JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
-								data.last_patron = obj.patron.id(); data.stash('last_patron');
+                                obj.patron = robj;
+                                JSAN.use('patron.util');
+                                util.widgets.set_text('patron_name',
+                                    patron.util.format_name( obj.patron )
+                                );
+                                patron.util.set_penalty_css(obj.patron);
+                                JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
+                                data.last_patron = obj.patron.id(); data.stash('last_patron');
 
-							} else {
+                            } else {
 
-								throw(robj);
+                                throw(robj);
 
-							}
-						} else {
+                            }
+                        } else {
 
-							throw(robj);
+                            throw(robj);
 
-						}
+                        }
 
-					} catch(E) {
-						throw(E);
-					}
-				};
-				blah_retrieve();
+                    } catch(E) {
+                        throw(E);
+                    }
+                };
+                blah_retrieve();
 
-			/*
-			// Retrieve the survey responses for required surveys
-			chain.push(
-				function() {
-					try {
-						var surveys = obj.OpenILS.data.list.my_asv;
-						var survey_responses = {};
-						for (var i = 0; i < surveys.length; i++) {
-							var s = obj.network.request(
-								api.FM_ASVR_RETRIEVE.app,
-								api.FM_ASVR_RETRIEVE.method,
-								[ ses(), surveys[i].id(), obj.patron.id() ]
-							);
-							survey_responses[ surveys[i].id() ] = s;
-						}
-						obj.patron.survey_responses( survey_responses );
-					} catch(E) {
-						var error = ('patron.summary.retrieve : ' + js2JSON(E));
-						obj.error.sdump('D_ERROR',error);
-						throw(error);
-					}
-				}
-			);
-			*/
+            /*
+            // Retrieve the survey responses for required surveys
+            chain.push(
+                function() {
+                    try {
+                        var surveys = obj.OpenILS.data.list.my_asv;
+                        var survey_responses = {};
+                        for (var i = 0; i < surveys.length; i++) {
+                            var s = obj.network.request(
+                                api.FM_ASVR_RETRIEVE.app,
+                                api.FM_ASVR_RETRIEVE.method,
+                                [ ses(), surveys[i].id(), obj.patron.id() ]
+                            );
+                            survey_responses[ surveys[i].id() ] = s;
+                        }
+                        obj.patron.survey_responses( survey_responses );
+                    } catch(E) {
+                        var error = ('patron.summary.retrieve : ' + js2JSON(E));
+                        obj.error.sdump('D_ERROR',error);
+                        throw(error);
+                    }
+                }
+            );
+            */
 
-			// Update the screen
-			chain.push( function() { obj.controller.render(); } );
+            // Update the screen
+            chain.push( function() {
+                obj.controller.render();
+                if ($('stat_cat_tab')) {
+                    util.widgets.dispatch('command','stat_cat_tab'); 
+                }
+            } );
 
-			// On Complete
+            // On Complete
 
-			chain.push( function() {
+            chain.push( function() {
 
-				if (typeof window.xulG == 'object' && typeof window.xulG.on_finished == 'function') {
-					obj.error.sdump('D_PATRON_SUMMARY',
-						'patron.summary: Calling external .on_finished()\n');
-					window.xulG.on_finished(obj.patron);
-				} else {
-					obj.error.sdump('D_PATRON_SUMMARY','patron.summary: No external .on_finished()\n');
-				}
+                if (typeof window.xulG == 'object' && typeof window.xulG.on_finished == 'function') {
+                    obj.error.sdump('D_PATRON_SUMMARY',
+                        'patron.summary: Calling external .on_finished()\n');
+                    window.xulG.on_finished(obj.patron);
+                } else {
+                    obj.error.sdump('D_PATRON_SUMMARY','patron.summary: No external .on_finished()\n');
+                }
 
-			} );
+            } );
 
-			// Do it
-			JSAN.use('util.exec'); obj.exec = new util.exec();
-			obj.exec.on_error = function(E) {
+            // Do it
+            JSAN.use('util.exec'); obj.exec = new util.exec();
+            obj.exec.on_error = function(E) {
 
-				if (typeof window.xulG == 'object' && typeof window.xulG.on_error == 'function') {
-					window.xulG.on_error(E);
-				} else {
-					alert(js2JSON(E));
-				}
+                if (typeof window.xulG == 'object' && typeof window.xulG.on_error == 'function') {
+                    window.xulG.on_error(E);
+                } else {
+                    alert(js2JSON(E));
+                }
 
-			}
-			this.exec.chain( chain );
+            }
+            this.exec.chain( chain );
 
-		} catch(E) {
-			if (typeof window.xulG == 'object' && typeof window.xulG.on_error == 'function') {
-				window.xulG.on_error(E);
-			} else {
-				alert(js2JSON(E));
-			}
-		}
-	}
+        } catch(E) {
+            if (typeof window.xulG == 'object' && typeof window.xulG.on_error == 'function') {
+                window.xulG.on_error(E);
+            } else {
+                alert(js2JSON(E));
+            }
+        }
+    },
+
+    'group_frame' : function() {
+        var obj = this;
+        try {
+            obj.group_list.clear();
+
+            var robj = obj.network.simple_request(
+                'FM_AU_LIST_RETRIEVE_VIA_GROUP.authoritative',
+                [ ses(), obj.patron.usrgroup() ]
+            );
+            if ((robj == null) || (typeof robj.ilsevent != 'undefined') ) throw(robj);
+            var ids = util.functional.filter_list( robj, function(o) { return o != obj.patron.id(); });
+            var funcs = [];
+
+                function gen_func(r) {
+                    return function() {
+                        obj.group_list.append( { 'retrieve_id' : r, 'row' : {} } );
+                    }
+                }
+
+            //funcs.push( gen_func(obj.patron.id()) );
+            for (var i = 0; i < ids.length; i++) {
+                funcs.push( gen_func(ids[i]) );
+            }
+            JSAN.use('util.exec'); var exec = new util.exec(4);
+            exec.chain( funcs );
+        } catch(E) {
+            alert('Error in summary.js, group_frame(): ' + E);
+        }
+    }
 }
 
 dump('exiting patron.summary.js\n');

Modified: conifer/branches/rel_2_0/xul/server/patron/summary_overlay.xul
===================================================================
--- conifer/branches/rel_2_0/xul/server/patron/summary_overlay.xul	2011-04-12 13:42:03 UTC (rev 1332)
+++ conifer/branches/rel_2_0/xul/server/patron/summary_overlay.xul	2011-04-12 13:54:03 UTC (rev 1333)
@@ -1,221 +1,231 @@
 <?xml version="1.0"?>
 <!DOCTYPE overlay PUBLIC "" ""[
-	<!--#include virtual="/opac/locale/${locale}/lang.dtd"-->
+    <!--#include virtual="/opac/locale/${locale}/lang.dtd"-->
 ]>
 <overlay id="patron_summary_overlay" 
-	xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+    xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
 <script>dump('loading patron/summary_overlay.xul\n');</script>
 
 <commandset id="patron_summary_cmds" />
 
 <box id="patron_summary_main" flex="1" orient="vertical" class="my_overflow">
-	<vbox id="patron_info_sidebar" />
+    <vbox id="patron_info_sidebar" />
 </box>
 
 <vbox id="patron_info_sidebar" flex="1">
-	<label id="patron_name" hidden="true" class="patronNameLarge"/>
-	<groupbox id="PatronSummaryAlert_groupbox" flex="0" hidden="true" class="alert">
-		<caption id="psagbc" label="&staff.patron.summary_overlay.psagbc.alert.label;" class="shrinkable_groupbox"/>
-		<description id="patron_alert"/>
-	</groupbox>
-	<groupbox id="PatronSummaryStanding_groupbox" flex="0" class="standing">
-		<caption id="pssgbc" label="&staff.patron.summary_overlay.pssgbc.standing.label;" class="shrinkable_groupbox"/>
-        <vbox id="pssgbvb">
-            <grid><columns><column/><column/></columns>
-                <rows id="patron_standing_penalties"/>
-            </grid>
-        </vbox>
-        <spacer/>
-	</groupbox>
-	<groupbox id="PatronSummaryStatus_groupbox" flex="0" class="status"/>
-	<!--
-	<groupbox id="PatronSummarySurvey_groupbox" flex="0">
-		<caption id="pdsgbc" label="Surveys" class="shrinkable_groupbox"/>
-		<vbox id="patron_surveys" />
-	</groupbox>
-	-->
-	<groupbox id="PatronSummaryContact_groupbox" flex="0" class="contact"/>
+    <description id="patron_name" hidden="true" class="copyable patronNameLarge"/>
+    <groupbox id="PatronSummaryAlert_groupbox" flex="0" hidden="true" class="alert">
+        <caption id="psagbc" label="&staff.patron.summary_overlay.psagbc.alert.label;" class="shrinkable_groupbox"/>
+        <description id="patron_alert"/>
+    </groupbox>
+    <groupbox id="PatronSummaryStatus_groupbox" flex="0" class="status"/>
+    <!--
+    <groupbox id="PatronSummarySurvey_groupbox" flex="0">
+        <caption id="pdsgbc" label="Surveys" class="shrinkable_groupbox"/>
+        <vbox id="patron_surveys" />
+    </groupbox>
+    -->
+    <groupbox id="PatronSummaryContact_groupbox" flex="0" class="contact"/>
 </vbox>
 
 <groupbox id="PatronSummaryStatus_groupbox" orient="vertical">
-	<caption label="&staff.patron_display.status.caption;" class="shrinkable_groupbox" />
-	<grid style="border: solid thin"><columns><column/></columns><rows>
-		<row hidden="true">
-			<label id="patron_standing" />
-		</row>
-		<row id="pdsgr1">
-			<label id="patron_profile" class="profile value"/>
-		</row>
-		<row id="pdsgr5">
-			<label id="patron_library" class="homelib value"/>
-		</row>
-		<row id="pdsgr5aa">
-			<label id="patron_date_of_exp" class="expire_date value"/>
-		</row>
-	</rows></grid>
-	<grid id="PatronSummaryStatus_grid" flex="1"/>
+    <caption label="&staff.patron_display.status.caption;" class="shrinkable_groupbox" />
+    <grid style="border: solid thin"><columns><column/></columns><rows>
+        <row hidden="true">
+            <description id="patron_standing" />
+        </row>
+        <row id="pdsgr1">
+            <description id="patron_profile" class="copyable profile value"/>
+        </row>
+        <row id="pdsgr5">
+            <description id="patron_library" class="copyable homelib value"/>
+        </row>
+        <row id="pdsgr5aa">
+            <description id="patron_date_of_exp" class="copyable expire_date value"/>
+        </row>
+    </rows></grid>
+    <grid id="PatronSummaryStatus_grid" flex="1"/>
 
 </groupbox>
 
 <grid id="PatronSummaryStatus_grid">
-	<columns id="pdsgc">
-		<column id="pdsgc1" />
-		<column id="pdsgc2" />
-		<column id="pdsgc3" />
-		<column id="pdsgc4" />
-	</columns>
-	<rows id="pdsgr" flex="1">
-		<row id="pdsgr4">
-			<label id="PatronSummaryStatus_holds_label" class="text_left holds label"
-				value="&staff.patron_display.holds.label;" />
-			<label id="patron_holds" class="holds value"/>
-		</row><row>
-			<label id="PatronSummaryStatus_holds_available_label" class="text_right holds_ready label"
-				value="&staff.patron_display.holds_available.label;"  style="background: grey"/>
-			<label id="patron_holds_available" class="holds_ready label" style="background: grey"/>
-		</row>
-		<row id="pdsgr2" class="hide_patron_credit" hidden="true">
-			<label id="PatronSummaryStatus_credit_label" class="text_left credit label"
-				value="&staff.patron_display.credit.label;" />
-			<label id="patron_credit" class="credit value"/>
-		</row><row>
-			<label id="PatronSummaryStatus_bills_label" class="text_left bill label"
-				value="&staff.patron_display.bills.label;" />
-			<label id="patron_bill" class="bill value"/>
-		</row>
-		<row id="pdsgr3">
-			<label id="PatronSummaryStatus_checkouts_label" class="text_left items_out label"
-				value="&staff.patron_display.checkouts.label;" />
-			<label id="patron_checkouts" class="items_out value"/>
-		</row>
-		<row>
-			<label id="PatronSummaryStatus_checkouts_overdue_label" class="text_right items_overdue label"
-				value="&staff.patron_display.checkouts_overdue.label;" style="background: grey"/>
-			<label id="patron_overdue" class="items_overdue value" style="background: grey"/>
-		</row>
-		<row id="pdsgr5">
-			<label id="PatronSummaryStatus_long_overdue_label" value="&staff.patron.summary_overlay.overdue.value;" class="text_right items_long_overdue label" style="background: grey"/>
-			<label id="patron_long_overdue" class="items_long_overdue value" style="background: grey"/>
-		</row>
-		<row id="pdsgr7">
-			<label id="PatronSummaryStatus_claimed_returned_label" value="&staff.patron.summary_overlay.claimed_returned.value;" class="text_right items_long_overdue label" style="background: grey"/>
-			<label id="patron_claimed_returned" class="items_claimed_returned value" style="background: grey"/>
-		</row>
-		<row id="pdsgr6">
-			<label id="PatronSummaryStatus_lost_label" value="&staff.patron.summary_overlay.lost_label.value;" class="text_left items_lost label"/>
-			<label id="patron_lost" class="items_lost value"/>
-		</row>
-		<row id="pdsgr6a">
-			<label id="PatronSummaryStatus_noncat_label" value="&staff.patron.summary_overlay.noncat_label.value;" class="text_left items_noncat label"/>
-			<label id="patron_noncat" class="items_noncat value"/>
-		</row>
-	</rows>
+    <columns id="pdsgc">
+        <column id="pdsgc1" />
+        <column id="pdsgc2" />
+        <column id="pdsgc3" />
+        <column id="pdsgc4" />
+    </columns>
+    <rows id="pdsgr" flex="1">
+        <row id="pdsgr4">
+            <label id="PatronSummaryStatus_holds_label" class="copyable text_left holds label"
+                value="&staff.patron_display.holds.label;" />
+            <description id="patron_holds" class="copyable holds value"/>
+        </row><row>
+            <label id="PatronSummaryStatus_holds_available_label" class="copyable text_right holds_ready label subgroup"
+                value="&staff.patron_display.holds_available.label;"  />
+            <description id="patron_holds_available" class="copyable holds_ready value subgroup" />
+        </row>
+        <row id="pdsgr2" class="hide_patron_credit" hidden="true">
+            <label id="PatronSummaryStatus_credit_label" class="copyable text_left credit label"
+                value="&staff.patron_display.credit.label;" />
+            <description id="patron_credit" class="copyable credit value"/>
+        </row><row>
+            <label id="PatronSummaryStatus_bills_label" class="copyable text_left bill label"
+                value="&staff.patron_display.bills.label;" />
+            <description id="patron_bill" class="copyable bill value"/>
+        </row>
+        <row id="pdsgr3">
+            <label id="PatronSummaryStatus_checkouts_label" class="copyable text_left items_out label"
+                value="&staff.patron_display.checkouts.label;" />
+            <description id="patron_checkouts" class="copyable items_out value"/>
+        </row>
+        <row>
+            <label id="PatronSummaryStatus_checkouts_overdue_label" class="copyable text_right items_overdue label subgroup"
+                value="&staff.patron_display.checkouts_overdue.label;" />
+            <description id="patron_overdue" class="copyable items_overdue value subgroup" />
+        </row>
+        <row id="pdsgr5">
+            <label id="PatronSummaryStatus_long_overdue_label" value="&staff.patron.summary_overlay.overdue.value;" class="copyable text_right items_long_overdue label subgroup" />
+            <description id="patron_long_overdue" class="copyable items_long_overdue value subgroup" />
+        </row>
+        <row id="pdsgr7">
+            <label id="PatronSummaryStatus_claimed_returned_label" value="&staff.patron.summary_overlay.claimed_returned.value;" class="copyable text_right items_long_overdue label subgroup" />
+            <description id="patron_claimed_returned" class="copyable items_claimed_returned value subgroup" />
+        </row>
+        <row id="pdsgr6">
+            <label id="PatronSummaryStatus_lost_label" value="&staff.patron.summary_overlay.lost_label.value;" class="copyable text_left items_lost label"/>
+            <description id="patron_lost" class="copyable items_lost value"/>
+        </row>
+        <row id="pdsgr6a">
+            <label id="PatronSummaryStatus_noncat_label" value="&staff.patron.summary_overlay.noncat_label.value;" class="copyable text_left items_noncat label"/>
+            <description id="patron_noncat" class="copyable items_noncat value"/>
+        </row>
+    </rows>
 </grid>
 
 <groupbox id="PatronSummaryContact_groupbox" orient="vertical">
-	<!--
-	<caption label="&staff.patron_display.contact.caption;"/>
-	-->
-	<caption id="PatronSummaryContact_caption" label="&staff.patron.summary_overlay.summary_contact.label;" class="shrinkable_groupbox" />
-	<hbox id="pdcgbhb1">
-		<grid id="PatronSummaryContact_grid" />
-		<spacer id="pdcgbhbs1" flex="1"/>
-		<image id="patron_photo_url" />
-	</hbox>
-	<grid id="PatronSummaryContact_grid_phone" />
-	<groupbox id="PatronSummaryContact_mailing_address" class="mailing_address"/>
-	<groupbox id="PatronSummaryContact_physical_address" class="physical_address"/>
+    <!--
+    <caption label="&staff.patron_display.contact.caption;"/>
+    -->
+    <caption id="PatronSummaryContact_caption" label="&staff.patron.summary_overlay.summary_contact.label;" class="shrinkable_groupbox" />
+    <hbox id="pdcgbhb1">
+        <grid id="PatronSummaryContact_grid" />
+        <spacer id="pdcgbhbs1" flex="1"/>
+        <image id="patron_photo_url" />
+    </hbox>
+    <grid id="PatronSummaryContact_grid_phone" />
+    <groupbox id="PatronSummaryContact_mailing_address" class="mailing_address"/>
+    <groupbox id="PatronSummaryContact_physical_address" class="physical_address"/>
 </groupbox>
 
 <grid id="PatronSummaryContact_grid">
-	<columns id="pdsgc">
-		<column id="pdsgc1" />
-		<column id="pdsgc2" />
-	</columns>
-	<rows id="pdsgr" flex="1">
-		<row id="pdsgr0">
-			<label id="PatronSummaryContact_library_card_label" class="text_left card label"
-				value="&staff.patron_display.library_card.label;"/>
-			<label id="patron_card" class="card value click_link" onclick="try { copy_to_clipboard(event); } catch(E) { alert(E); }"/>
-		</row>
-		<row id="pdsgr1">
-			<label id="PatronSummaryContact_ident_label" class="text_left"
-				value="&staff.patron_display.ident1.label;"/>
-			<vbox id="pdsgr0h">
-				<label id="patron_ident_type_1" class="ident ident_type ident1 value"/>
-				<label id="patron_ident_value_1" class="ident ident_value ident1 value"/>
-			</vbox>
-		</row>
-		<row id="pdsgr2">
-			<label id="PatronSummaryContact_ident_label2" class="text_left"
-				value="&staff.patron_display.ident2.label;"/>
-			<vbox id="pdsgr0ah">
-				<label id="patron_ident_type_2" class="ident ident_type ident2 value"/>
-				<label id="patron_ident_value_2" class="ident ident_value ident2 value"/>
-			</vbox>
-		</row>
-		<row id="pdsgr4"><label id="pdsgr4l" value=" "/></row>
-	</rows>
+    <columns id="pdsgc">
+        <column id="pdsgc1" />
+        <column id="pdsgc2" />
+    </columns>
+    <rows id="pdsgr" flex="1">
+        <row id="pdsgr0">
+            <label id="PatronSummaryContact_library_card_label" class="copyable text_left card label"
+                value="&staff.patron_display.library_card.label;"/>
+            <description id="patron_card" class="copyable card value click_link" onclick="try { copy_to_clipboard(event); } catch(E) { alert(E); }"/>
+        </row>
+        <row id="pdsgr1">
+            <label id="PatronSummaryContact_ident_label" class="copyable text_left"
+                value="&staff.patron_display.ident1.label;"/>
+            <vbox id="pdsgr0h">
+                <description id="patron_ident_type_1" class="copyable ident ident_type ident1 value"/>
+                <description id="patron_ident_value_1" class="copyable ident ident_value ident1 value"/>
+            </vbox>
+        </row>
+        <row id="pdsgr2">
+            <label id="PatronSummaryContact_ident_label2" class="copyable text_left"
+                value="&staff.patron_display.ident2.label;"/>
+            <vbox id="pdsgr0ah">
+                <description id="patron_ident_type_2" class="copyable ident ident_type ident2 value"/>
+                <description id="patron_ident_value_2" class="copyable ident ident_value ident2 value"/>
+            </vbox>
+        </row>
+        <row>
+            <label id="PatronSummaryContact_hold_alias_label" class="copyable text_left" value="&staff.patron_display.hold_alias.label;"/>
+            <description id="patron_hold_alias" class="copyable hold_alias value" />
+        </row>
+        <row id="pdsgr4"><label id="pdsgr4l" value=" "/></row>
+    </rows>
 </grid>
 
 <grid id="PatronSummaryContact_grid_phone">
-	<columns id="pdcgpc">
-		<column id="pdcgpc1" />
-		<column id="pdcgpc2" />
-	</columns>
-	<rows id="pdcgpr" flex="1">
-		<row id="pdcgpr1">
-			<label id="PatronSummaryContact_day_phone_label" class="text_left phone label day_phone"
-				value="&staff.patron_display.day_phone.label;" />
-			<label id="patron_day_phone" class="phone value day_phone"/> 
-		</row>
-		<row id="pdcgpr2">
-			<label id="PatronSummaryContact_evening_phone_label" class="text_left phone label evening_phone"
-				value="&staff.patron_display.evening_phone.label;" />
-			<label id="patron_evening_phone" class="phone value evening_phone"/>
-		</row>
-		<row id="pdcgpr3">
-			<label id="PatronSummaryContact_other_phone_label" class="text_left phone label other_phone"
-				value="&staff.patron_display.other_phone.label;" />
-			<label id="patron_other_phone" class="phone value other_phone"/> 
-		</row>
-		<row id="pdsgpr4"><label id="pdsgpr4l" value=" "/></row>
-		<row id="pdsgpr4a">
-			<label id="PatronSummaryContact_usrname_label" class="text_left usrname label"
-				value="&staff.patron.summary_overlay.opac_login.value;" />
-			<label id="patron_usrname" class="usrname value"/>
-		</row>
-		<row id="pdcgpr5">
-			<label id="PatronSummaryContact_email_label" class="text_left email label"
-				value="&staff.patron_display.email.label;" />
-			<label id="patron_email" class="email value" style="text-decoration: underline; color: blue; -moz-user-focus: normal;" onclick="copy_to_clipboard(event)"/>
-		</row>
-		<row id="pdsgpr6"><label id="pdsgpr6l" value=" "/></row>
+    <columns id="pdcgpc">
+        <column id="pdcgpc1" />
+        <column id="pdcgpc2" />
+    </columns>
+    <rows id="pdcgpr" flex="1">
+        <row id="pdcgpr1">
+            <label id="PatronSummaryContact_day_phone_label" class="copyable text_left phone label day_phone"
+                value="&staff.patron_display.day_phone.label;" />
+            <description id="patron_day_phone" class="copyable phone value day_phone"/> 
+        </row>
+        <row id="pdcgpr2">
+            <label id="PatronSummaryContact_evening_phone_label" class="copyable text_left phone label evening_phone"
+                value="&staff.patron_display.evening_phone.label;" />
+            <description id="patron_evening_phone" class="copyable phone value evening_phone"/>
+        </row>
+        <row id="pdcgpr3">
+            <label id="PatronSummaryContact_other_phone_label" class="copyable text_left phone label other_phone"
+                value="&staff.patron_display.other_phone.label;" />
+            <description id="patron_other_phone" class="copyable phone value other_phone"/> 
+        </row>
+        <row id="pdsgpr4"><label id="pdsgpr4l" value=" "/></row>
+        <row id="pdsgpr4a">
+            <label id="PatronSummaryContact_usrname_label" class="copyable text_left usrname label"
+                value="&staff.patron.summary_overlay.opac_login.value;" />
+            <description id="patron_usrname" class="copyable usrname value"/>
+        </row>
+        <row id="pdcgpr5">
+            <label id="PatronSummaryContact_email_label" class="copyable text_left email label"
+                value="&staff.patron_display.email.label;" />
+            <description id="patron_email" class="copyable email value" style="text-decoration: underline; color: blue; -moz-user-focus: normal;" onclick="copy_to_clipboard(event)"/>
+        </row>
+        <row id="pdsgpr6"><label id="pdsgpr6l" value=" "/></row>
 
-	</rows>
+    </rows>
 </grid>
 
+<popupset id="patron_summary_popups">
+    <popup id="addr_export_popup" oncommand="export_address(event);">
+        <menuitem id="addr_export_copy" label="&staff.patron_display.address_export_popup.copy;"/>
+        <menuitem id="addr_export_print" label="&staff.patron_display.address_export_popup.print;"/>
+    </popup>
+</popupset>
+
 <groupbox id="PatronSummaryContact_mailing_address" orient="vertical">
-	<caption id="pdcmac" label="&staff.patron_display.mailing_address;" class="shrinkable_groupbox"/>
-	<label id="patron_mailing_address_street1" tooltiptext="&staff.patron_display.mailing.street1.label;" class="address street street1 mailing"/>
-	<label id="patron_mailing_address_street2" tooltiptext="&staff.patron_display.mailing.street2.label;" class="address street street2 mailing"/>
-	<hbox id="pdcmah">
-		<label id="patron_mailing_address_city" tooltiptext="&staff.patron_display.mailing.city.label;" class="address city mailing"/>
-		<label id="patron_mailing_address_state" tooltiptext="&staff.patron_display.mailing.state.label;" class="address state mailing"/>
-		<label id="patron_mailing_address_post_code" tooltiptext="&staff.patron_display.mailing.post_code.label;" class="address post_code mailing"/>
-	</hbox>
+    <caption id="pdcmac" label="&staff.patron_display.mailing_address;" class="shrinkable_groupbox"/>
+    <description id="patron_mailing_address_street1" tooltiptext="&staff.patron_display.mailing.street1.label;" class="copyable address street street1 mailing value"/>
+    <description id="patron_mailing_address_street2" tooltiptext="&staff.patron_display.mailing.street2.label;" class="copyable address street street2 mailing value"/>
+    <hbox id="pdcmah">
+        <description id="patron_mailing_address_city" tooltiptext="&staff.patron_display.mailing.city.label;" class="copyable address city mailing value"/>
+        <description id="patron_mailing_address_state" tooltiptext="&staff.patron_display.mailing.state.label;" class="copyable address state mailing value"/>
+        <description id="patron_mailing_address_post_code" tooltiptext="&staff.patron_display.mailing.post_code.label;" class="copyable address post_code mailing value"/>
+    </hbox>
+    <hbox>
+        <spacer flex="1" />
+        <label id="addr_export_mailing" value="&staff.patron_display.address_export;" popup="addr_export_popup" class="copyable click_link"/>
+    </hbox>
 </groupbox>
 
 <groupbox id="PatronSummaryContact_physical_address" orient="vertical">
-	<caption id="pdcpac" label="&staff.patron_display.physical_address;" class="shrinkable_groupbox"/>
-	<label id="patron_physical_address_street1" tooltiptext="&staff.patron_display.physical.street1.label;" class="address street street1 physical" />
-	<label id="patron_physical_address_street2" tooltiptext="&staff.patron_display.physical.street2.label;"  class="address street street2 physical"/>
-	<hbox id="pdcpah">
-		<label id="patron_physical_address_city" tooltiptext="&staff.patron_display.physical.city.label;" class="address city physical"/>
-		<label id="patron_physical_address_state" tooltiptext="&staff.patron_display.physical.state.label;" class="address state physical"/>
-		<label id="patron_physical_address_post_code" tooltiptext="&staff.patron_display.physical.post_code.label;" class="address post_code physical"/>
-	</hbox>
+    <caption id="pdcpac" label="&staff.patron_display.physical_address;" class="shrinkable_groupbox"/>
+    <description id="patron_physical_address_street1" tooltiptext="&staff.patron_display.physical.street1.label;" class="copyable address street street1 physical value" />
+    <description id="patron_physical_address_street2" tooltiptext="&staff.patron_display.physical.street2.label;"  class="copyable address street street2 physical value"/>
+    <hbox id="pdcpah">
+        <description id="patron_physical_address_city" tooltiptext="&staff.patron_display.physical.city.label;" class="copyable address city physical value"/>
+        <description id="patron_physical_address_state" tooltiptext="&staff.patron_display.physical.state.label;" class="copyable address state physical value"/>
+        <description id="patron_physical_address_post_code" tooltiptext="&staff.patron_display.physical.post_code.label;" class="copyable address post_code physical value"/>
+    </hbox>
+    <hbox>
+        <spacer flex="1" />
+        <label id="addr_export_physical" value="&staff.patron_display.address_export;" popup="addr_export_popup" class="copyable click_link"/>
+    </hbox>
 </groupbox>
 
 </overlay>

Deleted: conifer/branches/rel_2_0/xul/server/patron/ue.xhtml
===================================================================
--- conifer/branches/rel_2_0/xul/server/patron/ue.xhtml	2011-04-12 13:42:03 UTC (rev 1332)
+++ conifer/branches/rel_2_0/xul/server/patron/ue.xhtml	2011-04-12 13:54:03 UTC (rev 1333)
@@ -1,923 +0,0 @@
-<?xml version='1.0' encoding="UTF-8"?>
-
-<!DOCTYPE html PUBLIC 
-	"-//W3C//DTD XHTML 1.0 Transitional//EN" 
-	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" [
-	<!--#include virtual="/opac/locale/${locale}/lang.dtd"-->
-	<!ENTITY nbsp " "> <!-- calendar needs this entity -->
-]>
-
-<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xi="http://www.w3.org/2001/XInclude">
-
-	<head>
-		<title>&ev.staff.patron.ue_xhtml.ev_user_editor.label;</title>
-		<script language='javascript' src='/opac/common/js/utils.js'> </script>
-		<script language='javascript' src='/opac/common/js//config.js'> </script> 
-		<script language='javascript' src='/opac/common/js/CGI.js'> </script>
-	
-		<script language='javascript' src='/opac/common/js/JSON_v1.js'> </script>
-		<script language='javascript' src='/opac/common/js/fmall.js'> </script>
-		<script language='javascript' src='/opac/common/js/fmgen.js'> </script>
-		<script language='javascript' src='/opac/common/js/Cookies.js'> </script>
-		<script language='javascript' src='/opac/common/js/opac_utils.js'> </script>
-		<script language='javascript' src='/opac/common/js/<!--#echo var="locale"-->/OrgTree.js'> </script>
-		<script language='javascript' src='/opac/common/js/org_utils.js'> </script>
-		<script language='javascript' src='/opac/common/js/init.js'> </script>
-		<script language='javascript' src='/opac/common/js/RemoteRequest.js'> </script>
-
-
-
-		<!--
-		<script language='javascript' src='/opac/common/js/date.js'> </script>
-		-->
-		<script language='javascript' src='../admin/adminlib.js'> </script>
-		<script language='javascript' src='ue_config.js'> </script>
-		<script language='javascript' src='ue_ui.js'> </script>
-		<script language='javascript' src='ue.js'> </script>
-		<link type='text/css' rel='stylesheet' href='../admin/admin.css'/>
-  
-		<link rel="stylesheet" type="text/css" media="all" 
-			href="/opac/common/js/jscalendar/calendar-brown.css" title="win2k-cold-1" />
-		<script type="text/javascript" src="/opac/common/js/jscalendar/calendar.js"></script>
-		<script type="text/javascript" src="/opac/common/js/jscalendar/lang/calendar-en.js"></script>
-		<script type="text/javascript" src="/opac/common/js/jscalendar/calendar-setup.js"></script>
-
-
-		<style type='text/css'>
-			.messagecatalog { -moz-binding: url( /xul/server/main/bindings.xml#messagecatalog ) }
-			.main_table { width: 98%; border-collapse: collapse;}
-			.main_table td { border: 1px solid #E0F0E0; text-align: center; padding: 4px;}
-			#uedit_nav_bar { border: 2px solid #E0F0E0; padding: 6px;}
-			.nav_link { padding-left: 90px; padding-right: 90px; }
-			.main_nav_link { -moz-border-radius: 7px; height: 13%;}
-			/*
-			.main_div { height: 480px; padding-left: 15px; 
-				text-align: center; vertical-align: middle; overflow: auto;}
-				*/
-
-			.main_div { min-height: 450px; padding-left: 15px; 
-				text-align: center; vertical-align: middle; }
-
-			.nav_link_table { height: 480px;}
-			.label_active { background: #E0F0E0; }
-			.right { text-align: right; padding-right: 3px;}
-			.left { text-align: left; padding-left: 3px;}
-			.wide { width: 98%;}
-			.pad { padding-left: 3px; padding-right: 3px; }
-			.no_border td { border: none; }
-			.uedit_table { width: 80% }
-			.address_table { -moz-border-radius: 4px; border: 4px solid #E0E0F0; padding: 4px; }
-			.shared_address { background : #E0F0F0; }
-			.address_table td { border: none; width: auto; padding: 1px; }
-			.addr_info_checked { -moz-border-radius: 6px; background: #F0E0E0; }
-			.button_row { width: 95%; text-align: center; margin-top: 7px; border: 1px solid #E0E0E0; }
-			/*.required_field { background: #F0E0E0; }*/
-			.invalid_value { background: red; }
-
-			/* all text inputs that don't have the .invalid_value 
-				class applied and are currently focused */
-			input:focus:not(.invalid_value) { background: #E0F0E0; color: darkblue;}
-
-			.deleted { background: #FF6666; }
-
-			.dup_link { padding-left: 5px; color: red; }
-
-
-		</style>
-	</head>
-	
-	<div class="messagecatalog" id="patronStrings" src="/xul/server/locale/<!--#echo var='locale'-->/patron.properties" />
-
-	<body onload='uEditInit();'>
-
-	<center>
-
-		<h2>&ev.staff.patron.ue_xhtml.ev_user_editor.label;</h2>
-
-		<div style='position:absolute; top: 5px; right: 5px;'>
-			<span>&ev.staff.patron.ue_xhtml.welcome.label;</span><b><span id='uedit_user'/></b>
-		</div>
-
-		<hr/><br/>
-
-		<div id='main_div_container'>
-
-		<table style='margin-bottom: 5px; width:100%;'>
-			<tbody>
-				<tr>
-					<td align='left' width='80%'>
-						<b>
-							<span>&staff.patron.ue.interface_note.label;</span>
-						</b>
-					</td>
-					<td align='right' width='20%'>
-						<a class='hide_me' id='ue_errors' href='javascript:void(0);' 
-							style='color: red; font-size: 12pt; font-weight: bold' onclick='uEditAlertErrors();'>
-							&ev.staff.patron.ue_xhtml.view_errors.label;
-						</a>
-					</td>
-				</tr>
-			</tbody>
-		</table>
-
-		<table class='main_table'>
-			<tbody>
-				<tr>
-					<td width='15%' valign='top'>
-						<!-- ************************************************************** -->
-						<!--  Top Navigation Links -->
-						<!-- ************************************************************** -->
-						<table height='100%' class='nav_link_table'>
-							<tbody>
-								<tr>
-									<td id='uedit_userid_label' class='main_nav_link'>
-										<a href='javascript:uEditShowPage("uedit_userid");'>&ev.staff.patron.ue_xhtml.user_id.label;</a>
-									</td>
-								</tr>
-								<tr>
-									<td id='uedit_contact_info_label' class='main_nav_link'>	
-										<a href='javascript:uEditShowPage("uedit_contact_info");'>&ev.staff.patron.ue_xhtml.contact_info.label;</a>
-									</td>
-								</tr>
-								<tr>
-									<td id='uedit_addresses_label' class='main_nav_link'>		
-										<a href='javascript:uEditShowPage("uedit_addresses");'>&ev.staff.patron.ue_xhtml.addresses.label;</a>
-									</td>
-								</tr>
-								<tr>
-									<td id='uedit_groups_label' class='main_nav_link'>			
-										<a href='javascript:uEditShowPage("uedit_groups");'>&ev.staff.patron.ue_xhtml.groups_permissions.label;</a>
-									</td>
-								</tr>
-								<tr>
-									<td id='uedit_stat_cats_label' class='main_nav_link'>		
-										<a href='javascript:uEditShowPage("uedit_stat_cats");'>&ev.staff.patron.ue_xhtml.statistical_categories.label;</a>
-									</td>
-								</tr>
-								<tr>
-									<td id='uedit_surveys_label' class='main_nav_link'>			
-										<a href='javascript:uEditShowPage("uedit_surveys");'>&ev.staff.patron.ue_xhtml.surveys.label;</a>
-									</td>
-								</tr>
-								<tr>
-									<td id='uedit_finalize_label' class='main_nav_link'>			
-										<a href='javascript:uEditShowPage("uedit_finalize");'>&ev.staff.patron.ue_xhtml.finish.label;</a>
-									</td>
-								</tr>
-							</tbody>
-						</table>
-					</td>
-
-					<td width='85%' id='uedit_loading'>
-						<div class='main_div has_color' 
-							style='padding: 50px; vertical-align: middle;'>
-							<b>&ev.staff.patron.ue_xhtml.loading_data.label;</b>
-						</div>
-					</td>
-
-
-					<td width='85%' id='ue_maintd' class='hide_me'>
-
-						<div id='dup_div_container'>
-							<div id='dup_div' name='dup_div'>
-								<a name='link' class='dup_link hide_me'
-									href='javascript:void(0);' onclick='uEditShowSearch(this);'>
-									&ev.staff.patron.ue_xhtml.found_duplicate_patron.label; <b name='count'/>
-									<b name='data'/>
-								</a>
-							</div>
-						</div>
-
-
-						<!-- ************************************************************** -->
-						<!--  Identification Pane -->
-						<!-- ************************************************************** -->
-						<div id='uedit_userid' class='main_div'>
-							<table class='uedit_table'>
-								<tbody>
-									<tr class='required_field'>
-										<td><div class='wide right'>&ev.staff.patron.ue_xhtml.barcode.label;</div></td>
-										<td>
-											<div class='wide left'>
-												<input type='text' id='ue_barcode' />
-													<!--
-													onblur=' 
-														var node = uEditFindFieldByWId("ue_username");
-														if(!node.widget.node.value) {
-															node.widget.node.value = this.value;
-															node.widget.node.onchange();
-														}'
-														/> -->
-														<button style='padding-left: 5px;' class='hide_me' id='ue_mark_card_lost'
-													onclick='uEditMarkCardLost();'>&ev.staff.patron.ue_xhtml.mark_lost.label;</button>
-											</div>
-										</td>
-									</tr>
-									<tr class='required_field'>
-										<td><div class='wide right'>&ev.staff.patron.ue_xhtml.username.label;</div></td>
-										<td><div class='wide left'><input type='text' id='ue_username'/></div></td>
-									</tr>
-									<tr class='required_field'>
-										<td><div class='wide right'>&ev.staff.patron.ue_xhtml.password.label;</div></td>
-										<td>
-											<div class='wide left'>
-												<input type='password' id='ue_password1'/>
-												<button class='hide_me' onclick='uEditResetPw();' id='ue_reset_pw'>&ev.staff.patron.ue_xhtml.reset.label;</button>
-												<span style='padding-left: 10px;' class='hide_me' id='ue_password_gen'>
-													&ev.staff.patron.ue_xhtml.re_password.label;
-													<span style='text-decoration:underline;' id='ue_password_plain'/>
-												</span>
-											</div>
-										</td>
-									</tr>
-									<tr class='required_field'>
-										<td><div class='wide right'>&ev.staff.patron.ue_xhtml.verify_password.label;</div></td>
-										<td><div class='wide left'><input type='password' id='ue_password2'/></div></td>
-									</tr>
-									<tr class='required_field'>
-										<td><div class='wide right'>&ev.staff.patron.ue_xhtml.first_name.label;</div></td>
-										<td><div class='wide left'><input type='text' id='ue_firstname'/></div></td>
-									</tr>
-									<tr>
-										<td><div class='wide right'>&ev.staff.patron.ue_xhtml.middle_name.label;</div></td>
-										<td><div class='wide left'><input type='text' id='ue_middlename'/></div></td>
-									</tr>
-									<tr class='required_field'>
-										<td><div class='wide right'>&ev.staff.patron.ue_xhtml.last_name.label;</div></td>
-										<td><div class='wide left'><input type='text' id='ue_lastname'/></div></td>
-									</tr>
-									<tr>
-										<td><div class='wide right'>&ev.staff.patron.ue_xhtml.alias.label;</div></td>
-										<td><div class='wide left'><input type='text' id='ue_alias'/></div></td>
-									</tr>
-									<tr class='required_field'>
-										<td><div class='wide right'>&ev.staff.patron.ue_xhtml.primary_id_type.label;</div></td>
-										<td><div class='wide left'>
-												<select id='ue_primary_ident_type'>
-													<option value=''>&ev.staff.patron.ue_xhtml.required.label;</option>
-												</select>
-											</div>
-										</td>
-									</tr>
-									<tr class='required_field'>
-										<td><div class='wide right'>&ev.staff.patron.ue_xhtml.primary_id.label;</div></td>
-										<td>
-											<div class='wide left'>
-												<input type='text' id='ue_primary_ident'/>
-												<span id='primary_ident_ssn_help' 
-													style='padding-left: 2px; font-size: 8pt;' class='hide_me'>
-												</span>
-												<span id='primary_ident_dl_help' 
-													style='padding-left: 2px; font-size: 8pt;' class='hide_me'>
-												</span>
-											</div>
-										</td>
-									</tr>
-									<!--
-									<tr>
-										<td><div class='wide right'>Secondary Identification Type</div></td>
-										<td><div class='wide left'>
-												<select id='ue_secondary_ident_type'>
-													<option value=''>  None Selected  </option>
-												</select>
-											</div>
-										</td>
-									</tr>
-									-->
-									<tr class='hide_me'>
-										<td><div class='wide right'>&ev.staff.patron.ue_xhtml.parent_guardian.label;</div></td>
-										<td>
-											<div class='wide left'>
-												<input type='text' id='ue_secondary_ident'/>
-												<input type='hidden' id='ue_dob' />
-												<input type='hidden' id='ue_juvenile' />
-												<input type='hidden' id='ue_suffix'/>
-												<input type='hidden' id='ue_suffix_selector'/>
-											</div>
-										</td>
-									</tr>
-									<!--
-									<tr class='hide_me' id='ue_guardian_row'>
-										<td><div class='wide right'><b>Parent / Guardian</b></div></td>
-										<td>
-											<div class='wide left'>
-												<span id='ue_guardian_field'/>
-											</div>
-										</td>
-									</tr>
-									-->
-								</tbody>
-							</table>
-						</div>
-
-						<!-- ************************************************************** -->
-						<!-- Contact Info Pane -->
-						<!-- ************************************************************** -->
-						<div id='uedit_contact_info' class='main_div hide_me'>
-
-							<table class='uedit_table'>
-								<tbody>
-									<tr>
-										<td><div class='wide right'>&ev.staff.patron.ue_xhtml.email_address.label;</div></td>
-										<td><div class='wide left'><input type='text' id='ue_email' size='32'/></div></td>
-									</tr>
-									<tr>
-										<td><div class='wide right'>&ev.staff.patron.ue_xhtml.daytime_phone.label;</div></td>
-										<td>
-											<div class='wide left'>
-												<input class='pad' type='text' id='ue_day_phone' size='18'/>
-												<span style='font-size: 9pt;'>&ev.staff.patron.ue_xhtml.phone_example;</span>
-											</div>
-										</td>
-									</tr>
-									<tr>
-										<td><div class='wide right'>&ev.staff.patron.ue_xhtml.evening_phone.label;</div></td>
-										<td>
-											<div class='wide left'>
-												<input class='pad' type='text' id='ue_night_phone' size='18'/>
-											</div>
-										</td>
-									</tr>
-									<tr>
-										<td><div class='wide right'>&ev.staff.patron.ue_xhtml.other_phone.label;</div></td>
-										<td>
-											<div class='wide left'>
-												<input class='pad' type='text' id='ue_other_phone' size='18'/>
-											</div>
-										</td>
-									</tr>
-									<tr class='required_field'>
-										<td><div class='wide right'>&ev.staff.patron.ue_xhtml.home_library.label;</div></td>
-										<td>
-											<div class='wide left'>
-												<select style='width: 20em;' id='ue_org_selector'/>
-											</div>
-										</td>
-									</tr>
-								</tbody>
-							</table>
-						</div>
-	
-						<!-- ************************************************************** -->
-						<!-- Addresses Pane -->
-						<!-- ************************************************************** -->
-						<div id='uedit_addresses' class='main_div hide_me' >
-							<table class='uedit_table' style='width: 98%; padding: 1px;'>
-								<thead>
-									<tr>
-										<td>&ev.staff.patron.ue_xhtml.address.label;</td>
-										<td>&ev.staff.patron.ue_xhtml.in_city_limits.label;</td>
-										<td>&ev.staff.patron.ue_xhtml.valid.label;</td>
-										<td>&ev.staff.patron.ue_xhtml.mailing_address.label;</td>
-										<td>&ev.staff.patron.ue_xhtml.physical_address.label;</td>
-									</tr>
-								</thead>
-								<tbody id='ue_address_tbody'>
-									<tr id='ue_address_template'>
-										<td>
-											<table class='address_table'>
-												<tbody>
-													<tr name='shared_row' class='hide_me'>
-														<td colspan='6'>
-															<div style='padding: 8px;'>
-																<span style='color:red;'>*</span>
-																&ev.staff.patron.ue_xhtml.address_owned_by.label;
-																<span name='addr_owner_name'/>
-																<span name='owner_link_div'>
-																	(<a name='addr_owner' href='javascript:void(0);'>&ev.staff.patron.ue_xhtml.edit.label;</a>)
-																</span>
-															</div>
-														</td>
-													</tr>
-													<tr>
-														<td><div class='wide right'>&ev.staff.patron.ue_xhtml.label.label;</div></td>
-														<td colspan='3'>
-															<div class='wide left'>
-																<input type='text' name='ue_addr_label' id='ue_addr_label'/>
-															</div>
-														</td>
-														<td><div class='wide right'>&ev.staff.patron.ue_xhtml.zip.label;</div></td>
-														<td>
-															<div class='wide left'>
-																<input type='text' name='ue_addr_zip' size='10' maxlength='10'/>
-															</div>
-														</td>
-													</tr>
-													<tr>
-														<td><div class='wide right'>&ev.staff.patron.ue_xhtml.street1.label;</div></td>
-														<td colspan='5'>
-															<div class='wide left'>
-																<input type='text' name='ue_addr_street1' size='42'/>
-															</div>
-														</td>
-													</tr>
-													<tr>
-														<td><div class='wide right'>&ev.staff.patron.ue_xhtml.street2.label;</div></td>
-														<td colspan='5'>
-															<div class='wide left'>
-																<input type='text' name='ue_addr_street2' size='42'/>
-															</div>
-														</td>
-													</tr>
-													<tr>
-														<td><div class='wide right'>&ev.staff.patron.ue_xhtml.city.label;</div></td>
-														<td colspan='3'>
-															<div class='wide left'>
-																<input type='text' name='ue_addr_city' size='17'/>
-															</div>
-														</td>
-														<td><div class='wide right'>&ev.staff.patron.ue_xhtml.conuty.label;</div></td>
-														<td>
-															<div class='wide left'>
-																<input type='text' name='ue_addr_county' size='17'/>
-															</div>
-														</td>
-													</tr>
-													<tr>
-														<td><div class='wide right'>&ev.staff.patron.ue_xhtml.state.label;</div></td>
-														<td colspan='3'>
-															<div class='wide left'>
-																<input type='text' name='ue_addr_state' size='3' maxlength='3'/>
-															</div>
-														</td>
-														<!--
-														<td><div class='wide right'>Zip</div></td>
-														<td>
-															<div class='wide left'>
-																<input type='text' name='ue_addr_zip' size='6' maxlength='6'/>
-															</div>
-														</td>
-														-->
-														<td><div class='wide right'>&ev.staff.patron.ue_xhtml.country.label;</div></td>
-														<td>
-															<div class='wide left'>
-																<input type='text' name='ue_addr_country' size='6'/>
-															</div>
-														</td>
-													</tr>
-													<tr>
-														<td colspan='6'>
-															<div class='button_row'>
-																<input type='submit' name='ue_addr_delete' 
-																	value='&ev.staff.patron.ue_xhtml.ue_addr_delete.label;'/>
-																<span style='padding-left: 10px;'> </span>
-																<input type='submit' name='ue_addr_detach' 
-																	value='&ev.staff.patron.ue_xhtml.ue_addr_detach.label;' class='hide_me'/>
-																<input type='submit' name='ue_addr_approve' 
-																	value='&ev.staff.patron.ue_xhtml.ue_addr_approve.label;' class='hide_me'/>
-															</div>
-														</td>
-													</tr>
-													<tr class='hide_me' name='ue_addr_replaced_row'>
-														<td colspan='6'>
-															<div class='button_row' name='ue_addr_replaced_div'>
-                                                            </div>
-                                                        </td>
-                                                    </tr>
-												</tbody>
-											</table>
-										</td>
-										<td><input type='checkbox' name='ue_addr_inc_yes' checked='checked'/></td>
-										<td><input type='checkbox' name='ue_addr_valid_yes' checked='checked'/></td>
-										<td>
-											<div style='width: 100%; -moz-border-radius: 8px;'>
-												<input type='radio' name='ue_addr_mailing_yes'
-													onchange='uEditAddrTypeClick(this, "mailing");'
-													onclick='uEditAddrTypeClick(this, "mailing");'/>
-											</div>
-										</td>
-										<td>
-											<div style='width: 100%; -moz-border-radius: 8px;'>
-												<input type='radio' name='ue_addr_billing_yes'
-													onchange='uEditAddrTypeClick(this, "billing");'
-													onclick='uEditAddrTypeClick(this, "billing");'/>
-											</div>
-										</td>
-									</tr>
-								</tbody>
-							</table>
-
-							<div class='button_row' style='margin-top: 20px;'>
-								<!--
-								<input type='submit' value='Create a New Address' id='ue_address_new'/>
-								-->
-								<input type='submit' value='&staff.patron.ue.create_address.label;' onclick='uEditCreateNewAddr();'/>
-							</div>
-						</div>
-	
-						<!-- ************************************************************** -->
-						<!-- Groups Pane -->
-						<!-- ************************************************************** -->
-						<div id='uedit_groups' class='main_div hide_me'>
-							<table class='uedit_table'>
-								<tbody>
-									<tr class='required_field'>
-										<td><div class='wide right'>&ev.staff.patron.ue_xhtml.profile_group.label;</div></td>
-										<td>
-											<div class='wide left'>
-												<select id='ue_profile' class='select_big'>
-													<option value=''>&ev.staff.patron.ue_xhtml.required.label;</option>
-												</select>
-											</div>
-										</td>
-									</tr>
-									<tr class='required_field'>
-										<td><div class='wide right'>&ev.staff.patron.ue_xhtml.account_expiration_date.label;</div></td>
-										<td>
-											<div class='wide left'>
-												<input type='text' id='ue_expire' size='10' maxlength='10'/>
-	
-												<button style='padding: 0px;' id='ue_expire_trigger'>
-													<img src="/opac/common/js/jscalendar/img.gif" 
-														style="cursor: pointer; border: 1px solid red; padding: 0px; margin: -3px;" 
-														title="&ev.staff.patron.ue_xhtml.date_selector.label;"
-														onmouseover="this.style.background='red';" 
-														onmouseout="this.style.background=''" />
-												</button>
-
-												<span class='pad' style='font-size: 8pt;'>(YYYY-MM-DD)</span>
-												<script type="text/javascript">
-													Calendar.setup({
-														inputField	: "ue_expire",				// id of the input field
-														ifFormat		: "%Y-%m-%d",				// format of the input field
-														button		: "ue_expire_trigger",  // trigger for the calendar (button ID)
-														align			: "Tl",						// alignment (defaults to "Bl")
-														singleClick	: true
-													});
-												</script>
-											</div>
-										</td>
-									</tr>
-									<tr class='hide_me'>
-										<td><div class='wide right'>&ev.staff.patron.ue_xhtml.net_access_level.label;</div></td>
-										<td>
-											<div class='wide left'>
-												<select id='ue_net_level'>
-												</select>
-											</div>
-										</td>
-									</tr>
-									<tr>
-										<td><div class='wide right'>&ev.staff.patron.ue_xhtml.active.label;</div></td>
-										<td>
-											<div class='wide left'>
-												<input id='ue_active' type='checkbox' checked='checked'/>
-											</div>
-										</td>
-									</tr>
-									<tr>
-										<td><div class='wide right'>&ev.staff.patron.ue_xhtml.barred.label;</div></td>
-										<td>
-											<div class='wide left'>
-												<input id='ue_barred' type='checkbox'/>
-											</div>
-										</td>
-									</tr>
-									<tr>
-										<td><div class='wide right'>&ev.staff.patron.ue_xhtml.set_family_group_lead_account.label;</div></td>
-										<td>
-											<div class='wide left'>
-												<input id='ue_group_lead' type='checkbox'/>
-											</div>
-										</td>
-									</tr>
-									<tr>
-										<td><div class='wide right'>&ev.staff.patron.ue_xhtml.claims_returned_count.label;</div></td>
-										<td>
-											<div class='wide left'>
-												<input id='ue_claims_returned' type='text' disabled='disabled' size='6'/>
-												<script>
-													$('ue_claims_returned').value = 0;
-													$('ue_claims_returned').disabled = true;
-												</script>
-												<input class='pad' id='ue_claims_returned_reset' type='submit' value='&ev.staff.patron.ue_xhtml.reset.label;' 
-													onclick="
-														if( confirmId('ue_claims_return_confirm') ) {
-															$('ue_claims_returned').value = 0;
-															$('ue_claims_returned').onchange();
-														}
-													"/>
-											</div>
-										</td>
-									</tr>
-									<tr>
-										<td><div class='wide right'>&ev.staff.patron.ue_xhtml.alert_message.label;</div></td>
-										<td>
-											<div class='wide left'>
-												<textarea wrap='soft' cols='30' rows='4' id='ue_alert_message'/>
-												<input class='pad' id='ue_alert_message_reset' 
-													type='submit' value='&ev.staff.patron.ue_xhtml.alert_message_reset.value;' 
-														onclick='
-														var node = $("ue_alert_message");
-														node.value = "";
-														if(node.onchange) node.onchange();'/>
-											</div>
-										</td>
-									</tr>
-								</tbody>
-							</table>
-						</div>
-	
-						<!-- ************************************************************** -->
-						<!-- Stat Cats Pane -->
-						<!-- ************************************************************** -->
-						<div id='uedit_stat_cats' class='main_div hide_me'>
-							<table class='uedit_table' style='width: 98%'>
-								<thead>
-									<tr style='font-weight: bold;'>
-										<td>&ev.staff.patron.ue_xhtml.stat_cat_name.label;</td>
-										<td>&ev.staff.patron.ue_xhtml.owner.label;</td>
-										<td>&ev.staff.patron.ue_xhtml.value.label;</td>
-									</tr>
-								</thead>
-								<tbody id='ue_stat_cat_tbody'>
-									<tr id='ue_stat_cat_row'>
-										<td><div class='wide right' name='ue_stat_cat_name'/></td>
-										<td><div class='wide right' style='font-size: 8pt' name='ue_stat_cat_owner'/></td>
-										<td>
-											<div class='wide left'>
-												<select name='ue_stat_cat_selector'>
-													<option value=''>&ev.staff.patron.ue_xhtml.none_selected.label;</option>
-												</select>
-												<span class='pad'> or </span>
-												<input class='pad' type='text' name='ue_stat_cat_newval'/>
-											</div>
-										</td>
-									</tr>
-								</tbody>
-							</table>
-
-						</div>
-	
-						<!-- ************************************************************** -->
-						<!-- Surveys Pane -->
-						<!-- ************************************************************** -->
-						<div id='uedit_surveys' class='main_div hide_me'>
-							<div id='uedit_no_surveys' class='hide_me'>
-								<b>&ev.staff.patron.ue_xhtml.no_surveys_for_location.label;</b>
-							</div>
-							<table id='ue_survey_table' 
-								class='uedit_table data_grid' style='width: 95%; margin-top: 17px;'>
-								<thead>
-									<tr>
-										<td colspan='2' style='text-align: left; padding-left: 20px;'>
-											<span class='pad' name='ue_survey_name' style='font-weight: bold;'/>
-											<span class='pad' name='ue_survey_desc'> : </span>
-										</td>
-									</tr>
-								</thead>
-								<tbody name='ue_survey_tbody'>
-									<tr name='ue_survey_row'>
-										<td name='ue_survey_question' 
-											style='width: 60%; text-align: left; padding-left: 40px;'/>
-										<td>
-											<select name='ue_survey_answer'>
-												<option value=''>&ev.staff.patron.ue_xhtml.none_selected.label;</option>
-											</select>
-										</td>
-									</tr>
-								</tbody>
-							</table>
-						</div>
-
-						<!-- ************************************************************** -->
-						<!-- Finish Up -->
-						<!-- ************************************************************** -->
-						<div id='uedit_finalize' class='main_div hide_me'>
-							<div class='has_color' style='width: 95%; margin-top: 40px; text-align: center'>
-								<div style='padding: 5px;'>
-									&ev.staff.patron.ue_xhtml.finishing_message.label;
-								</div>
-								<br/>
-								<div style='margin-bottom: 15px;'>
-									<a style='margin-right: 30px;' id='ue_view_summary' 
-										href='javascript:uEditShowSummary();'>View Summary</a>
-								</div>
-								<input style='margin-left: 5px; margin-right: 5px;' id='ue_save'
-									type='submit' value='&ev.staff.patron.ue_xhtml.save_user.value;' onclick='uEditSaveUser();'/>
-								<input style='margin-left: 5px; margin-right: 5px;' id='ue_save_clone'
-									type='submit' value='&ev.staff.patron.ue_xhtml.save_clone_user.value;' onclick='uEditSaveUser(true);'/>
-								<button style='margin-left: 5px; margin-right: 5px;' 
-									onclick='if(confirm($("ue_cancel_confirm").innerHTML)) uEditCancel();'>&ev.staff.patron.ue_xhtml.cancel.value;</button>
-							</div>
-						</div>
-					</td>
-				</tr>
-
-				<tr>
-					<td colspan='2'>
-						<!-- ************************************************************** -->
-						<!-- Bottom Navigation Links -->
-						<!-- ************************************************************** -->
-						<table width='100%' class='no_border'>
-							<tbody>
-								<tr id='uedit_nav_bar'>
-									<td width='10%'/>
-									<td width='40%'>
-										<a id='ue_back' class='nav_link hide_me' 
-											href='javascript:uEditPrev()'>&#x2190;&ev.staff.patron.ue_xhtml.back.label;</a>
-									</td>
-									<td width='40%'>
-										<a id='ue_fwd' class='nav_link' 
-											href='javascript:uEditNext()'>&ev.staff.patron.ue_xhtml.forward.label;&#x2192;</a>
-									</td>
-									<td width='10%'/>
-								</tr>
-							</tbody>
-						</table>
-					</td>
-				</tr>
-			</tbody>
-		</table>
-	</div>
-
-	</center>
-
-	<div id='summary_div_container' class='hide_me'>
-
-	<div id='ue_summary_page'>
-		<table id='ue_summary_table' class='data_grid' width='55%'>
-			<thead>
-				<tr>
-					<td colspan='2'>
-						<span>&staff.patron.ue.user_summary.label;</span>
-					</td>
-				</tr>
-			</thead>
-			<tbody name='ue_summary_page_tbody'>
-
-				<tr>
-
-					<td colspan='2' align='center'>
-						<input style='margin-right: 15px;' type='submit' value='&ev.staff.patron.ue_xhtml.print_page.label;' onclick='window.print();'/>
-						<input style='margin-left: 15px;' type='submit' value='&ev.staff.patron.ue_xhtml.return_to_editor.label;' 
-							onclick=' unHideMe($("main_div_container")); 
-								hideMe($("summary_div_container"));'/>
-					</td>
-				</tr>
-
-				<tr><td>&ev.staff.patron.ue_xhtml.barcode.label;</td><td id='ue_summary_barcode'/></tr>
-				<tr><td>&ev.staff.patron.ue_xhtml.username.label;</td><td id='ue_summary_usrname'/></tr>
-				<tr><td>&ev.staff.patron.ue_xhtml.first_name.label;</td><td id='ue_summary_first_given_name'/></tr>
-				<tr><td>&ev.staff.patron.ue_xhtml.middle_name.label;</td><td id='ue_summary_second_given_name'/></tr>
-				<tr><td>&ev.staff.patron.ue_xhtml.last_name.label;</td><td id='ue_summary_family_name'/></tr>
-				<tr><td>&ev.staff.patron.ue_xhtml.alias.label;</td><td id='ue_summary_alias'/></tr>
-				<tr><td>&ev.staff.patron.ue_xhtml.suffix.label;</td><td id='ue_summary_suffix'/></tr>
-				<tr><td>&ev.staff.patron.ue_xhtml.dob.label;</td><td id='ue_summary_dob'/></tr>
-				<tr><td>&ev.staff.patron.ue_xhtml.primary_id_type.label;</td><td id='ue_summary_ident_type'/></tr>
-				<tr><td>&ev.staff.patron.ue_xhtml.primary_id.label;</td><td id='ue_summary_ident_value'/></tr>
-				<tr><td>&ev.staff.patron.ue_xhtml.secondary_id_type.label;</td><td id='ue_summary_ident_type2'/></tr>
-				<tr><td>&ev.staff.patron.ue_xhtml.secondary_id.label;</td><td id='ue_summary_ident_value2'/></tr>
-				<tr><td>&ev.staff.patron.ue_xhtml.email_address.label;</td><td id='ue_summary_email'/></tr>
-				<tr><td>&ev.staff.patron.ue_xhtml.daytime_phone.label;</td><td id='ue_summary_day_phone'/></tr>
-				<tr><td>&ev.staff.patron.ue_xhtml.evening_phone.label;</td><td id='ue_summary_evening_phone'/></tr>
-				<tr><td>&ev.staff.patron.ue_xhtml.other_phone.label;</td><td id='ue_summary_other_phone'/></tr>
-				<tr><td>&ev.staff.patron.ue_xhtml.home_library.label;</td><td id='ue_summary_home_ou'/></tr>
-
-				<tr>
-					<td colspan='2'>
-						<table width='100%' style='margin-top: 15px; margin-bottom: 15px;'>
-							<thead><tr><td>&ev.staff.patron.ue_xhtml.addresses.label;</td></tr></thead>
-							<tbody name='ue_summary_addr_tbody'>
-								<tr name='ue_summary_addr_row'>
-									<td>
-										<table name='ue_summary_addr_table' width='100%'>
-											<thead><tr><td colspan='4'/><span> </span></tr></thead>
-											<tbody>
-												<tr>
-													<td><b>&ev.staff.patron.ue_xhtml.address_label.label;</b></td><td name='label'/>
-													<td><b>&ev.staff.patron.ue_xhtml.zip.label;</b></td><td name='zip'/>
-												</tr>
-												<tr>
-													<td><b>&ev.staff.patron.ue_xhtml.street1.label;</b></td><td name='street1'/>
-													<td><b>&ev.staff.patron.ue_xhtml.country.label;</b></td><td name='country'/>
-												</tr>
-												<tr>
-													<td><b>&ev.staff.patron.ue_xhtml.street2.label;</b></td><td name='street2'/>
-													<td><b>&ev.staff.patron.ue_xhtml.mailing.label;</b></td><td name='mailing'/>
-												</tr>
-												<tr>
-													<td><b>&ev.staff.patron.ue_xhtml.city.label;</b></td><td name='city'/>
-													<td><b>&ev.staff.patron.ue_xhtml.billing.label;</b></td><td name='billing'/>
-												</tr>
-												<tr>
-													<td><b>&ev.staff.patron.ue_xhtml.county.label;</b></td><td name='county'/>
-													<td><b>&ev.staff.patron.ue_xhtml.valid.label;</b></td><td name='valid'/>
-												</tr>
-												<tr>
-													<td><b>&ev.staff.patron.ue_xhtml.state.label;</b></td><td name='state'/>
-													<td><b>&ev.staff.patron.ue_xhtml.in_city_limits.label;</b></td><td name='incorporated'/>
-												</tr>
-											</tbody>
-										</table>
-									</td>
-								</tr>
-							</tbody>
-						</table>
-					</td>
-				</tr>
-				<tr><td>&ev.staff.patron.ue_xhtml.profile.label;</td><td id='ue_summary_profile'/></tr>
-				<tr><td>&ev.staff.patron.ue_xhtml.active.label;</td><td id='ue_summary_active'/></tr>
-				<tr><td>&ev.staff.patron.ue_xhtml.barred.label;</td><td id='ue_summary_barred'/></tr>
-				<tr><td>&ev.staff.patron.ue_xhtml.expire_date.label;</td><td id='ue_summary_expire_date'/></tr>
-				<tr><td>&ev.staff.patron.ue_xhtml.family_lead_account.label;</td><td id='ue_summary_master_account'/></tr>
-				<tr><td>&ev.staff.patron.ue_xhtml.claims_returned_count.label;</td><td id='ue_summary_claims_returned_count'/></tr>
-				<tr><td>&ev.staff.patron.ue_xhtml.alert_message.label;</td><td id='ue_summary_alert_message'/></tr>
-				<tr name='ue_summary_stat_cat_td'>
-					<td colspan='2' >
-						<table width='100%' style='margin-top: 15px; margin-bottom: 15px;'>
-							<thead><tr><td colspan='2'>&ev.staff.patron.ue_xhtml.stat_categories.label;</td></tr></thead>
-							<tbody name='ue_summary_stats_tbody'>
-								<tr name='ue_summary_stats_row'>
-									<td name='ue_summary_stat_name'/><td name='ue_summary_stat_value'/>
-								</tr>
-							</tbody>
-						</table>
-					</td>
-				</tr>
-				<tr name='ue_summary_survey_td'>
-					<td colspan='2'>
-						<table width='100%' style='margin-top: 15px; margin-bottom: 15px;'>
-							<thead>
-								<tr>
-									<td>&ev.staff.patron.ue_xhtml.survey.label;</td>
-									<td>&ev.staff.patron.ue_xhtml.question.label;</td>
-									<td>&ev.staff.patron.ue_xhtml.answer.label;</td>
-								</tr>
-							</thead>
-							<tbody name='ue_summary_survey_tbody'>
-								<tr name='ue_summary_survey_row'>
-									<td name='ue_summary_survey_name'/>
-									<td name='ue_summary_survey_question'/>
-									<td name='ue_summary_survey_answer'/>
-								</tr>
-							</tbody>
-						</table>
-					</td>
-				</tr>
-				<tr>
-					<td colspan='2' align='center'>
-						<input style='margin-right: 15px;' type='submit' value='&ev.staff.patron.ue_xhtml.print_page.label;' onclick='window.print();'/>
-						<input style='margin-left: 15px;' type='submit' value='&ev.staff.patron.ue_xhtml.return_to_editor.label;' 
-							onclick=' unHideMe($("main_div_container")); 
-								hideMe($("summary_div_container"));'/>
-					</td>
-				</tr>
-			</tbody>
-		</table>
-	</div>
-	</div>
-
-
-	<!-- ************************************************************** -->
-	<!-- This holds all of the strings we may have to alert to the user -->
-	<!-- ************************************************************** -->
-	<div class='hide_me'>
-		<span id='ue_bad_dob'>&staff.patron.ue.bad_dob.label;</span>
-		<span id='ue_bad_username'>&staff.patron.ue.bad_username.label;</span>
-		<span id='ue_bad_password'>&staff.patron.ue.bad_passwords.label;</span>
-		<span id='ue_bad_firstname'>&staff.patron.ue.bad_firstname.label;</span>
-		<span id='ue_bad_middlename'>&staff.patron.ue.bad_middlename.label;</span>
-		<span id='ue_bad_lastname'>&staff.patron.ue.bad_lastname.label;</span>
-		<span id='ue_bad_barcode'>&staff.patron.ue.bad_barcode.label;</span>
-		<span id='ue_duplicate_barcode'>&staff.patron.ue.duplicate_barcode.label;</span>
-		<span id='ue_new_barcode_warn'>&staff.patron.ue.new_barcode_warn.label;</span>
-		<span id='ue_no_ident'>&staff.patron.ue.no_ident.label;</span>
-		<span id='ue_bad_ident_dl'>&staff.patron.ue.bad_ident_dl.label;</span>
-		<span id='ue_bad_ident_ssn'>&staff.patron.ue.bad_ident_ssn.label;</span>
-		<span id='ue_bad_email'>&staff.patron.ue.bad_email.label;</span>
-		<span id='ue_bad_phone'>&staff.patron.ue.bad_phone.label;</span>
-		<span id='ue_no_profile'>&staff.patron.ue.no_profile.label;</span>
-		<span id='ue_bad_expire'>&staff.patron.ue.bad_expire.label;</span>
-		<span id='ue_bad_claims_returned'>&staff.patron.ue.bad_claims_returned.label;</span>
-		<span id='ue_no_profile'>&ev.staff.patron.ue_xhtml.no_profile.label;</span>
-		<span id='ue_unknown_error'>&staff.patron.ue.unknown_error.label;</span>
-		<span id='ue_bad_addr_label'>&staff.patron.ue.bad_addr_label.label;</span>
-		<span id='ue_bad_addr_street'>&staff.patron.ue.bad_addr_street.label;</span>
-		<span id='ue_bad_addr_city'>&staff.patron.ue.bad_addr_city.label;</span>
-		<span id='ue_bad_addr_county'>&staff.patron.ue.bad_addr_county.label;</span>
-		<span id='ue_bad_addr_state'>&staff.patron.ue.bad_addr_state.label;</span>
-		<span id='ue_bad_addr_country'>&staff.patron.ue.bad_addr_country.label;</span>
-		<span id='ue_bad_addr_zip'>&staff.patron.ue.bad_addr_zip.label;</span>
-		<span id='ue_bad_survey'>&staff.patron.ue.bad_survey.label;</span>
-		<span id='ue_delete_addr_warn'>&staff.patron.ue.delete_addr_warn.label;</span>
-		<span id='yes'>&staff.patron.ue.yes.label;</span>
-		<span id='no'>&staff.patron.ue.no.label;</span>
-		<span id='ue_summary_window'>&staff.patron.ue.summary_window.label;</span>
-		<span id='ue_success'>&staff.patron.ue.success.label;</span>
-		<span id='ue_dup_ident1'>&staff.patron.ue.dup_ident1.label;</span>
-		<span id='ue_dup_username'>&staff.patron.ue.dup_username.label;</span>
-		<span id='ue_dup_barcode'>&staff.patron.ue.dup_barcode.label;</span>
-		<span class='hide_me' id='ue_cancel_confirm'>&staff.patron.ue.cancel_confirm.label;</span>
-		<span class='hide_me' id='ue_juv_guardian'>&staff.patron.ue.juv_guardian.label;</span>
-		<span class='hide_me' id='ue_bad_date'>&staff.patron.ue.bad_date.label;</span>
-		<span class='hide_me' id='ue_made_barred'>&staff.patron.ue.made_barred.label;</span>
-		<span class='hide_me' id='ue_claims_return_confirm'>&ev.staff.patron.ue_xhtml.claims_return_confirm.label;</span>
-		<span class='hide_me' id='ue_unsaved_changes'>&ev.staff.patron.ue_xhtml.unsaved_changes.label;</span>
-		<span class='hide_me' id='ue_xact_collision'>&ev.staff.patron.ue_xhtml.xact_collision.label;</span>
-		<span class='hide_me' id='ue_add_approve_confirm'>&ev.staff.patron.ue_xhtml.ue_addr_approve_confirm.label;</span>
-	</div>
-
-	</body>
-</html>
-

Deleted: conifer/branches/rel_2_0/xul/server/patron/ue_config.js
===================================================================
--- conifer/branches/rel_2_0/xul/server/patron/ue_config.js	2011-04-12 13:42:03 UTC (rev 1332)
+++ conifer/branches/rel_2_0/xul/server/patron/ue_config.js	2011-04-12 13:54:03 UTC (rev 1333)
@@ -1,1181 +0,0 @@
-/* -----------------------------------------------------------------------
-	----------------------------------------------------------------------- */
-const SC_FETCH_ALL		= 'open-ils.circ:open-ils.circ.stat_cat.actor.retrieve.all';
-const SC_CREATE_MAP		= 'open-ils.circ:open-ils.circ.stat_cat.actor.user_map.create';
-const SV_FETCH_ALL		= 'open-ils.circ:open-ils.circ.survey.retrieve.all';
-const FETCH_ID_TYPES		= 'open-ils.actor:open-ils.actor.user.ident_types.retrieve';
-const FETCH_GROUPS		= 'open-ils.actor:open-ils.actor.groups.tree.retrieve';
-const FETCH_NET_LEVELS	= 'open-ils.actor:open-ils.actor.net_access_level.retrieve.all';
-const UPDATE_PATRON		= 'open-ils.actor:open-ils.actor.patron.update';
-const PATRON_SEARCH		= 'open-ils.actor:open-ils.actor.patron.search.advanced';
-const ZIP_SEARCH			= 'open-ils.search:open-ils.search.zip';
-const APPROVE_ADDR		= 'open-ils.actor:open-ils.actor.user.pending_address.approve';
-const FETCH_ADDR_MEMS	= 'open-ils.actor:open-ils.actor.address.members';
-const FETCH_GRP_MEMS		= 'open-ils.actor:open-ils.actor.usergroup.members.retrieve';
-const CREATE_USER_NOTE	= 'open-ils.actor:open-ils.actor.note.create';
-const CHECK_BARCODE		= 'open-ils.actor:open-ils.actor.barcode.exists';
-const defaultState		= 'ON';
-const defaultCountry		= 'Canada';
-const defaultNetAccess	= 'None';
-const defaultNetLevel   = 1;
-const CSS_INVALID_DATA	= 'invalid_value';
-
-// if no org setting exists
-const DEFAULT_ADULT_AGE			= '18 years';
-
-//const GUARDIAN_NOTE		= 'SYSTEM: Parent/Guardian';
-
-var dataFields;
-const laxRegex		= /\w+/;
-const nameRegex         = /^\S+[\S\s]*$/;
-const numRegex		= /^\d+$/;
-const wordRegex	= /^[\w-]+$/;
-const unameRegex	= /^\w[\.\w\@-]*$/;
-const ssnRegex		= /^\d{3}-\d{2}-\d{4}$/;
-const dlRegex		= /^[a-zA-Z]{2}-\w+/; /* driver's license */
-const phoneRegex	= /^\d{3}-\d{3}-\d{4}(| \S+.*)$/i;
-const nonumRegex	= /^[a-zA-Z]\D*$/; /* no numbers, no beginning whitespace */
-const dateRegex	= /^\d{4}-\d{2}-\d{2}/;
-const zipRegex		= /^\d{5}(-\d{4}|-?$)/; /* 12345 or 12345-6789 */
-
-var barredAlerted = false;
-
-
-function uEditUsrnameBlur(field) {
-	var usrname = uEditNodeVal(field);
-	if (!usrname) { return; }
-	var req = new Request(CHECK_USERNAME, SESSION, usrname);
-	req.callback( 
-		function(r) {
-			var res = r.getResultObject();
-			if( res !== null && res != patron.id() ) {
-				field.widget.onblur = null; /* prevent alert storm */
-				alertId('ue_dup_username');
-				field.widget.onblur = uEditUsrnameBlur;
-				setTimeout( 
-					function() {
-						field.widget.node.focus();
-						field.widget.node.select();
-					}, 10 
-				);
-			}
-		}
-	);
-	req.send();
-}
-
-
-function uEditBarcodeBlur(field) {
-	var barcode = uEditNodeVal(field);
-	if(!barcode) return;
-	_debug("blurring card with new value " + barcode);
-	var req = new Request(CHECK_BARCODE, SESSION, barcode);
-	req.callback( 
-		function(r) {
-			var res = r.getResultObject();
-			if( res == 1 ) {
-				field.widget.onblur = null; /* prevent alert storm */
-				alertId('ue_dup_barcode');
-				field.widget.onblur = uEditBarcodeBlur;
-				setTimeout( 
-					function() {
-						field.widget.node.focus();
-						field.widget.node.select();
-					}, 10 
-				);
-			} else {
-				var node = uEditFindFieldByWId("ue_username");
-				if(!node.widget.node.value) {
-					node.widget.node.value = barcode;
-					node.widget.node.onchange();
-				}
-			}
-		}
-	);
-	req.send();
-}
-
-
-function uEditDefineData(patron) {
-
-	var fields = [
-		{
-			required : true,
-			object	: patron.card(),
-			key		: 'barcode',
-			errkey	: 'ue_bad_barcode',
-			widget	: {
-				id		: 'ue_barcode',
-				regex	: wordRegex,
-				type	: 'input',
-				onblur : uEditBarcodeBlur
-			}
-		},
-		{
-			required : true,
-			object	: patron,
-			key		: 'usrname',
-			errkey	: 'ue_bad_username',
-			widget	: {
-				id		: 'ue_username',
-				regex	: unameRegex,
-				type	: 'input',
-				onblur : uEditUsrnameBlur
-			}
-		},
-		{
-			required : (patron.isnew()) ? true : false,
-			object	: patron,
-			key		: 'passwd',
-			errkey	: 'ue_bad_password',
-			widget	: {
-				id		: 'ue_password1',
-				type	: 'input',
-				onpostchange : function(field, newval) {
-					var pw2 = uEditFindFieldByWId('ue_password2');
-					/* tell the second passsword input to re-validate */
-					pw2.widget.node.onchange();
-				}
-
-			}
-		},
-		{
-			required : (patron.isnew()) ? true : false,
-			object	: patron,
-			key		: 'passwd',
-			errkey	: 'ue_bad_password',
-			widget	: {
-				id		: 'ue_password2',
-				type	: 'input',
-				onpostchange : function(field, newval) {
-					var pw1f = uEditFindFieldByWId('ue_password1');
-					var pw1 = uEditNodeVal(pw1f);
-					field.widget.regex = new RegExp('^'+pw1+'$');
-					if( pw1 ) field.required = true;
-					else {
-						if(!patron.isnew())
-							field.required = false;
-					}
-				}
-			}
-		},
-		{
-			required : true,
-			object	: patron,
-			key		: 'first_given_name',
-			errkey	: 'ue_bad_firstname',
-			widget	: {
-				id		: 'ue_firstname',
-				regex	: nameRegex,
-				type	: 'input',
-				onblur : function(field) {
-					uEditCheckNamesDup('first', field );
-				}
-			}
-		},
-		{
-			required : false,
-			object	: patron,
-			key		: 'second_given_name',
-			errkey	: 'ue_bad_middlename',
-			widget	: {
-				id		: 'ue_middlename',
-				regex	: nameRegex,
-				type	: 'input'
-			}
-		},
-		{
-			required : true,
-			object	: patron,
-			key		: 'family_name',
-			errkey	: 'ue_bad_lastname',
-			widget	: {
-				id		: 'ue_lastname',
-				regex	: nameRegex,
-				type	: 'input',
-				onblur : function(field) {
-					uEditCheckNamesDup('last', field );
-				}
-			}
-		},
-		{
-			required : false,
-			object	: patron,
-			key		: 'suffix',
-			widget	: {
-				id			: 'ue_suffix',
-				type		: 'input',
-				onload	: function(val) {
-					setSelector($('ue_suffix_selector'), val);
-					$('ue_suffix_selector').onchange = function() {
-						uEditFindFieldByKey('suffix').widget.node.onchange();
-					}
-				},
-			}
-		},
-		{
-			required : false,
-			object	: patron,
-			key		: 'alias',
-			widget	: {
-				id		: 'ue_alias',
-				type	: 'input',
-			}
-		},
-		{
-			required : false,
-			object	: patron,
-			key		: 'dob',
-			errkey	: 'ue_bad_dob',
-			widget	: {
-				id			: 'ue_dob',
-				regex		: dateRegex,
-				type		: 'input',
-				onpostchange	: function(field) { uEditCheckDOB(field); },
-				onblur	: function(field) { uEditCheckDOB(field); }
-			}
-		},
-		{
-			required : true,
-			object	: patron,
-			key		: 'ident_type',
-			errkey	: 'ue_no_ident',
-			widget	: {
-				id		: 'ue_primary_ident_type',
-				regex	: numRegex,
-				type	: 'select',
-				onpostchange : function(field, newval) 
-					{ _uEditIdentPostchange('primary', field, newval); }
-			}
-		},
-		{
-			required : false,
-			object	: patron,
-			key		: 'ident_value',
-			widget	: {
-				id			: 'ue_primary_ident',
-				type		: 'input',
-				onblur : function(field) {
-					uEditCheckIdentDup(field);
-				}
-			}
-		},
-		{
-			required : false,
-			object	: patron,
-			key		: 'ident_value2',
-			widget	: {
-				id			: 'ue_secondary_ident',
-				type		: 'input'
-			}
-		},
-		{
-			required : false,
-			object	: patron,
-			key		: 'email',
-			errkey	: 'ue_bad_email',
-			widget	: {
-				id			: 'ue_email',
-				type		: 'input',
-				regex		:  /.+\@.+\..+/,  /* make me better */
-				onblur	: function(field) {
-					var val = uEditNodeVal(field);
-					if( val && val != field.oldemail ) {
-						uEditRunDupeSearch('email',
-							{ email : { value : val, group : 0 } });
-						field.oldemail = val;
-					}
-				}
-			}
-		},
-		{
-			required : false,
-			object	: patron,
-			key		: 'day_phone',
-			errkey	: 'ue_bad_phone',
-			widget	: {
-				id			: 'ue_day_phone',
-				type		: 'input',
-				regex		:  laxRegex,
-                onblur      : function() {
-                    if(uEditUsePhonePw)
-                        uEditMakePhonePw();
-                },
-                onpostchange: function(field, newval) {
-                    /*  if this is a new patron and we are using the phone number for
-                        the password and the staff edits the phone number after entering
-                        it (think typos), update the password too */
-                    if(uEditUsePhonePw && patron.isnew() && patron.passwd() != newval) {
-                        patron.passwd(null);
-                        uEditMakePhonePw();
-                    }
-                }
-			}
-		},
-		{
-			required : false,
-			object	: patron,
-			key		: 'evening_phone',
-			errkey	: 'ue_bad_phone',
-			widget	: {
-				id			: 'ue_night_phone',
-				type		: 'input',
-				regex		:  laxRegex,
-                onblur      : function() {
-                    if(uEditUsePhonePw)
-                        uEditMakePhonePw();
-                }
-			}
-		},
-		{
-			required : false,
-			object	: patron,
-			key		: 'other_phone',
-			errkey	: 'ue_bad_phone',
-			widget	: {
-				id			: 'ue_other_phone',
-				type		: 'input',
-				regex		:  laxRegex,
-                onblur      : function() {
-                    if(uEditUsePhonePw)
-                        uEditMakePhonePw();
-                }
-			}
-		},
-		{
-			required : true,
-			object	: patron,
-			key		: 'home_ou',
-			widget	: {
-				id			: 'ue_org_selector',
-				type		: 'select',
-				regex		:  numRegex,
-			}
-		},
-		{
-			required : true,
-			object	: patron,
-			key		: 'expire_date',
-			errkey	: 'ue_bad_expire',
-			widget	: {
-				id			: 'ue_expire',
-				type		: 'input',
-				regex		:  dateRegex,
-			}
-		},
-		{
-			required : false,
-			object	: patron,
-			key		: 'active',
-			widget	: {
-				id			: 'ue_active',
-				type		: 'checkbox',
-			}
-		},
-		{
-			required : false,
-			object	: patron,
-			key		: 'juvenile',
-			widget	: {
-				id			: 'ue_juvenile',
-				type		: 'checkbox',
-				onpostchange	: function(field) { uEditCheckDOB(uEditFindFieldByKey('dob')); },
-				onblur	: function(field) { uEditCheckDOB(uEditFindFieldByKey('dob')); }
-			}
-		},
-		{
-			required : false,
-			object	: patron,
-			key		: 'barred',
-			widget	: {
-				id			: 'ue_barred',
-				type		: 'checkbox',
-				onpostchange : function(field, val) {
-					var afield = uEditFindFieldByKey('alert_message');
-					if( val ) {
-						if( !barredAlerted ) {
-							barredAlerted = true;
-							alertId('ue_made_barred');
-						}
-						afield.required = true;	
-					} else {
-						afield.required = false;
-					}
-				}
-			}
-		},
-		{
-			required : true,
-			object	: patron,
-			key		: 'profile',
-			errkey	: 'ue_no_profile',
-			widget	: {
-				id			: 'ue_profile',
-				type		: 'select',
-				regex		: numRegex,
-				onpostchange : function(field, value) {
-					var type			= groupsCache[value];
-					if(!type) return;
-					var interval	= type.perm_interval();
-
-					/* interval_to_seconds expects 'M' for months, 'm' for minutes */
-					interval			= interval.replace(/mon/, 'Mon'); 
-					var intsecs		= parseInt(interval_to_seconds(interval));
-
-					var expdate		= new Date();
-					var exptime		= expdate.getTime();
-					exptime			+= intsecs * 1000;
-					expdate.setTime(exptime);
-
-					_debug("profile change (interval= '"+interval+"', seconds="+intsecs+")\n\tgenerated a date of " + expdate);
-
-					var year			= expdate.getYear() + 1900;
-					var month		= (expdate.getMonth() + 1) + '';
-					var day			= (expdate.getDate()) + '';
-
-					if(!month.match(/\d{2}/)) month = '0' + month;
-					if(!day.match(/\d{2}/)) day = '0' + day;
-
-
-					var node = $('ue_expire');
-					node.value = year+'-'+month+'-'+day;
-
-					_debug("profile change formatted date to "+ node.value);
-					node.onchange();
-				}
-			}
-		},
-		{
-			required : false,
-			object	: patron,
-			key		: 'net_access_level',
-			widget	: {
-				id		: 'ue_net_level',
-				type	: 'select'
-			}
-		},
-		{
-			required : false,
-			object	: patron,
-			key		: 'master_account',
-			widget	: {
-				id			: 'ue_group_lead',
-				type		: 'checkbox',
-			}
-		},
-		{
-			required : true,
-			object	: patron,
-			key		: 'claims_returned_count',
-			widget	: {
-				id			: 'ue_claims_returned',
-				type		: 'input',
-				regex		: numRegex,
-				disabled : true
-			}
-		},
-		{
-			required : false,
-			object	: patron,
-			key		: 'alert_message',
-			widget	: {
-				id			: 'ue_alert_message',
-				type		: 'input',
-			}
-		}
-	];
-
-	for( var f in fields ) 
-		dataFields.push(fields[f]);
-
-	uEditBuildAddrs(patron);
-	uEditBuildPatronSCM(patron);
-}
-
-var uEditOldFirstName;
-var uEditOldMiddleName; /* future */
-var uEditOldLastName;
-function uEditCheckNamesDup(type, field) {
-	var newval = uEditNodeVal(field);
-	if(!newval) return;
-
-	var dosearch = false;
-
-	if(type =='first') {
-		if( newval != uEditOldFirstName )
-			dosearch = true;
-		uEditOldFirstName = newval;
-	}
-
-	if(type =='last') {
-		if( newval != uEditOldLastName )
-			dosearch = true;
-		uEditOldLastName = newval;
-	}
-
-	if( dosearch && uEditOldFirstName && uEditOldLastName ) {
-		var search_hash = {};
-		search_hash['first_given_name'] = { value : uEditOldFirstName, group : 0 };
-		search_hash['family_name'] = { value : uEditOldLastName, group : 0 };
-		uEditRunDupeSearch('names', search_hash);
-	}
-}
-
-var uEditOldIdentValue;
-function uEditCheckIdentDup(field) {
-	var newval = uEditNodeVal(field);
-	if( newval && newval != uEditOldIdentValue ) {
-		/* searches all ident_value fields */
-		var search_hash  = { ident : { value : newval, group : 2 } };
-		uEditRunDupeSearch('ident', search_hash);
-		uEditOldIdentValue = newval;
-	}
-}
-
-
-/* Adds all of the addresses attached to the patron object
-	to the fields array */
-var uEditAddrTemplate;
-function uEditBuildAddrs(patron) {
-	var tbody = $('ue_address_tbody');
-	if(!uEditAddrTemplate)
-		uEditAddrTemplate = tbody.removeChild($('ue_address_template'));
-	for( var a in patron.addresses() ) 
-		uEditBuildAddrFields( patron, patron.addresses()[a]);
-}
-
-
-function uEditDeleteAddr( tbody, row, address, detach ) {
-	if(!confirm($('ue_delete_addr_warn').innerHTML)) return;
-	if(address.isnew()) { 
-		patron.addresses(
-			grep( patron.addresses(), 
-				function(i) {
-					return (i.id() != address.id());
-				}
-			)
-		);
-        if(!patron.addresses())
-            patron.addresses([]);
-
-		/* XXX */
-		for( var f in dataFields ) {
-			if( dataFields[f].object == address ) {
-				dataFields[f] = null;
-			}
-		}
-
-		dataFields = compactArray(dataFields);
-
-	} else {
-
-		if( detach ) { /* remove the offending address from the list */
-			patron.addresses(
-				grep( 
-					patron.addresses(), 
-					function(i) {
-						return (i.id() != address.id());
-					}
-				)
-			);
-            if(!patron.addresses()) {                                      
-                patron.addresses([]);                                      
-                patron.billing_address(null);                              
-                patron.mailing_address(null);
-                patron.ischanged(1);
-            }
-
-
-		} else {
-			address.isdeleted(1);
-		}
-	}
-
-	tbody.removeChild(row);
-
-	var bid = patron.billing_address();
-    bid = (bid != null && typeof bid == 'object') ? bid.id() : bid;
-
-	var mid = patron.mailing_address();
-    mid = (mid != null && typeof mid == 'object') ? mid.id() : mid;
-
-
-	/* -----------------------------------------------------------------------
-		if we're deleting a billing or mailing address 
-		make sure some other address is automatically
-		assigned as the billing or mailng address 
-		----------------------------------------------------------------------- */
-
-	if( bid == address.id() ) {
-		for( var a in patron.addresses() ) {
-			var addr = patron.addresses()[a];
-			if(!addr.isdeleted() && addr.id() != address.id()) {
-				var node = uEditFindAddrInput('billing', addr.id());
-				node.checked = true;
-				uEditAddrTypeClick(node, 'billing');
-				break;
-			}
-		}
-	}
-
-	if( mid == address.id() ) {
-		for( var a in patron.addresses() ) {
-			var addr = patron.addresses()[a];
-			if(!addr.isdeleted() && addr.id() != address.id()) {
-				var node = uEditFindAddrInput('mailing', addr.id());
-				node.checked = true;
-				uEditAddrTypeClick(node, 'mailing');
-				break;
-			}
-		}
-	}
-
-}
-
-function uEditApproveAddr( tbody, row, address ) {
-    if(!confirm($('ue_add_approve_confirm').innerHTML)) return;
-    var req = new Request(APPROVE_ADDR, SESSION, address);
-    req.callback(
-        function(r) {
-            var oldId = r.getResultObject();
-            if(oldId != null) {
-                // remove the replaced address 
-		        patron.addresses(
-			        grep( patron.addresses(), 
-				        function(i) { return (i.id() != oldId); }
-			        )
-		        );
-                // update the ID on the new address
-                address.id(oldId);
-                address.replaces(null);
-                address.pending('f');
-                removeChildren($('ue_address_tbody'));
-	            uEditBuildAddrs(patron);
-            }
-        }
-    );
-    req.send();
-}
-
-
-function uEditFindAddrInput(type, id) {
-	var tbody = $('ue_address_tbody');
-	var rows = tbody.getElementsByTagName('tr');
-	for( var r in rows ) {
-		var row = rows[r];
-		if(row.parentNode != tbody) continue;
-		var node = $n(row, 'ue_addr_'+type+'_yes');
-		if( node.getAttribute('address') == id )
-			return node;
-	}
-}
-
-
-function uEditAddrTypeClick(input, type) {
-	var tbody = $('ue_address_tbody');
-	var rows = tbody.getElementsByTagName('tr');
-	for( var r in rows ) {
-		var row = rows[r];
-		if(row.parentNode != tbody) continue;
-		var node = $n(row, 'ue_addr_'+type+'_yes');
-		removeCSSClass(node.parentNode,'addr_info_checked');
-	}
-
-	addCSSClass(input.parentNode,'addr_info_checked');
-	patron[type+'_address'](input.getAttribute('address'));
-	patron.ischanged(1);
-}
-
-
-
-
-/* Creates the field entries for an address object. */
-function uEditBuildAddrFields(patron, address) {
-
-	var tbody = $('ue_address_tbody');
-
-	var row	= tbody.appendChild(
-		uEditAddrTemplate.cloneNode(true));
-
-	uEditCheckSharedAddr(patron, address, tbody, row);
-    
-    // see if this is a pending address
-    if( isTrue(address.pending()) ) {
-        var button = $n(row, 'ue_addr_approve');
-        unHideMe(button);
-        button.onclick = function() { uEditApproveAddr( tbody, row, address ); }
-        var oldaddr = grep(patron.addresses(), function(a){return (a.id() == address.replaces());});
-        if(oldaddr) {
-            oldaddr = oldaddr[0];
-            unHideMe($n(row, 'ue_addr_replaced_row')); 
-            $n(row, 'ue_addr_replaced_div').innerHTML = 
-                $("patronStrings").getFormattedString(
-                    'web.staff.patron.ue.uedit_show_addr_replacement', [
-                    oldaddr.address_type(),
-                    oldaddr.street1(),
-                    oldaddr.street2(),
-                    oldaddr.city(),
-                    oldaddr.state(),
-                    oldaddr.post_code() 
-                ]);
-        }
-    }
-
-	$n(row, 'ue_addr_delete').onclick = 
-		function() { 
-			uEditDeleteAddr(tbody, row, address); 
-			uEditCheckErrors();
-		};
-
-	if( patron.billing_address() &&
-			address.id() == patron.billing_address().id() ) 
-		$n(row, 'ue_addr_billing_yes').checked = true;
-
-	if( patron.mailing_address() &&
-			address.id() == patron.mailing_address().id() ) 
-		$n(row, 'ue_addr_mailing_yes').checked = true;
-
-	$n(row, 'ue_addr_billing_yes').setAttribute('address', address.id());
-	$n(row, 'ue_addr_mailing_yes').setAttribute('address', address.id());
-
-	/* currently, non-owners cannot edit an address */
-	var disabled = (address.usr() != patron.id())
-
-	var fields = [
-		{ 
-			required : false,
-			object	: address, 
-			key		: 'address_type', 
-			widget	: {
-				base	: row,
-				name	: 'ue_addr_label',
-				type	: 'input',
-				disabled : disabled,
-			}
-		},
-		{ 
-			required : true,
-			object	: address, 
-			key		: 'street1', 
-			errkey	: 'ue_bad_addr_street',
-			widget	: {
-				base	: row,
-				name	: 'ue_addr_street1',
-				type	: 'input',
-				disabled : disabled,
-			}
-		},
-		{ 
-			required : false,
-			object	: address, 
-			key		: 'street2', 
-			errkey	: 'ue_bad_addr_street',
-			widget	: {
-				base	: row,
-				name	: 'ue_addr_street2',
-				type	: 'input',
-				disabled : disabled,
-			}
-		},
-		{ 
-			required : true,
-			object	: address, 
-			key		: 'city', 
-			errkey	: 'ue_bad_addr_city',
-			widget	: {
-				base	: row,
-				name	: 'ue_addr_city',
-				type	: 'input',
-				disabled : disabled,
-			}
-		},
-		{ 
-			required : false,
-			object	: address, 
-			key		: 'county', 
-			widget	: {
-				base	: row,
-				name	: 'ue_addr_county',
-				type	: 'input',
-				disabled : disabled,
-			}
-		},
-		{ 
-			required : true,
-			object	: address, 
-			key		: 'state', 
-			errkey	: 'ue_bad_addr_state',
-			widget	: {
-				base	: row,
-				name	: 'ue_addr_state',
-				type	: 'input',
-				disabled : disabled,
-			}
-		},
-		{ 
-			required : true,
-			object	: address, 
-			key		: 'country', 
-			errkey	: 'ue_bad_addr_country',
-			widget	: {
-				base	: row,
-				name	: 'ue_addr_country',
-				type	: 'input',
-				disabled : disabled,
-			}
-		},
-		{ 
-			required : true,
-			object	: address, 
-			key		: 'post_code',
-			errkey	: 'ue_bad_addr_zip',
-			widget	: {
-				base	: row,
-				name	: 'ue_addr_zip',
-				type	: 'input',
-				disabled : disabled,
-				regex	: laxRegex,
-				onblur : function(f) {
-					var v = uEditNodeVal(f);
-					var req = new Request(ZIP_SEARCH, v);
-					req.callback( 
-						function(r) {
-							var info = r.getResultObject();
-							if(!info) return;
-							var state = $n(f.widget.base, 'ue_addr_state');
-							var county = $n(f.widget.base, 'ue_addr_county');
-							var city = $n(f.widget.base, 'ue_addr_city');
-							state.value = info.state;
-							state.onchange();
-							county.value = info.county;
-							county.onchange();
-							city.value = info.city;
-							city.onchange();
-						}
-					);
-					req.send();
-				}
-			}
-		},
-		{ 
-			required : false,
-			object	: address, 
-			key		: 'within_city_limits',
-			widget	: {
-				base	: row,
-				name	: 'ue_addr_inc_yes',
-				type	: 'checkbox',
-				disabled : disabled,
-			}
-		},
-		{ 
-			required : false,
-			object	: address, 
-			key		: 'valid',
-			widget	: {
-				base	: row,
-				name	: 'ue_addr_valid_yes',
-				type	: 'checkbox',
-				disabled : disabled,
-			}
-		}
-	];
-
-	for( var f in fields ) {
-		dataFields.push(fields[f]);
-		uEditActivateField(fields[f]);
-	}
-}
-
-function uEditBuildPatronSCM(patron) {
-	/* get the list of pre-defined maps */
-	var fields = uEditFindFieldsByKey('stat_cat_entry');
-	var map;
-	var newmaps = [];
-
-	/* for each user stat cat, pop it off the list,
-	updated the existing stat map field to match
-	the popped map and shove the existing stat
-	map field onto the user's list of stat maps */
-	while( (map = patron.stat_cat_entries().pop()) ) {
-
-		var field = grep(fields, 
-			function(item) {
-				return (item.object.stat_cat() == map.stat_cat());
-			}
-		);
-
-		if(field) {
-			var val = map.stat_cat_entry();
-			field = field[0];
-			$n(field.widget.base, field.widget.name).value = val;
-			setSelector($n(field.widget.base, 'ue_stat_cat_selector'), val );
-			field.object.stat_cat_entry(val);
-			field.object.id(map.id());
-			newmaps.push(field.object);
-		}
-	}
-
-	for( var m in newmaps ) 
-		patron.stat_cat_entries().push(newmaps[m]);
-}
-
-
-function uEditBuildSCMField(statcat, row) {
-
-	var map = new actscecm();
-	map.stat_cat(statcat.id());
-	map.target_usr(patron.id());
-
-	var field = {
-		required : false,
-		object	: map,
-		key		: 'stat_cat_entry',
-		widget	: {
-			base	: row,
-			name	: 'ue_stat_cat_newval',
-			type	: 'input',
-
-			onpostchange : function( field, newval ) {
-
-				/* see if the current map already resides in 
-					the patron entry list */
-				var exists = grep( patron.stat_cat_entries(),
-					function(item) {
-						return (item.stat_cat() == statcat.id()); 
-					}
-				);
-
-				if(newval) {
-					map.isdeleted(0);
-					setSelector($n(row, 'ue_stat_cat_selector'), newval);
-				}
-
-				if(exists) {
-					if(!newval) {
-
-						/* if the map is new but currently contains no value
-							remove it from the set of new maps */
-						if(map.isnew()) {
-							patron.stat_cat_entries(
-								grep( patron.stat_cat_entries(),
-									function(item) {
-										return (item.stat_cat() != map.stat_cat());
-									}
-								)
-							);
-
-						} else {
-							map.isdeleted(1);
-							map.ischanged(0);
-						}
-					} 
-
-				} else {
-
-					/* map does not exist in the map array but now has data */
-					if(newval) { 
-						map.isnew(1);
-						if(!patron.stat_cat_entries())
-							patron.stat_cat_entries([]);
-						patron.stat_cat_entries().push(map);
-					}
-				}
-			}
-		}
-	}
-
-	dataFields.push(field);
-}
-
-
-
-/** Run this after a new ident type is selected */
-function _uEditIdentPostchange(type, field, newval) {
-
-	if(!newval) return;
-
-	/* When the ident type is changed, we change the
-	regex on the ident_value to match the selected type */
-	var vfname = 'ident_value';
-	if(type == 'secondary') vfname = 'ident_value2';
-	var vfield = uEditFindFieldByKey(vfname);
-	var name = identTypesCache[uEditNodeVal(field)].name();
-
-	hideMe($(type+'_ident_ssn_help'));
-	hideMe($(type+'_ident_dl_help'));
-
-	if(name.match(/ssn/i)) {
-		vfield.widget.regex = ssnRegex;
-		vfield.errkey = 'ue_bad_ident_ssn';
-		unHideMe($(type+'_ident_ssn_help'));
-
-	} else {
-
-		if(name.match(/driver/i)) {
-			vfield.widget.regex = dlRegex;
-			vfield.errkey = 'ue_bad_ident_dl';
-			unHideMe($(type+'_ident_dl_help'));
-			if(!uEditNodeVal(vfield))
-				vfield.widget.node.value = defaultState + '-';
-
-		} else {
-			vfield.widget.regex = null;
-			vfield.errkey = null;
-		}
-	}
-
-	/* focus then valdate the value field */
-	vfield.widget.node.onchange();
-	vfield.widget.node.focus();
-}
-
-
-/* checks to see if the given address is shared by others.
- * if so, the address row is styled and ...
- */
-
-function uEditCheckSharedAddr(patron, address, tbody, row) {
-
-	if( address.isnew() || (patron.isnew() && !clone) ) return;
-
-	var req = new Request(FETCH_ADDR_MEMS, SESSION, address.id());
-	req.callback( 
-		function(r) {
-
-			var members = r.getResultObject();
-			var shared = false;
-
-			for( var m in members ) {
-				var id = members[m];
-
-				if( id != patron.id() ) {
-
-					addCSSClass(row.getElementsByTagName('table')[0], 'shared_address');
-					unHideMe($n(row, 'shared_row'));
-					$n(row, 'ue_addr_delete').disabled = true;
-
-					if( address.usr() != patron.id() ) {
-						var button = $n(row, 'ue_addr_detach');
-						unHideMe(button);
-						button.onclick = 
-							function() { uEditDeleteAddr( tbody, row, address, true ); }
-					}
-
-					shared = true;
-					break;
-				}
-			}
-
-			if( shared ) {
-
-				/* if this is a shared address, set the owner field and 
-					give the staff a chance to edit the owner if it's not this user */
-
-				var nnode = $n(row, 'addr_owner_name');
-				var link = $n(row, 'addr_owner');
-				var id = address.usr();
-			
-				if( id == patron.id() ) {
-			
-					nnode.appendChild(text(
-						patron.first_given_name() + ' ' + patron.family_name()));
-					hideMe($n(row, 'owner_link_div'));
-			
-				} else {
-			
-					var ses = cgi.param('ses'); 
-					if (xulG) if (xulG.ses) ses = xulG.ses;
-					if (xulG) if (xulG.params) if (xulG.params.ses) ses = xulG.params.ses;
-					link.onclick = 
-						function() { window.xulG.spawn_editor({ses:ses,usr:id}) };
-				
-					if( userCache[id] ) {
-                        var usr = userCache[id];
-						nnode.appendChild(text(
-							usr.first_given_name() + ' ' +  usr.family_name()));
-				
-					} else {
-				
-						fetchFleshedUser( id, 
-							function(usr) {
-								userCache[usr.id()] = usr;
-								nnode.appendChild(text(
-									usr.first_given_name() + ' ' + usr.family_name()));
-							}
-						);
-					}
-				}
-			}
-		}
-	);
-
-	req.send();
-}
-
-
-
-
-var __lastdob;
-function uEditCheckDOB(field) {
-
-	var dob = uEditNodeVal(field);
-    var ident_field = uEditFindFieldByKey('ident_value2');
-
-    if(dob) {
-
-        /* don't bother if the data isn't valid */
-        if(!dob.match(field.widget.regex)) 
-            return;
-
-        if( dob == __lastdob ) return;
-
-        __lastdob = dob;
-
-        var parts = dob.split(/-/);
-        parts[2] = parts[2].replace(/[T ].*/,'');
-        dob = buildDate( parts[0], parts[1], parts[2] );
-
-        var today = new Date();
-
-        if(!dob || dob > today) {
-            addCSSClass(field.widget.node, CSS_INVALID_DATA);
-            alertId('ue_bad_date');
-            return;
-        }
-
-        var base = new Date();
-        var age;
-        if(orgSettings['global.juvenile_age_threshold'])
-            age = orgSettings['global.juvenile_age_threshold'].value;
-        else age = DEFAULT_ADULT_AGE;
-        base.setTime(base.getTime() - Number(interval_to_seconds(age) + '000'));
-
-
-        unHideMe(ident_field.widget.node.parentNode.parentNode.parentNode);
-        if( dob < base ) { /* patron is of age */
-            ident_field.required = false;
-	        uEditFindFieldByKey('juvenile').widget.node.checked = false;
-            if(!uEditNodeVal(ident_field))
-                hideMe(ident_field.widget.node.parentNode.parentNode.parentNode);
-            return;
-        }
-
-    } else {
-        // no DOB and we are not flagged as a juvenile
-        if(uEditFindFieldByKey('juvenile').widget.node.checked == false) {
-            if(!uEditNodeVal(ident_field))
-                hideMe(ident_field.widget.node.parentNode.parentNode.parentNode);
-            return;
-        }
-    }
-
-    unHideMe(ident_field.widget.node.parentNode.parentNode.parentNode);
-    if(!uEditFindFieldByKey('juvenile').widget.node.checked)
-	    uEditFindFieldByKey('juvenile').widget.node.checked = true;
-	ident_field.required = true;
-	uEditCheckErrors();
-}
-
-
-

Modified: conifer/branches/rel_2_0/xul/server/patron/util.js
===================================================================
--- conifer/branches/rel_2_0/xul/server/patron/util.js	2011-04-12 13:42:03 UTC (rev 1332)
+++ conifer/branches/rel_2_0/xul/server/patron/util.js	2011-04-12 13:54:03 UTC (rev 1333)
@@ -3,703 +3,726 @@
 if (typeof patron == 'undefined') var patron = {};
 patron.util = {};
 
-patron.util.EXPORT_OK	= [ 
-	'columns', 'mbts_columns', 'mb_columns', 'mp_columns', /*'std_map_row_to_column',*/ 'std_map_row_to_columns',
-	'retrieve_au_via_id', 'retrieve_fleshed_au_via_id', 'retrieve_fleshed_au_via_barcode', 'set_penalty_css', 'retrieve_name_via_id',
-    'merge', 'ausp_columns'
+patron.util.EXPORT_OK    = [ 
+    'columns', 'mbts_columns', 'mb_columns', 'mp_columns', /*'std_map_row_to_column',*/ 'std_map_row_to_columns',
+    'retrieve_au_via_id', 'retrieve_fleshed_au_via_id', 'retrieve_fleshed_au_via_barcode', 'set_penalty_css', 'retrieve_name_via_id',
+    'merge', 'ausp_columns', 'format_name', 'work_log_patron_edit'
 ];
-patron.util.EXPORT_TAGS	= { ':all' : patron.util.EXPORT_OK };
+patron.util.EXPORT_TAGS    = { ':all' : patron.util.EXPORT_OK };
 
 patron.util.mbts_columns = function(modify,params) {
 
-	JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
-	JSAN.use('util.money'); JSAN.use('util.date');
+    JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
+    JSAN.use('util.money'); JSAN.use('util.date');
 
     var commonStrings = document.getElementById('commonStrings');
 
-	var c = [
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'id', 'label' : commonStrings.getString('staff.mbts_id_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : false, 'render' : function(my) { return my.mbts.id(); }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'usr', 'label' : commonStrings.getString('staff.mbts_usr_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.mbts.usr() ? "Id = " + my.mbts.usr() : ""; }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'xact_type', 'label' : commonStrings.getString('staff.mbts_xact_type_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : false, 'render' : function(my) { return my.mbts.xact_type(); }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'balance_owed', 'label' : commonStrings.getString('staff.mbts_balance_owed_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : false, 'render' : function(my) { return util.money.sanitize( my.mbts.balance_owed() ); },
-			'sort_type' : 'money'
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'total_owed', 'label' : commonStrings.getString('staff.mbts_total_owed_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : false, 'render' : function(my) { return util.money.sanitize( my.mbts.total_owed() ); },
-			'sort_type' : 'money'
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'total_paid', 'label' : commonStrings.getString('staff.mbts_total_paid_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : false, 'render' : function(my) { return util.money.sanitize( my.mbts.total_paid() ); },
-			'sort_type' : 'money'
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'last_billing_note', 'label' : commonStrings.getString('staff.mbts_last_billing_note_label'), 'flex' : 2,
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.mbts.last_billing_note(); }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'last_billing_type', 'label' : commonStrings.getString('staff.mbts_last_billing_type_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.mbts.last_billing_type(); }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'last_billing_ts', 'label' : commonStrings.getString('staff.mbts_last_billing_timestamp_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return util.date.formatted_date( my.mbts.last_billing_ts(), "" ); }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'last_payment_note', 'label' : commonStrings.getString('staff.mbts_last_payment_note_label'), 'flex' : 2,
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.mbts.last_payment_note(); }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'last_payment_type', 'label' : commonStrings.getString('staff.mbts_last_payment_type_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.mbts.last_payment_type(); }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'last_payment_ts', 'label' : commonStrings.getString('staff.mbts_last_payment_timestamp_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return util.date.formatted_date( my.mbts.last_payment_ts(), "" ); }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'xact_start', 'label' : commonStrings.getString('staff.mbts_xact_start_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : false, 'render' : function(my) { return my.mbts.xact_start() ? my.mbts.xact_start().toString().substr(0,10) : ""; }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'xact_finish', 'label' : commonStrings.getString('staff.mbts_xact_finish_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : false, 'render' : function(my) { return my.mbts.xact_finish() ? my.mbts.xact_finish().toString().substr(0,10) : ""; }
-		},
-	];
-	for (var i = 0; i < c.length; i++) {
-		if (modify[ c[i].id ]) {
-			for (var j in modify[ c[i].id ]) {
-				c[i][j] = modify[ c[i].id ][j];
-			}
-		}
-	}
-	if (params) {
-		if (params.just_these) {
-			JSAN.use('util.functional');
-			var new_c = [];
-			for (var i = 0; i < params.just_these.length; i++) {
-				var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
-				new_c.push( function(y){ return y; }( x ) );
-			}
-			c = new_c;
-		}
-		if (params.except_these) {
-			JSAN.use('util.functional');
-			var new_c = [];
-			for (var i = 0; i < c.length; i++) {
-				var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
-				if (!x) new_c.push(c[i]);
-			}
-			c = new_c;
-		}
-	}
-	return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
+    var c = [
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'mbts_id', 'label' : commonStrings.getString('staff.mbts_id_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return my.mbts.id(); }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'usr', 'label' : commonStrings.getString('staff.mbts_usr_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.mbts.usr() ? "Id = " + my.mbts.usr() : ""; }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'xact_type', 'label' : commonStrings.getString('staff.mbts_xact_type_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return my.mbts.xact_type(); }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'balance_owed', 'label' : commonStrings.getString('staff.mbts_balance_owed_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return util.money.sanitize( my.mbts.balance_owed() ); },
+            'sort_type' : 'money'
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'total_owed', 'label' : commonStrings.getString('staff.mbts_total_owed_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return util.money.sanitize( my.mbts.total_owed() ); },
+            'sort_type' : 'money'
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'total_paid', 'label' : commonStrings.getString('staff.mbts_total_paid_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return util.money.sanitize( my.mbts.total_paid() ); },
+            'sort_type' : 'money'
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'last_billing_note', 'label' : commonStrings.getString('staff.mbts_last_billing_note_label'), 'flex' : 2,
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.mbts.last_billing_note(); }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'last_billing_type', 'label' : commonStrings.getString('staff.mbts_last_billing_type_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.mbts.last_billing_type(); }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'last_billing_ts', 'label' : commonStrings.getString('staff.mbts_last_billing_timestamp_label'), 'flex' : 1,
+            'sort_type' : 'date',
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.mbts.last_billing_ts(), "%{localized}" ); }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'last_payment_note', 'label' : commonStrings.getString('staff.mbts_last_payment_note_label'), 'flex' : 2,
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.mbts.last_payment_note(); }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'last_payment_type', 'label' : commonStrings.getString('staff.mbts_last_payment_type_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.mbts.last_payment_type(); }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'last_payment_ts', 'label' : commonStrings.getString('staff.mbts_last_payment_timestamp_label'), 'flex' : 1,
+            'sort_type' : 'date',
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.mbts.last_payment_ts(), "%{localized}" ); }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'mbts_xact_start', 'label' : commonStrings.getString('staff.mbts_xact_start_label'), 'flex' : 1,
+            'sort_type' : 'date',
+            'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return my.mbts.xact_start() ? util.date.formatted_date( my.mbts.xact_start(), "%{localized}" ) : ""; }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'mbts_xact_finish', 'label' : commonStrings.getString('staff.mbts_xact_finish_label'), 'flex' : 1,
+            'sort_type' : 'date',
+            'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return my.mbts.xact_finish() ? util.date.formatted_date( my.mbts.xact_finish(), "%{localized}" ) : ""; }
+        },
+    ];
+    for (var i = 0; i < c.length; i++) {
+        if (modify[ c[i].id ]) {
+            for (var j in modify[ c[i].id ]) {
+                c[i][j] = modify[ c[i].id ][j];
+            }
+        }
+    }
+    if (params) {
+        if (params.just_these) {
+            JSAN.use('util.functional');
+            var new_c = [];
+            for (var i = 0; i < params.just_these.length; i++) {
+                var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
+                new_c.push( function(y){ return y; }( x ) );
+            }
+            c = new_c;
+        }
+        if (params.except_these) {
+            JSAN.use('util.functional');
+            var new_c = [];
+            for (var i = 0; i < c.length; i++) {
+                var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
+                if (!x) new_c.push(c[i]);
+            }
+            c = new_c;
+        }
+    }
+    return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
 }
 
 patron.util.mb_columns = function(modify,params) {
 
-	JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
-	JSAN.use('util.money'); JSAN.use('util.date');
+    JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
+    JSAN.use('util.money'); JSAN.use('util.date');
 
     var commonStrings = document.getElementById('commonStrings');
 
-	var c = [
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'id', 'label' : commonStrings.getString('staff.mb_id_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.mb.id(); }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'voided', 'label' : commonStrings.getString('staff.mb_voided_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : false, 'render' : function(my) { return get_bool( my.mb.voided() ) ? "Yes" : "No"; }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'voider', 'label' : commonStrings.getString('staff.mb_voider_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.mb.voider() ? "Id = " + my.mb.voider() : ""; }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'void_time', 'label' : commonStrings.getString('staff.mb_void_time_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.mb.void_time(); }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'amount', 'label' : commonStrings.getString('staff.mb_amount_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : false, 'render' : function(my) { return util.money.sanitize( my.mb.amount() ); },
-			'sort_type' : 'money'
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'billing_type', 'label' : commonStrings.getString('staff.mb_billing_type_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : false, 'render' : function(my) { return my.mb.billing_type(); }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'billing_ts', 'label' : commonStrings.getString('staff.mb_billing_ts_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : false, 'render' : function(my) { return util.date.formatted_date( my.mb.billing_ts(), "" ); }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'note', 'label' : commonStrings.getString('staff.mb_note_label'), 'flex' : 2,
-			'primary' : false, 'hidden' : false, 'render' : function(my) { return my.mb.note(); }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'xact', 'label' : commonStrings.getString('staff.mb_xact_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.mb.xact(); }
-		},
-	];
-	for (var i = 0; i < c.length; i++) {
-		if (modify[ c[i].id ]) {
-			for (var j in modify[ c[i].id ]) {
-				c[i][j] = modify[ c[i].id ][j];
-			}
-		}
-	}
-	if (params) {
-		if (params.just_these) {
-			JSAN.use('util.functional');
-			var new_c = [];
-			for (var i = 0; i < params.just_these.length; i++) {
-				var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
-				new_c.push( function(y){ return y; }( x ) );
-			}
-			c = new_c;
-		}
-		if (params.except_these) {
-			JSAN.use('util.functional');
-			var new_c = [];
-			for (var i = 0; i < c.length; i++) {
-				var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
-				if (!x) new_c.push(c[i]);
-			}
-			c = new_c;
-		}
+    var c = [
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'mb_id', 'label' : commonStrings.getString('staff.mb_id_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.mb.id(); }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'voided', 'label' : commonStrings.getString('staff.mb_voided_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return get_bool( my.mb.voided() ) ? "Yes" : "No"; }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'voider', 'label' : commonStrings.getString('staff.mb_voider_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.mb.voider() ? "Id = " + my.mb.voider() : ""; }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'void_time', 'label' : commonStrings.getString('staff.mb_void_time_label'), 'flex' : 1,
+            'sort_type' : 'date',
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.mb.void_time(), "%{localized}" ); }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'amount', 'label' : commonStrings.getString('staff.mb_amount_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return util.money.sanitize( my.mb.amount() ); },
+            'sort_type' : 'money'
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'billing_type', 'label' : commonStrings.getString('staff.mb_billing_type_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return my.mb.billing_type(); }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'billing_ts', 'label' : commonStrings.getString('staff.mb_billing_ts_label'), 'flex' : 1,
+            'sort_type' : 'date',
+            'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.mb.billing_ts(), "%{localized}" ); }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'note', 'label' : commonStrings.getString('staff.mb_note_label'), 'flex' : 2,
+            'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return my.mb.note(); }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'xact', 'label' : commonStrings.getString('staff.mb_xact_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.mb.xact(); }
+        },
+    ];
+    for (var i = 0; i < c.length; i++) {
+        if (modify[ c[i].id ]) {
+            for (var j in modify[ c[i].id ]) {
+                c[i][j] = modify[ c[i].id ][j];
+            }
+        }
+    }
+    if (params) {
+        if (params.just_these) {
+            JSAN.use('util.functional');
+            var new_c = [];
+            for (var i = 0; i < params.just_these.length; i++) {
+                var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
+                new_c.push( function(y){ return y; }( x ) );
+            }
+            c = new_c;
+        }
+        if (params.except_these) {
+            JSAN.use('util.functional');
+            var new_c = [];
+            for (var i = 0; i < c.length; i++) {
+                var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
+                if (!x) new_c.push(c[i]);
+            }
+            c = new_c;
+        }
 
-	}
-	return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
+    }
+    return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
 }
 
 patron.util.mp_columns = function(modify,params) {
 
-	JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
-	JSAN.use('util.money'); JSAN.use('util.date'); JSAN.use('patron.util');
+    JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
+    JSAN.use('util.money'); JSAN.use('util.date'); JSAN.use('patron.util');
 
     var commonStrings = document.getElementById('commonStrings');
 
-	var c = [
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'mp_id', 'label' : commonStrings.getString('staff.mp_id_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.mp.id(); }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'mp_amount', 'label' : commonStrings.getString('staff.mp_amount_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : false, 'render' : function(my) { return util.money.sanitize( my.mp.amount() ); },
-			'sort_type' : 'money'
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'mp_payment_type', 'label' : commonStrings.getString('staff.mp_payment_type_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : false, 'render' : function(my) { return my.mp.payment_type(); }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'mp_payment_ts', 'label' : commonStrings.getString('staff.mp_payment_timestamp_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : false, 'render' : function(my) { return util.date.formatted_date( my.mp.payment_ts(), "" ); }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'mp_note', 'label' : commonStrings.getString('staff.mp_note_label'), 'flex' : 2,
-			'primary' : false, 'hidden' : false, 'render' : function(my) { return my.mp.note(); }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'mp_ws', 'label' : commonStrings.getString('staff.mp_cash_drawer_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : false, 'render' : function(my) { return my.mp.cash_drawer().name(); }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'mp_staff', 'label' : commonStrings.getString('staff.mp_accepting_usr_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : false, 'render' : function(my) { var s = my.mp.accepting_usr(); if (s && typeof s != "object") s = patron.util.retrieve_fleshed_au_via_id(ses(),s); return s.family_name() + " (" + s.card().barcode() + ") @ " + data.hash.aou[ s.home_ou() ].shortname(); }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'mp_xact', 'label' : commonStrings.getString('staff.mp_xact_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.mp.xact(); }
-		},
-	];
-	for (var i = 0; i < c.length; i++) {
-		if (modify[ c[i].id ]) {
-			for (var j in modify[ c[i].id ]) {
-				c[i][j] = modify[ c[i].id ][j];
-			}
-		}
-	}
-	if (params) {
-		if (params.just_these) {
-			JSAN.use('util.functional');
-			var new_c = [];
-			for (var i = 0; i < params.just_these.length; i++) {
-				var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
-				new_c.push( function(y){ return y; }( x ) );
-			}
-			c = new_c;
-		}
-		if (params.except_these) {
-			JSAN.use('util.functional');
-			var new_c = [];
-			for (var i = 0; i < c.length; i++) {
-				var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
-				if (!x) new_c.push(c[i]);
-			}
-			c = new_c;
-		}
+    var c = [
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'mp_id', 'label' : commonStrings.getString('staff.mp_id_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.mp.id(); }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'mp_amount', 'label' : commonStrings.getString('staff.mp_amount_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return util.money.sanitize( my.mp.amount() ); },
+            'sort_type' : 'money'
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'mp_payment_type', 'label' : commonStrings.getString('staff.mp_payment_type_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return my.mp.payment_type(); }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'mp_payment_ts', 'label' : commonStrings.getString('staff.mp_payment_timestamp_label'), 'flex' : 1,
+            'sort_type' : 'date',
+            'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.mp.payment_ts(), "%{localized}" ); }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'mp_note', 'label' : commonStrings.getString('staff.mp_note_label'), 'flex' : 2,
+            'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return my.mp.note(); }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'mp_ws', 'label' : commonStrings.getString('staff.mp_cash_drawer_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return my.mp.cash_drawer().name(); }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'mp_staff', 'label' : commonStrings.getString('staff.mp_accepting_usr_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { var s = my.mp.accepting_usr(); if (s && typeof s != "object") s = patron.util.retrieve_fleshed_au_via_id(ses(),s,["card"]); return s.family_name() + " (" + s.card().barcode() + ") @ " + data.hash.aou[ s.home_ou() ].shortname(); }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'mp_xact', 'label' : commonStrings.getString('staff.mp_xact_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.mp.xact(); }
+        },
+    ];
+    for (var i = 0; i < c.length; i++) {
+        if (modify[ c[i].id ]) {
+            for (var j in modify[ c[i].id ]) {
+                c[i][j] = modify[ c[i].id ][j];
+            }
+        }
+    }
+    if (params) {
+        if (params.just_these) {
+            JSAN.use('util.functional');
+            var new_c = [];
+            for (var i = 0; i < params.just_these.length; i++) {
+                var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
+                new_c.push( function(y){ return y; }( x ) );
+            }
+            c = new_c;
+        }
+        if (params.except_these) {
+            JSAN.use('util.functional');
+            var new_c = [];
+            for (var i = 0; i < c.length; i++) {
+                var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
+                if (!x) new_c.push(c[i]);
+            }
+            c = new_c;
+        }
 
-	}
-	return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
+    }
+    return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
 }
 
 patron.util.ausp_columns = function(modify,params) {
 
-	JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
+    JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
     JSAN.use('util.functional');
 
     var commonStrings = document.getElementById('commonStrings');
 
-	var c = [
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'csp_id', 'label' : commonStrings.getString('staff.csp_id_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.csp.id(); }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'csp_name', 'label' : commonStrings.getString('staff.csp_name_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : false, 'render' : function(my) { return my.csp.name(); }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'csp_label', 'label' : commonStrings.getString('staff.csp_label_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : false, 'render' : function(my) { return my.csp.label(); }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'csp_block_list', 'label' : commonStrings.getString('staff.csp_block_list_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.csp.block_list(); }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'csp_block_circ', 'label' : commonStrings.getString('staff.csp_block_circ_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : true, 'render' : function(my) { 
-                return String( my.csp.block_list() ).match('CIRC') ? commonStrings.getString('staff.csp_block_circ_yes') : commonStrings.getString('staff.csp_block_circ_no'); 
+    var c = [
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'csp_id', 'label' : commonStrings.getString('staff.csp_id_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return typeof my.csp == 'object' ? my.csp.id() : my.csp; }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'csp_name', 'label' : commonStrings.getString('staff.csp_name_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return typeof my.csp == 'object' ? my.csp.name() : data.hash.csp[ my.csp ].name(); }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'csp_label', 'label' : commonStrings.getString('staff.csp_label_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return typeof my.csp == 'object' ? my.csp.label() : data.hash.csp[ my.csp ].label(); }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'csp_block_list', 'label' : commonStrings.getString('staff.csp_block_list_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return typeof my.csp == 'object' ? my.csp.block_list() : data.hash.csp[ my.csp ].block_list(); }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'csp_block_circ', 'label' : commonStrings.getString('staff.csp_block_circ_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { 
+                var my_csp = typeof my.csp == 'object' ? my.csp : data.hash.csp[ my.csp ];
+                return String( my_csp.block_list() ).match('CIRC') ? commonStrings.getString('staff.csp_block_circ_yes') : commonStrings.getString('staff.csp_block_circ_no'); 
             }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'csp_block_renew', 'label' : commonStrings.getString('staff.csp_block_renew_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : true, 'render' : function(my) { 
-                return String( my.csp.block_list() ).match('RENEW') ? commonStrings.getString('staff.csp_block_renew_yes') : commonStrings.getString('staff.csp_block_renew_no'); 
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'csp_block_renew', 'label' : commonStrings.getString('staff.csp_block_renew_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { 
+                var my_csp = typeof my.csp == 'object' ? my.csp : data.hash.csp[ my.csp ];
+                return String( my_csp.block_list() ).match('RENEW') ? commonStrings.getString('staff.csp_block_renew_yes') : commonStrings.getString('staff.csp_block_renew_no'); 
 
             }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'csp_block_hold', 'label' : commonStrings.getString('staff.csp_block_hold_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : true, 'render' : function(my) { 
-                return String( my.csp.block_list() ).match('HOLD') ?  commonStrings.getString('staff.csp_block_hold_yes') : commonStrings.getString('staff.csp_block_hold_no'); 
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'csp_block_hold', 'label' : commonStrings.getString('staff.csp_block_hold_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { 
+                var my_csp = typeof my.csp == 'object' ? my.csp : data.hash.csp[ my.csp ];
+                return String( my_csp.block_list() ).match('HOLD') ?  commonStrings.getString('staff.csp_block_hold_yes') : commonStrings.getString('staff.csp_block_hold_no'); 
             }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'ausp_staff', 'label' : commonStrings.getString('staff.ausp_staff_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : true, 'render' : function(my) { 
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'ausp_id', 'label' : commonStrings.getString('staff.ausp_id_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.ausp ? my.ausp.id() : ''; }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'ausp_staff', 'label' : commonStrings.getString('staff.ausp_staff_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { 
                 return my.ausp ? my.ausp.staff() : '';
             }
         },
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'ausp_set_date', 'label' : commonStrings.getString('staff.ausp_set_date_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : false, 'render' : function(my) { 
-                return my.ausp ? my.ausp.set_date() : '';
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'ausp_set_date', 'label' : commonStrings.getString('staff.ausp_set_date_label'), 'flex' : 1,
+            'sort_type' : 'date',
+            'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { 
+                return my.ausp ? util.date.formatted_date( my.ausp.set_date(), "%{localized}" ) : '';
             }
         },
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'ausp_note', 'label' : commonStrings.getString('staff.ausp_note_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : false, 'render' : function(my) { 
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'ausp_note', 'label' : commonStrings.getString('staff.ausp_note_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { 
                 return my.ausp ? my.ausp.note() : '';
             }
         },
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'ausp_org_unit', 'label' : commonStrings.getString('staff.ausp_org_unit_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : false, 'render' : function(my) { 
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'ausp_org_unit', 'label' : commonStrings.getString('staff.ausp_org_unit_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { 
                 return my.ausp ? data.hash.aou[ my.ausp.org_unit() ].shortname() : '';
             }
         }
-	];
-	for (var i = 0; i < c.length; i++) {
-		if (modify[ c[i].id ]) {
-			for (var j in modify[ c[i].id ]) {
-				c[i][j] = modify[ c[i].id ][j];
-			}
-		}
-	}
-	if (params) {
-		if (params.just_these) {
-			var new_c = [];
-			for (var i = 0; i < params.just_these.length; i++) {
-				var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
-				new_c.push( function(y){ return y; }( x ) );
-			}
-			c = new_c;
-		}
-		if (params.except_these) {
-			var new_c = [];
-			for (var i = 0; i < c.length; i++) {
-				var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
-				if (!x) new_c.push(c[i]);
-			}
-			c = new_c;
-		}
+    ];
+    for (var i = 0; i < c.length; i++) {
+        if (modify[ c[i].id ]) {
+            for (var j in modify[ c[i].id ]) {
+                c[i][j] = modify[ c[i].id ][j];
+            }
+        }
+    }
+    if (params) {
+        if (params.just_these) {
+            var new_c = [];
+            for (var i = 0; i < params.just_these.length; i++) {
+                var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
+                new_c.push( function(y){ return y; }( x ) );
+            }
+            c = new_c;
+        }
+        if (params.except_these) {
+            var new_c = [];
+            for (var i = 0; i < c.length; i++) {
+                var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
+                if (!x) new_c.push(c[i]);
+            }
+            c = new_c;
+        }
 
-	}
-	return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
+    }
+    return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
 }
 
 
 patron.util.columns = function(modify,params) {
-	
-	JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
+    
+    JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
 
     var commonStrings = document.getElementById('commonStrings');
 
-	var c = [
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'barcode', 'label' : commonStrings.getString('staff.card_barcode_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.au.card().barcode(); }
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'usrname', 'label' : commonStrings.getString('staff.au_usrname_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.au.usrname(); }
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'profile', 'label' : commonStrings.getString('staff.au_profile_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return data.hash.pgt[ my.au.profile() ].name(); }
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'active', 'label' : commonStrings.getString('staff.au_active_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return get_bool( my.au.active() ) ? "Yes" : "No"; }
-		},
-		{
-			'persist' : 'hidden width ordinal', 'id' : 'barred', 'label' : commonStrings.getString('staff.au_barred_label'), 'flex' : 1,
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return get_bool( my.au.barred() ) ? "Yes" : "No"; }
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'id', 'label' : document.getElementById('commonStrings').getString('staff.au_id_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.au.id(); }
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'prefix', 'label' : document.getElementById('commonStrings').getString('staff.au_name_prefix_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.au.prefix(); }
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'family_name', 'label' : document.getElementById('commonStrings').getString('staff.au_family_name_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.au.family_name(); }
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'first_given_name', 'label' : document.getElementById('commonStrings').getString('staff.au_first_given_name_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.au.first_given_name(); }
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'second_given_name', 'label' : document.getElementById('commonStrings').getString('staff.au_second_given_name_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.au.second_given_name(); }
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'suffix', 'label' : document.getElementById('commonStrings').getString('staff.au_name_suffix_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.au.suffix(); }
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'alert_message', 'label' : commonStrings.getString('staff.au_alert_message_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.au.alert_message(); }
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'claims_returned_count', 'label' : commonStrings.getString('staff.au_claims_returned_count_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.au.claims_returned_count(); },
-			'sort_type' : 'number'
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'create_date', 'label' : commonStrings.getString('staff.au_create_date_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.au.create_date(); }
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'expire_date', 'label' : commonStrings.getString('staff.au_expire_date_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.au.expire_date().substr(0,10); }
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'home_ou', 'label' : commonStrings.getString('staff.au_home_library_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return data.hash.aou[ my.au.home_ou() ].shortname(); }
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'home_ou_fullname', 'label' : commonStrings.getString('staff.au_home_library_fullname_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return data.hash.aou[ my.au.home_ou() ].name(); }
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'credit_forward_balance', 'label' : commonStrings.getString('staff.au_credit_forward_balance_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.au.credit_forward_balance(); },
-			'sort_type' : 'money'
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'day_phone', 'label' : commonStrings.getString('staff.au_day_phone_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.au.day_phone(); }
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'evening_phone', 'label' : commonStrings.getString('staff.au_evening_phone_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.au.evening_phone(); }
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'other_phone', 'label' : commonStrings.getString('staff.au_other_phone_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.au.other_phone(); }
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'email', 'label' : commonStrings.getString('staff.au_email_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.au.email(); }
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'alias', 'label' : commonStrings.getString('staff.au_alias_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.au.alias(); }
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'dob', 'label' : commonStrings.getString('staff.au_birth_date_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.au.dob().substr(0,10); }
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'ident_type', 'label' : commonStrings.getString('staff.au_ident_type_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return data.hash.cit[ my.au.ident_type() ].name(); }
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'ident_value', 'label' : commonStrings.getString('staff.au_ident_value_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.au.ident_value(); }
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'ident_type2', 'label' : commonStrings.getString('staff.au_ident_type2_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return data.hash.cit[ my.au.ident_type2() ].name(); }
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'ident_value2', 'label' : commonStrings.getString('staff.au_ident_value2_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.au.ident_value2(); }
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'net_access_level', 'label' : commonStrings.getString('staff.au_net_access_level_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.au.net_access_level(); }
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'master_account', 'label' : commonStrings.getString('staff.au_master_account_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return get_bool( my.au.master_account() ) ? "Yes" : "No"; }
-		},
-		{ 
-			'persist' : 'hidden width ordinal', 'id' : 'usrgroup', 'label' : commonStrings.getString('staff.au_group_id_label'), 'flex' : 1, 
-			'primary' : false, 'hidden' : true, 'render' : function(my) { return my.au.usrgroup(); }
-		},
-	];
-	for (var i = 0; i < c.length; i++) {
-		if (modify[ c[i].id ]) {
-			for (var j in modify[ c[i].id ]) {
-				c[i][j] = modify[ c[i].id ][j];
-			}
-		}
-	}
-	if (params) {
-		if (params.just_these) {
-			JSAN.use('util.functional');
-			var new_c = [];
-			for (var i = 0; i < params.just_these.length; i++) {
-				var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
-				new_c.push( function(y){ return y; }( x ) );
-			}
-			c = new_c;
-		}
-		if (params.except_these) {
-			JSAN.use('util.functional');
-			var new_c = [];
-			for (var i = 0; i < c.length; i++) {
-				var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
-				if (!x) new_c.push(c[i]);
-			}
-			c = new_c;
-		}
+    var c = [
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'au_barcode', 'label' : commonStrings.getString('staff.card_barcode_label'), 'flex' : 1, 
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.card().barcode(); }
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'usrname', 'label' : commonStrings.getString('staff.au_usrname_label'), 'flex' : 1, 
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.usrname(); }
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'profile', 'label' : commonStrings.getString('staff.au_profile_label'), 'flex' : 1, 
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return data.hash.pgt[ my.au.profile() ].name(); }
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'active', 'label' : commonStrings.getString('staff.au_active_label'), 'flex' : 1, 
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return get_bool( my.au.active() ) ? "Yes" : "No"; }
+        },
+        {
+            'persist' : 'hidden width ordinal', 'id' : 'barred', 'label' : commonStrings.getString('staff.au_barred_label'), 'flex' : 1,
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return get_bool( my.au.barred() ) ? "Yes" : "No"; }
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'au_id', 'label' : document.getElementById('commonStrings').getString('staff.au_id_label'), 'flex' : 1, 
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.id(); }
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'prefix', 'label' : document.getElementById('commonStrings').getString('staff.au_name_prefix_label'), 'flex' : 1, 
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.prefix(); }
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'family_name', 'label' : document.getElementById('commonStrings').getString('staff.au_family_name_label'), 'flex' : 1, 
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.family_name(); }
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'first_given_name', 'label' : document.getElementById('commonStrings').getString('staff.au_first_given_name_label'), 'flex' : 1, 
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.first_given_name(); }
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'second_given_name', 'label' : document.getElementById('commonStrings').getString('staff.au_second_given_name_label'), 'flex' : 1, 
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.second_given_name(); }
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'suffix', 'label' : document.getElementById('commonStrings').getString('staff.au_name_suffix_label'), 'flex' : 1, 
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.suffix(); }
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'au_alert_message', 'label' : commonStrings.getString('staff.au_alert_message_label'), 'flex' : 1, 
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.alert_message(); }
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'claims_returned_count', 'label' : commonStrings.getString('staff.au_claims_returned_count_label'), 'flex' : 1, 
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.claims_returned_count(); },
+            'sort_type' : 'number'
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'au_create_date', 'label' : commonStrings.getString('staff.au_create_date_label'), 'flex' : 1, 
+            'sort_type' : 'date',
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.au.create_date(), "%{localized}" ); }
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'expire_date', 'label' : commonStrings.getString('staff.au_expire_date_label'), 'flex' : 1, 
+            'sort_type' : 'date',
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.au.expire_date(), "%{localized_date}" ); }
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'home_ou', 'label' : commonStrings.getString('staff.au_home_library_label'), 'flex' : 1, 
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return data.hash.aou[ my.au.home_ou() ].shortname(); }
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'home_ou_fullname', 'label' : commonStrings.getString('staff.au_home_library_fullname_label'), 'flex' : 1, 
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return data.hash.aou[ my.au.home_ou() ].name(); }
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'credit_forward_balance', 'label' : commonStrings.getString('staff.au_credit_forward_balance_label'), 'flex' : 1, 
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.credit_forward_balance(); },
+            'sort_type' : 'money'
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'day_phone', 'label' : commonStrings.getString('staff.au_day_phone_label'), 'flex' : 1, 
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.day_phone(); }
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'evening_phone', 'label' : commonStrings.getString('staff.au_evening_phone_label'), 'flex' : 1, 
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.evening_phone(); }
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'other_phone', 'label' : commonStrings.getString('staff.au_other_phone_label'), 'flex' : 1, 
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.other_phone(); }
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'email', 'label' : commonStrings.getString('staff.au_email_label'), 'flex' : 1, 
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.email(); }
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'alias', 'label' : commonStrings.getString('staff.au_alias_label'), 'flex' : 1, 
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.alias(); }
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'dob', 'label' : commonStrings.getString('staff.au_birth_date_label'), 'flex' : 1, 
+            'sort_type' : 'date',
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.au.dob(), "%{localized_date}" ); }
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'ident_type', 'label' : commonStrings.getString('staff.au_ident_type_label'), 'flex' : 1, 
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return data.hash.cit[ my.au.ident_type() ].name(); }
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'ident_value', 'label' : commonStrings.getString('staff.au_ident_value_label'), 'flex' : 1, 
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.ident_value(); }
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'ident_type2', 'label' : commonStrings.getString('staff.au_ident_type2_label'), 'flex' : 1, 
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return data.hash.cit[ my.au.ident_type2() ].name(); }
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'ident_value2', 'label' : commonStrings.getString('staff.au_ident_value2_label'), 'flex' : 1, 
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.ident_value2(); }
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'net_access_level', 'label' : commonStrings.getString('staff.au_net_access_level_label'), 'flex' : 1, 
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.net_access_level(); }
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'master_account', 'label' : commonStrings.getString('staff.au_master_account_label'), 'flex' : 1, 
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return get_bool( my.au.master_account() ) ? "Yes" : "No"; }
+        },
+        { 
+            'persist' : 'hidden width ordinal', 'id' : 'usrgroup', 'label' : commonStrings.getString('staff.au_group_id_label'), 'flex' : 1, 
+            'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.usrgroup(); }
+        },
+    ];
+    for (var i = 0; i < c.length; i++) {
+        if (modify[ c[i].id ]) {
+            for (var j in modify[ c[i].id ]) {
+                c[i][j] = modify[ c[i].id ][j];
+            }
+        }
+    }
+    if (params) {
+        if (params.just_these) {
+            JSAN.use('util.functional');
+            var new_c = [];
+            for (var i = 0; i < params.just_these.length; i++) {
+                var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
+                new_c.push( function(y){ return y; }( x ) );
+            }
+            c = new_c;
+        }
+        if (params.except_these) {
+            JSAN.use('util.functional');
+            var new_c = [];
+            for (var i = 0; i < c.length; i++) {
+                var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
+                if (!x) new_c.push(c[i]);
+            }
+            c = new_c;
+        }
 
-	}
-	return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
+    }
+    return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
 }
 
 patron.util.std_map_row_to_columns = function(error_value) {
-	return function(row,cols) {
-		// row contains { 'my' : { 'au' : {} } }
-		// cols contains all of the objects listed above in columns
-		
-		var obj = {}; obj.OpenILS = {}; 
-		JSAN.use('util.error'); obj.error = new util.error();
-		JSAN.use('OpenILS.data'); obj.OpenILS.data = new OpenILS.data(); obj.OpenILS.data.init({'via':'stash'});
-		JSAN.use('util.date'); JSAN.use('util.money');
+    return function(row,cols) {
+        // row contains { 'my' : { 'au' : {} } }
+        // cols contains all of the objects listed above in columns
+        
+        var obj = {}; obj.OpenILS = {}; 
+        JSAN.use('util.error'); obj.error = new util.error();
+        JSAN.use('OpenILS.data'); obj.OpenILS.data = new OpenILS.data(); obj.OpenILS.data.init({'via':'stash'});
+        JSAN.use('util.date'); JSAN.use('util.money');
 
-		var my = row.my;
-		var values = [];
-		var cmd = '';
-		try { 
-			for (var i = 0; i < cols.length; i++) {
-				switch (typeof cols[i].render) {
-					case 'function': try { values[i] = cols[i].render(my); } catch(E) { values[i] = error_value; obj.error.sdump('D_COLUMN_RENDER_ERROR',E); } break;
-					case 'string' : cmd += 'try { ' + cols[i].render + '; values['+i+'] = v; } catch(E) { values['+i+'] = error_value; }'; break;
-					default: cmd += 'values['+i+'] = "??? '+(typeof cols[i].render)+'"; ';
-				}
-			}
-			if (cmd) eval( cmd );
-		} catch(E) {
-			obj.error.sdump('D_WARN','map_row_to_column: ' + E);
-			if (error_value) { value = error_value; } else { value = '   ' };
-		}
-		return values;
-	}
+        var my = row.my;
+        var values = [];
+        var cmd = '';
+        try { 
+            for (var i = 0; i < cols.length; i++) {
+                switch (typeof cols[i].render) {
+                    case 'function': try { values[i] = cols[i].render(my); } catch(E) { values[i] = error_value; obj.error.sdump('D_COLUMN_RENDER_ERROR',E); } break;
+                    case 'string' : cmd += 'try { ' + cols[i].render + '; values['+i+'] = v; } catch(E) { values['+i+'] = error_value; }'; break;
+                    default: cmd += 'values['+i+'] = "??? '+(typeof cols[i].render)+'"; ';
+                }
+            }
+            if (cmd) eval( cmd );
+        } catch(E) {
+            obj.error.sdump('D_WARN','map_row_to_column: ' + E);
+            if (error_value) { value = error_value; } else { value = '   ' };
+        }
+        return values;
+    }
 }
 
 patron.util.retrieve_au_via_id = function(session, id, f) {
-	JSAN.use('util.network');
-	var network = new util.network();
-	var patron_obj = network.simple_request(
-		'FM_AU_RETRIEVE_VIA_ID',
-		[ session, id ],
-		f
-	);
-	return patron_obj;
+    JSAN.use('util.network');
+    var network = new util.network();
+    var patron_obj = network.simple_request(
+        'FM_AU_RETRIEVE_VIA_ID.authoritative',
+        [ session, id ],
+        f
+    );
+    return patron_obj;
 }
 
 patron.util.retrieve_name_via_id = function(session, id) {
-	JSAN.use('util.network');
-	var network = new util.network();
-	var parts = network.simple_request(
-		'BLOB_AU_PARTS_RETRIEVE',
-		[ session, id, ['family_name', 'first_given_name', 'second_given_name', 'home_ou' ] ]
-	);
-	return parts;
+    JSAN.use('util.network');
+    var network = new util.network();
+    var parts = network.simple_request(
+        'BLOB_AU_PARTS_RETRIEVE',
+        [ session, id, ['family_name', 'first_given_name', 'second_given_name', 'home_ou' ] ]
+    );
+    return parts;
 }
 
-patron.util.retrieve_fleshed_au_via_id = function(session, id) {
-	JSAN.use('util.network');
-	var network = new util.network();
-	var patron_obj = network.simple_request(
-		'FM_AU_FLESHED_RETRIEVE_VIA_ID',
-		[ session, id ]
-	);
-	patron.util.set_penalty_css(patron_obj);
-	return patron_obj;
+patron.util.retrieve_fleshed_au_via_id = function(session, id, fields, func) {
+    JSAN.use('util.network');
+    var network = new util.network();
+    var patron_obj = network.simple_request(
+        'FM_AU_FLESHED_RETRIEVE_VIA_ID.authoritative',
+        [ session, id, fields ],
+        typeof func == 'function' ? func : null
+    );
+    if (typeof func != 'function') {
+        if (!fields) { patron.util.set_penalty_css(patron_obj); }
+        return patron_obj;
+    }
 }
 
 patron.util.retrieve_fleshed_au_via_barcode = function(session, id) {
-	JSAN.use('util.network');
-	var network = new util.network();
-	var patron_obj = network.simple_request(
-		'FM_AU_RETRIEVE_VIA_BARCODE.authoritative',
-		[ session, id ]
-	);
-	patron.util.set_penalty_css(patron_obj);
-	return patron_obj;
+    JSAN.use('util.network');
+    var network = new util.network();
+    var patron_obj = network.simple_request(
+        'FM_AU_RETRIEVE_VIA_BARCODE.authoritative',
+        [ session, id ]
+    );
+    if (typeof patron_obj.ilsevent == 'undefined') patron.util.set_penalty_css(patron_obj);
+    return patron_obj;
 }
 
 var TIME = { minute : 60, hour : 60*60, day : 60*60*24, year : 60*60*24*365 };
 
 patron.util.set_penalty_css = function(patron) {
-	try {
-							removeCSSClass(document.documentElement,'PATRON_HAS_BILLS');
-							removeCSSClass(document.documentElement,'PATRON_HAS_OVERDUES');
-							removeCSSClass(document.documentElement,'PATRON_HAS_NOTES');
-							removeCSSClass(document.documentElement,'PATRON_EXCEEDS_CHECKOUT_COUNT');
-							removeCSSClass(document.documentElement,'PATRON_EXCEEDS_OVERDUE_COUNT');
-							removeCSSClass(document.documentElement,'PATRON_EXCEEDS_FINES');
-							removeCSSClass(document.documentElement,'NO_PENALTIES');
-							removeCSSClass(document.documentElement,'ONE_PENALTY');
-							removeCSSClass(document.documentElement,'MULTIPLE_PENALTIES');
-							removeCSSClass(document.documentElement,'PATRON_HAS_ALERT');
-							removeCSSClass(document.documentElement,'PATRON_BARRED');
-							removeCSSClass(document.documentElement,'PATRON_INACTIVE');
-							removeCSSClass(document.documentElement,'PATRON_EXPIRED');
-							removeCSSClass(document.documentElement,'PATRON_HAS_INVALID_DOB');
-							removeCSSClass(document.documentElement,'PATRON_HAS_INVALID_ADDRESS');
-							removeCSSClass(document.documentElement,'PATRON_AGE_GE_65');
-							removeCSSClass(document.documentElement,'PATRON_AGE_LT_65');
-							removeCSSClass(document.documentElement,'PATRON_AGE_GE_24');
-							removeCSSClass(document.documentElement,'PATRON_AGE_LT_24');
-							removeCSSClass(document.documentElement,'PATRON_AGE_GE_21');
-							removeCSSClass(document.documentElement,'PATRON_AGE_LT_21');
-							removeCSSClass(document.documentElement,'PATRON_AGE_GE_18');
-							removeCSSClass(document.documentElement,'PATRON_AGE_LT_18');
-							removeCSSClass(document.documentElement,'PATRON_AGE_GE_13');
-							removeCSSClass(document.documentElement,'PATRON_AGE_LT_13');
-							removeCSSClass(document.documentElement,'PATRON_NET_ACCESS_1');
-							removeCSSClass(document.documentElement,'PATRON_NET_ACCESS_2');
-							removeCSSClass(document.documentElement,'PATRON_NET_ACCESS_3');
+    try {
+        removeCSSClass(document.documentElement,'PATRON_HAS_BILLS');
+        removeCSSClass(document.documentElement,'PATRON_HAS_OVERDUES');
+        removeCSSClass(document.documentElement,'PATRON_HAS_NOTES');
+        removeCSSClass(document.documentElement,'PATRON_EXCEEDS_CHECKOUT_COUNT');
+        removeCSSClass(document.documentElement,'PATRON_EXCEEDS_OVERDUE_COUNT');
+        removeCSSClass(document.documentElement,'PATRON_EXCEEDS_FINES');
+        removeCSSClass(document.documentElement,'NO_PENALTIES');
+        removeCSSClass(document.documentElement,'ONE_PENALTY');
+        removeCSSClass(document.documentElement,'MULTIPLE_PENALTIES');
+        removeCSSClass(document.documentElement,'PATRON_HAS_ALERT');
+        removeCSSClass(document.documentElement,'PATRON_BARRED');
+        removeCSSClass(document.documentElement,'PATRON_INACTIVE');
+        removeCSSClass(document.documentElement,'PATRON_EXPIRED');
+        removeCSSClass(document.documentElement,'PATRON_HAS_INVALID_DOB');
+        removeCSSClass(document.documentElement,'PATRON_HAS_INVALID_ADDRESS');
+        removeCSSClass(document.documentElement,'PATRON_AGE_GE_65');
+        removeCSSClass(document.documentElement,'PATRON_AGE_LT_65');
+        removeCSSClass(document.documentElement,'PATRON_AGE_GE_24');
+        removeCSSClass(document.documentElement,'PATRON_AGE_LT_24');
+        removeCSSClass(document.documentElement,'PATRON_AGE_GE_21');
+        removeCSSClass(document.documentElement,'PATRON_AGE_LT_21');
+        removeCSSClass(document.documentElement,'PATRON_AGE_GE_18');
+        removeCSSClass(document.documentElement,'PATRON_AGE_LT_18');
+        removeCSSClass(document.documentElement,'PATRON_AGE_GE_13');
+        removeCSSClass(document.documentElement,'PATRON_AGE_LT_13');
+        removeCSSClass(document.documentElement,'PATRON_NET_ACCESS_1');
+        removeCSSClass(document.documentElement,'PATRON_NET_ACCESS_2');
+        removeCSSClass(document.documentElement,'PATRON_NET_ACCESS_3');
 
-		JSAN.use('util.network'); var net = new util.network();
-		net.simple_request('FM_MOUS_RETRIEVE.authoritative',[ ses(), patron.id() ], function(req) {
-			if (req.getResultObject().balance_owed() > 0) addCSSClass(document.documentElement,'PATRON_HAS_BILLS');
-		});
-		net.simple_request('FM_CIRC_COUNT_RETRIEVE_VIA_USER.authoritative',[ ses(), patron.id() ], function(req) {
-			try {
-				var co = req.getResultObject();
-				if (co.overdue > 0 || co.long_overdue > 0) addCSSClass(document.documentElement,'PATRON_HAS_OVERDUES');
-			} catch(E) {
-				alert(E);
-			}
-		});
-		net.simple_request('FM_AUN_RETRIEVE_ALL.authoritative',[ ses(), { 'patronid' : patron.id() } ], function(req) {
-			var notes = req.getResultObject();
-			if (notes.length > 0) addCSSClass(document.documentElement,'PATRON_HAS_NOTES');
-		});
+        JSAN.use('util.network'); var net = new util.network();
+        net.simple_request('FM_MOUS_RETRIEVE.authoritative',[ ses(), patron.id() ], function(req) {
+            var summary = req.getResultObject();
+            if (summary && summary.balance_owed() > 0) addCSSClass(document.documentElement,'PATRON_HAS_BILLS');
+        });
+        net.simple_request('FM_CIRC_COUNT_RETRIEVE_VIA_USER.authoritative',[ ses(), patron.id() ], function(req) {
+            try {
+                var co = req.getResultObject();
+                if (co.overdue > 0 || co.long_overdue > 0) addCSSClass(document.documentElement,'PATRON_HAS_OVERDUES');
+            } catch(E) {
+                alert(E);
+            }
+        });
+        net.simple_request('FM_AUN_RETRIEVE_ALL.authoritative',[ ses(), { 'patronid' : patron.id() } ], function(req) {
+            var notes = req.getResultObject();
+            if (notes.length > 0) addCSSClass(document.documentElement,'PATRON_HAS_NOTES');
+        });
 
-		/*
-		JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
-		data.last_patron = patron.id(); data.stash('last_patron');
-		*/
+        /*
+        JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
+        data.last_patron = patron.id(); data.stash('last_patron');
+        */
 
-		var penalties = patron.standing_penalties();
-		for (var i = 0; i < penalties.length; i++) {
-			/* this comes from /opac/common/js/utils.js */
-			addCSSClass(document.documentElement,penalties[i].standing_penalty().name());
-		}
+        var penalties = patron.standing_penalties();
+        if (!penalties) { penalties = []; }
+        for (var i = 0; i < penalties.length; i++) {
+            /* this comes from /opac/common/js/utils.js */
+            addCSSClass(document.documentElement,penalties[i].standing_penalty().name());
+        }
 
-		switch(penalties.length) {
-			case 0: addCSSClass(document.documentElement,'NO_PENALTIES'); break;
-			case 1: addCSSClass(document.documentElement,'ONE_PENALTY'); break;
-			default: addCSSClass(document.documentElement,'MULTIPLE_PENALTIES'); break;
-		}
+        switch(penalties.length) {
+            case 0: addCSSClass(document.documentElement,'NO_PENALTIES'); break;
+            case 1: addCSSClass(document.documentElement,'ONE_PENALTY'); break;
+            default: addCSSClass(document.documentElement,'MULTIPLE_PENALTIES'); break;
+        }
 
-		if (patron.alert_message()) {
-			addCSSClass(document.documentElement,'PATRON_HAS_ALERT');
-		}
+        if (patron.alert_message()) {
+            addCSSClass(document.documentElement,'PATRON_HAS_ALERT');
+        }
 
-		if (get_bool( patron.barred() )) {
-			addCSSClass(document.documentElement,'PATRON_BARRED');
-		}
+        if (get_bool( patron.barred() )) {
+            addCSSClass(document.documentElement,'PATRON_BARRED');
+        }
 
-		if (!get_bool( patron.active() )) {
-			addCSSClass(document.documentElement,'PATRON_INACTIVE');
-		}
+        if (!get_bool( patron.active() )) {
+            addCSSClass(document.documentElement,'PATRON_INACTIVE');
+        }
 
-		var now = new Date();
-		now = now.getTime()/1000;
+        var now = new Date();
+        now = now.getTime()/1000;
 
-		var expire_parts = patron.expire_date().substr(0,10).split('-');
-		expire_parts[1] = expire_parts[1] - 1;
+        var expire_parts = patron.expire_date().substr(0,10).split('-');
+        expire_parts[1] = expire_parts[1] - 1;
 
-		var expire = new Date();
-		expire.setFullYear(expire_parts[0], expire_parts[1], expire_parts[2]);
-		expire = expire.getTime()/1000
+        var expire = new Date();
+        expire.setFullYear(expire_parts[0], expire_parts[1], expire_parts[2]);
+        expire = expire.getTime()/1000
 
-		if (expire < now) addCSSClass(document.documentElement,'PATRON_EXPIRED');
+        if (expire < now) addCSSClass(document.documentElement,'PATRON_EXPIRED');
 
-		if (patron.mailing_address()) {
-			if (!get_bool(patron.mailing_address().valid())) {
-				addCSSClass(document.documentElement,'PATRON_HAS_INVALID_ADDRESS');
-			}
-		}
-		if (patron.billing_address()) {
-			if (!get_bool(patron.billing_address().valid())) {
-				addCSSClass(document.documentElement,'PATRON_HAS_INVALID_ADDRESS');
-			}
-		}
+        if (patron.mailing_address() && typeof patron.mailing_address() == 'object') {
+            if (!get_bool(patron.mailing_address().valid())) {
+                addCSSClass(document.documentElement,'PATRON_HAS_INVALID_ADDRESS');
+            }
+        }
+        if (patron.billing_address() && typeof patron.billing_address() == 'object') {
+            if (!get_bool(patron.billing_address().valid())) {
+                addCSSClass(document.documentElement,'PATRON_HAS_INVALID_ADDRESS');
+            }
+        }
 
-	} catch(E) {
-		dump('patron.util.set_penalty_css: ' + E + '\n');
-		alert('patron.util.set_penalty_css: ' + E + '\n');
-	}
+    } catch(E) {
+        dump('patron.util.set_penalty_css: ' + E + '\n');
+        alert('patron.util.set_penalty_css: ' + E + '\n');
+    }
 }
 
 patron.util.merge = function(record_ids) {
@@ -707,6 +730,8 @@
     try {
         netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
         JSAN.use('util.error'); error = new util.error();
+        JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.stash_retrieve();
+        var horizontal_interface = String( data.hash.aous['ui.circ.patron_summary.horizontal'] ) == 'true';
         var top_xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" >';
         top_xml += '<description>' + $("patronStrings").getString('staff.patron.usr_buckets.merge_records.merge_lead') + '</description>';
         top_xml += '<hbox>';
@@ -716,24 +741,47 @@
                 + $("patronStrings").getString('staff.patron.usr_buckets.merge_records.cancel_button.accesskey') +'" name="fancy_cancel"/></hbox></vbox>';
 
         var xml = '<form xmlns="http://www.w3.org/1999/xhtml">';
-        xml += '<table><tr valign="top">';
-        for (var i = 0; i < record_ids.length; i++) {
+        xml += '<table>';
+
+        function table_cell_with_lead_button(id) {
+            var xml = '';
             xml += '<td><input value="' + $("patronStrings").getString('staff.patron.usr_buckets.merge_records.lead')
-            xml += '" id="record_' + record_ids[i] + '" type="radio" name="lead"';
+            xml += '" id="record_' + id + '" type="radio" name="lead"';
             xml += ' onclick="' + "try { var x = $('lead'); x.setAttribute('value',";
-            xml += record_ids[i] + '); x.disabled = false; } catch(E) { alert(E); }">';
-            xml += '</input>' + $("patronStrings").getFormattedString('staff.patron.usr_buckets.merge_records.lead_record_number',[record_ids[i]]) + '</td>';
+            xml += id + '); x.disabled = false; } catch(E) { alert(E); }">';
+            xml += '</input>' + $("patronStrings").getFormattedString('staff.patron.usr_buckets.merge_records.lead_record_number',[id]) + '</td>';
+            return xml;
         }
-        xml += '</tr><tr valign="top">';
+
+        var iframe_css;
+        if (!horizontal_interface) {
+            xml += '<tr valign="top">';
+            for (var i = 0; i < record_ids.length; i++) {
+                xml += table_cell_with_lead_button( record_ids[i] );
+            }
+            xml += '</tr><tr valign="top">';
+            iframe_css = 'min-height: 1000px; min-width: 300px;';
+        } else {
+            iframe_css = 'min-height: 200px; min-width: 1000px;';
+        }
         for (var i = 0; i < record_ids.length; i++) {
-            xml += '<td nowrap="nowrap"><iframe style="min-height: 1000px; min-width: 300px" flex="1" src="' + urls.XUL_PATRON_SUMMARY; 
+            if (horizontal_interface) {
+                xml += '<tr valign="top">' + table_cell_with_lead_button( record_ids[i] );
+            }
+            xml += '<td nowrap="nowrap"><iframe style="' + iframe_css + '" flex="1" src="' + urls.XUL_PATRON_SUMMARY; 
             xml += '?id=' + record_ids[i] + '&amp;show_name=1"/></td>';
+            if (horizontal_interface) {
+                xml += '</tr>';
+            }
         }
-        xml += '</tr></table></form>';
+        if (!horizontal_interface) {
+            xml += '</tr>';
+        }
+        xml += '</table></form>';
         JSAN.use('util.window'); var win = new util.window();
         var fancy_prompt_data = win.open(
             urls.XUL_FANCY_PROMPT,
-            'fancy_prompt', 'chrome,resizable,modal,width=750,height=500',
+            'fancy_prompt', 'chrome,resizable,modal,width=1000,height=700',
             {
                 'top_xml' : top_xml, 'xml' : xml, 'title' : $("patronStrings").getString('staff.patron.usr_buckets.merge_records.fancy_prompt_title')
             }
@@ -759,10 +807,44 @@
         if (Number(robj) != 1) { throw(robj); }
         return fancy_prompt_data.lead;
     } catch(E) {
-		dump('patron.util.merge: ' + js2JSON(E) + '\n');
+        dump('patron.util.merge: ' + js2JSON(E) + '\n');
         try { error.standard_unexpected_error_alert('Error in patron.util.merge',E); } catch(F) { alert('patron.util.merge: ' + E + '\n'); }
         return false;
     }
 }
 
+patron.util.format_name = function(patron_obj) {
+    var patron_name = ( patron_obj.prefix() ? patron_obj.prefix() + ' ' : '') +
+        patron_obj.family_name() + ', ' +
+        patron_obj.first_given_name() + ' ' +
+        ( patron_obj.second_given_name() ? patron_obj.second_given_name() + ' ' : '' ) +
+        ( patron_obj.suffix() ? patron_obj.suffix() : ''); 
+    return patron_name;
+}
+
+patron.util.work_log_patron_edit = function(p) {
+    var error;
+    try {
+        netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
+        JSAN.use('util.error'); error = new util.error();
+        error.work_log(
+            document.getElementById('patronStrings').getFormattedString(
+                'staff.circ.work_log_patron_edit.message',
+                [
+                    ses('staff_usrname'),
+                    p.family_name(),
+                    p.card().barcode()
+                ]
+            ), {
+                'au_id' : p.id(),
+                'au_family_name' : p.family_name(),
+                'au_barcode' : p.card().barcode()
+            }
+        );
+    } catch(E) {
+        error.sdump('D_ERROR','Error with work_logging in menu.js, cmd_patron_register:' + E);
+    }
+}
+
+
 dump('exiting patron/util.js\n');



More information about the open-ils-commits mailing list