]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/ui/default/actor/user/register.js
fixed editing number widgets, setting ischanged on user
[working/Evergreen.git] / Open-ILS / web / js / ui / default / actor / user / register.js
1 dojo.require('dojo.data.ItemFileReadStore');
2 dojo.require('dijit.form.Textarea');
3 dojo.require('dijit.form.FilteringSelect');
4 dojo.require('dijit.form.ComboBox');
5 dojo.require('fieldmapper.IDL');
6 dojo.require('openils.PermaCrud');
7 dojo.require('openils.widget.AutoGrid');
8 dojo.require('openils.widget.AutoFieldWidget');
9 dojo.require('dijit.form.CheckBox');
10 dojo.require('dijit.form.Button');
11 dojo.require('dojo.date');
12 dojo.require('openils.CGI');
13
14 var pcrud;
15 var fmClasses = ['au', 'ac', 'aua', 'actsc', 'asv', 'asvq', 'asva'];
16 var fieldDoc = {};
17 var statCats;
18 var statCatTempate;
19 var surveys;
20 var staff;
21 var patron;
22 var uEditUsePhonePw = false;
23 var widgetPile = [];
24 var uEditCardVirtId = -1;
25 var uEditAddrVirtId = -1;
26 var orgSettings = {};
27 var tbody;
28 var addrTemplateRows;
29 var cgi;
30
31
32 function load() {
33     staff = new openils.User().user;
34     pcrud = new openils.PermaCrud();
35     cgi = new openils.CGI();
36     uEditLoadUser(cgi.param('usr'));
37
38     orgSettings = fieldmapper.aou.fetchOrgSettingBatch(staff.ws_ou(), [
39         'global.juvenile_age_threshold',
40         'patron.password.use_phone',
41     ]);
42     for(k in orgSettings)
43         orgSettings[k] = orgSettings[k].value;
44
45     var list = pcrud.search('fdoc', {fm_class:fmClasses});
46     for(var i in list) {
47         var doc = list[i];
48         if(!fieldDoc[doc.fm_class()])
49             fieldDoc[doc.fm_class()] = {};
50         fieldDoc[doc.fm_class()][doc.field()] = doc;
51     }
52
53     tbody = dojo.byId('uedit-tbody');
54
55     addrTemplateRows = dojo.query('tr[type=addr-template]', tbody);
56     dojo.forEach(addrTemplateRows, function(row) { row.parentNode.removeChild(row); } );
57     statCatTemplate = tbody.removeChild(dojo.byId('stat-cat-row-template'));
58     surveyTemplate = tbody.removeChild(dojo.byId('survey-row-template'));
59     surveyQuestionTemplate = tbody.removeChild(dojo.byId('survey-question-row-template'));
60
61     loadStaticFields();
62     if(patron.isnew()) 
63         uEditNewAddr(null, uEditAddrVirtId);
64     else loadAllAddrs();
65     loadStatCats();
66     loadSurveys();
67 }
68
69 function uEditLoadUser(userId) {
70     if(!userId) return uEditNewPatron();
71     patron = fieldmapper.standardRequest(
72         ['open-ils.actor', 'open-ils.actor.user.fleshed.retrieve'],
73         {params : [openils.User.authtoken, cgi.param('usr')]}
74     );
75 }
76
77 function loadStaticFields() {
78     for(var idx = 0; tbody.childNodes[idx]; idx++) {
79         var row = tbody.childNodes[idx];
80         if(row.nodeType != row.ELEMENT_NODE) continue;
81         var fmcls = row.getAttribute('fmclass');
82         if(!fmcls) continue;
83         fleshFMRow(row, fmcls);
84     }
85 }
86
87 function loadAllAddrs() {
88     dojo.forEach(patron.addresses(),
89         function(addr) {
90             uEditNewAddr(null, addr.id());
91         }
92     );
93 }
94
95 function loadStatCats() {
96
97     statCats = fieldmapper.standardRequest(
98         ['open-ils.circ', 'open-ils.circ.stat_cat.actor.retrieve.all'],
99         {params : [openils.User.authtoken, staff.ws_ou()]}
100     );
101
102     // draw stat cats
103     for(var idx in statCats) {
104         var stat = statCats[idx];
105         var row = statCatTemplate.cloneNode(true);
106         row.id = 'stat-cat-row-' + idx;
107         tbody.appendChild(row);
108         getByName(row, 'name').innerHTML = stat.name();
109         var valtd = getByName(row, 'widget');
110         var span = valtd.appendChild(document.createElement('span'));
111         var store = new dojo.data.ItemFileReadStore(
112                 {data:fieldmapper.actsc.toStoreData(stat.entries())});
113         var comboBox = new dijit.form.ComboBox({store:store}, span);
114         comboBox.labelAttr = 'value';
115         comboBox.searchAttr = 'value';
116
117         comboBox._wtype = 'statcat';
118         comboBox._statcat = stat.id();
119         widgetPile.push(comboBox); 
120
121         // populate existing cats
122         var map = patron.stat_cat_entries().filter(
123             function(mp) { return (mp.stat_cat() == stat.id()) })[0];
124         if(map) comboBox.attr('value', map.stat_cat_entry()); 
125
126     }
127 }
128
129 function loadSurveys() {
130
131     surveys = fieldmapper.standardRequest(
132         ['open-ils.circ', 'open-ils.circ.survey.retrieve.all'],
133         {params : [openils.User.authtoken]}
134     );
135
136     // draw surveys
137     for(var idx in surveys) {
138         var survey = surveys[idx];
139         var srow = surveyTemplate.cloneNode(true);
140         tbody.appendChild(srow);
141         getByName(srow, 'name').innerHTML = survey.name();
142
143         for(var q in survey.questions()) {
144             var quest = survey.questions()[q];
145             var qrow = surveyQuestionTemplate.cloneNode(true);
146             tbody.appendChild(qrow);
147             getByName(qrow, 'question').innerHTML = quest.question();
148
149             var span = getByName(qrow, 'answers').appendChild(document.createElement('span'));
150             var store = new dojo.data.ItemFileReadStore(
151                 {data:fieldmapper.asva.toStoreData(quest.answers())});
152             var select = new dijit.form.FilteringSelect({store:store}, span);
153             select.labelAttr = 'answer';
154             select.searchAttr = 'answer';
155
156             select._wtype = 'survey';
157             select._survey = survey.id();
158             select._question = quest.id();
159             widgetPile.push(select); 
160         }
161     }
162 }
163
164
165 function fleshFMRow(row, fmcls, args) {
166     var fmfield = row.getAttribute('fmfield');
167     var wclass = row.getAttribute('wclass');
168     var wstyle = row.getAttribute('wstyle');
169     var fieldIdl = fieldmapper.IDL.fmclasses[fmcls].field_map[fmfield];
170     if(!args) args = {};
171
172     var existing = dojo.query('td', row);
173     var htd = existing[0] || row.appendChild(document.createElement('td'));
174     var ltd = existing[1] || row.appendChild(document.createElement('td'));
175     var wtd = existing[2] || row.appendChild(document.createElement('td'));
176
177     openils.Util.addCSSClass(htd, 'uedit-help');
178     if(fieldDoc[fmcls] && fieldDoc[fmcls][fmfield]) {
179         var link = dojo.byId('uedit-help-template').cloneNode(true);
180         link.id = '';
181         link.onclick = function() { ueLoadContextHelp(fmcls, fmfield) };
182         openils.Util.removeCSSClass(link, 'hidden');
183         htd.appendChild(link);
184     }
185
186     if(!ltd.textContent) {
187         var span = document.createElement('span');
188         ltd.appendChild(document.createTextNode(fieldIdl.label));
189     }
190
191     span = document.createElement('span');
192     wtd.appendChild(span);
193
194     var fmObject = null;
195     switch(fmcls) {
196         case 'au' : fmObject = patron; break;
197         case 'ac' : fmObject = patron.card(); break;
198         case 'aua' : 
199             fmObject = patron.addresses().filter(
200                 function(i) { return (i.id() == args.addr) })[0];
201             break;
202     }
203     
204     var widget = new openils.widget.AutoFieldWidget({
205         idlField : fieldIdl,
206         fmObject : fmObject,
207         fmClass : fmcls,
208         parentNode : span,
209         widgetClass : wclass,
210         dijitArgs : {style: wstyle},
211         orgLimitPerms : ['UPDATE_USER'],
212     });
213
214     widget.build();
215     widget._wtype = fmcls;
216     widget._fmfield = fmfield;
217     widget._addr = args.addr;
218     widgetPile.push(widget);
219     attachWidgetEvents(fmcls, fmfield, widget);
220     return widget;
221 }
222
223 function findWidget(wtype, fmfield) {
224     return widgetPile.filter(
225         function(i){
226             return (i._wtype == wtype && i._fmfield == fmfield);
227         }
228     ).pop();
229 }
230
231 function attachWidgetEvents(fmcls, fmfield, widget) {
232
233     if(fmcls == 'ac') {
234         if(fmfield == 'barcode') {
235             dojo.connect(widget.widget, 'onChange',
236                 function() {
237                     var un = findWidget('au', 'usrname');
238                     if(!un.widget.attr('value'))
239                         un.widget.attr('value', this.attr('value'));
240                 }
241             );
242         }
243     }
244
245     if(fmcls == 'au') {
246         switch(fmfield) {
247
248             case 'profile': // when the profile changes, update the expire date
249                 dojo.connect(widget.widget, 'onChange', 
250                     function() {
251                         var self = this;
252                         var expireWidget = findWidget('au', 'expire_date');
253                         function found(items) {
254                             if(items.length == 0) return;
255                             var item = items[0];
256                             var interval = self.store.getValue(item, 'perm_interval');
257                             expireWidget.widget.attr('value', dojo.date.add(new Date(), 
258                                 'second', openils.Util.intervalToSeconds(interval)));
259                         }
260                         this.store.fetch({onComplete:found, query:{id:this.attr('value')}});
261                     }
262                 );
263         }
264     }
265 }
266
267 function getByName(node, name) {
268     return dojo.query('[name='+name+']', node)[0];
269 }
270
271
272 function ueLoadContextHelp(fmcls, fmfield) {
273     openils.Util.removeCSSClass(dojo.byId('uedit-help-div'), 'hidden');
274     dojo.byId('uedit-help-field').innerHTML = fieldmapper.IDL.fmclasses[fmcls].field_map[fmfield].label;
275     dojo.byId('uedit-help-text').innerHTML = fieldDoc[fmcls][fmfield].string();
276 }
277
278
279 /* creates a new patron object with card attached */
280 function uEditNewPatron() {
281     patron = new au();
282     patron.isnew(1);
283     patron.id(-1);
284     card = new ac();
285     card.id(uEditCardVirtId);
286     card.isnew(1);
287     patron.card(card);
288     patron.cards([card]);
289     //patron.net_access_level(defaultNetLevel); XXX
290     patron.stat_cat_entries([]);
291     patron.survey_responses([]);
292     patron.addresses([]);
293     //patron.home_ou(USER.ws_ou()); XXX
294     uEditMakeRandomPw(patron);
295 }
296
297 function uEditMakeRandomPw(patron) {
298     if(uEditUsePhonePw) return;
299     var rand  = Math.random();
300     rand = parseInt(rand * 10000) + '';
301     while(rand.length < 4) rand += '0';
302 /*
303     appendClear($('ue_password_plain'),text(rand));
304     unHideMe($('ue_password_gen'));
305 */
306     patron.passwd(rand);
307     return rand;
308 }
309
310 function uEditWidgetVal(w) {
311     var val = (w.getFormattedValue) ? w.getFormattedValue() : w.attr('value');
312     if(val === '') val = null;
313     return val;
314 }
315
316 function uEditSave() {
317     for(var idx in widgetPile) {
318         var w = widgetPile[idx];
319         var val = uEditWidgetVal(w);
320
321         switch(w._wtype) {
322             case 'au':
323                 patron[w._fmfield](val);
324                 break;
325
326             case 'ac':
327                 patron.card()[w._fmfield](val);
328                 break;
329
330             case 'aua':
331                 var addr = patron.addresses().filter(function(i){return (i.id() == w._addr)})[0];
332                 if(!addr) {
333                     addr = new fieldmapper.aua();
334                     addr.id(w._addr);
335                     addr.isnew(1);
336                     addr.usr(patron.id());
337                     patron.addresses().push(addr);
338                 } else {
339                     if(addr[w._fmfield]() != val)
340                         addr.ischanged(1);
341                 }
342                 addr[w._fmfield](val);
343                 break;
344
345             case 'survey':
346                 if(val == null) break;
347                 var resp = new fieldmapper.asvr();
348                 resp.isnew(1);
349                 resp.survey(w._survey)
350                 resp.usr(patron.id());
351                 resp.question(w._question)
352                 resp.answer(val);
353                 patron.survey_responses().push(resp);
354                 break;
355
356             case 'statcat':
357                 if(val == null) break;
358
359                 var map = patron.stat_cat_entries().filter(
360                     function(m){
361                         return (m.stat_cat() == w._statcat) })[0];
362
363                 if(map) {
364                     if(map.stat_cat_entry() == val) 
365                         break;
366                     map.ischanged(1);
367                 } else {
368                     map = new fieldmapper.actscecm();
369                     map.isnew(1);
370                 }
371
372                 map.stat_cat(w._statcat);
373                 map.stat_cat_entry(val);
374                 map.target_usr(patron.id());
375                 patron.stat_cat_entries().push(map);
376                 break;
377         }
378     }
379
380     patron.ischanged(1);
381     fieldmapper.standardRequest(
382         ['open-ils.actor', 'open-ils.actor.patron.update'],
383         {   async: true,
384             params: [openils.User.authtoken, patron],
385             oncomplete: function(r) {
386                 patron = openils.Util.readResponse(r);
387                 if(patron) {
388                     uEditRefresh();
389                 } 
390             }
391         }
392     );
393 }
394
395 function uEditRefresh() {
396     var href = location.href;
397     href = href.replace(/\&?clone=\d+/, '');
398     location.href = href;
399 }
400
401 function uEditNewAddr(evt, id) {
402     if(id == null) id = --uEditAddrVirtId;
403     dojo.forEach(addrTemplateRows, 
404         function(row) {
405             row = tbody.insertBefore(row.cloneNode(true), dojo.byId('new-addr-row'));
406             row.setAttribute('type', '');
407             row.setAttribute('addr', id+'');
408             if(row.getAttribute('fmclass')) {
409                 fleshFMRow(row, 'aua', {addr:id});
410             } else {
411                var btn = dojo.query('[name=delete-button]', row)[0];
412                if(btn) btn.onclick = function(){ uEditDeleteAddr(id) };
413             }
414         }
415     );
416 }
417
418
419 function uEditDeleteAddr(id) {
420     if(!confirm('Delete address ' + id)) return; /* XXX i18n */
421     var rows = dojo.query('tr[addr='+id+']', tbody);
422     for(var i = 0; i < rows.length; i++)
423         rows[i].parentNode.removeChild(rows[i]);
424     widgetPile = widgetPile.filter(function(w){return (w._addr != id)});
425 }
426
427 function uEditToggleRequired() {
428     if((tbody.className +'').match(/hide-non-required/))
429         openils.Util.removeCSSClass(tbody, 'hide-non-required');
430     else
431         openils.Util.addCSSClass(tbody, 'hide-non-required');
432 }
433
434
435
436 openils.Util.addOnLoad(load);