]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/web/js/dojo/openils/conify/BestHoldOrder.js
LP#1869794 new best hold sort order
[Evergreen.git] / Open-ILS / web / js / dojo / openils / conify / BestHoldOrder.js
1 if (!dojo._hasResource["openils.conify.BestHoldOrder"]) {
2     dojo.requireLocalization("openils.conify", "conify");
3
4     dojo._hasResource["openils.conify.BestHoldOrder"] = true;
5     dojo.provide("openils.conify.BestHoldOrder");
6     dojo.provide("openils.conify.SetOrderer");
7
8     dojo.require("dojo.string");
9     dojo.require("openils.Util");
10     dojo.require("openils.User");
11     dojo.require("openils.PermaCrud");
12     dojo.require("openils.widget.AutoFieldWidget");
13
14 (function() {
15     var localeStrings =
16         dojo.i18n.getLocalization("openils.conify", "conify");
17
18     /* This helper module is OO. */
19     dojo.declare(
20         "openils.conify.SetOrderer", null, {
21             "constructor": function(select, field_map, format_string) {
22                 this.select = select;   /* HTML <select> node */
23                 this.field_map = field_map; /* object of id:label pairs */
24                 this.format_string = format_string || "[${0}] ${1}";
25             },
26
27             "clear": function() {
28                 dojo.forEach(
29                     this.select.options,
30                     dojo.hitch(
31                         this, function(o) { this.select.options.remove(o); }
32                     )
33                 );
34             },
35
36             /* This trusts that what you are passing is actually a set (no
37              * repeats). */
38             "set": function(
39                 set, pos_callback /* called for each set member's <option>
40                                      node now and at any position change */
41             ) {
42                 this.clear();
43                 this.pos_callback = pos_callback;
44                 dojo.forEach(
45                     set, dojo.hitch(this, function(o, p) { this.add(o, p); })
46                 );
47             },
48
49             "focus": function() {
50                 this.select.focus();
51             },
52
53             /* For now this trusts that your item is in the field_map */
54             "add": function(item, position) {
55                 var option = dojo.create(
56                     "option", {
57                         "value": item,
58                         "innerHTML": dojo.string.substitute(
59                             this.format_string, [item, this.field_map[item]]
60                         )
61                     }
62                 );
63
64                 this.select.options.add(option, null);
65                 if (this.pos_callback)
66                     this.pos_callback(option, position);
67             },
68
69             /* Returns option values in order, as a set, assuming you didn't
70              * add dupes. */
71             "get": function() {
72                 /* XXX Could probably use dojo.forEach() here, but don't have
73                  * time to check whether it's sure to preserve order
74                  * with pseudo-arrays or NodeLists or whatever this is. */
75                 var list = [];
76                 for (var i = 0; i < this.select.options.length; i++)
77                     list.push(this.select.options[i].value);
78
79                 return list;
80             },
81
82             "move_selected": function(offset) {
83                 var si = this.select.selectedIndex;
84                 if (si < 0)
85                     return false;
86
87                 var opt = this.select.options[si];
88                 var len = this.select.options.length;
89                 var newpos = si + offset;
90
91                 if (newpos >= 0 && newpos < len) {
92                     var newopt = dojo.clone(opt);
93                     this.select.remove(si);
94                     this.select.add(newopt, newpos);
95
96                     if (this.pos_callback)
97                         for (var i = 0; i < len; i++)
98                             this.pos_callback(this.select.options[i], i);
99
100                     this.select.selectedIndex = newpos;
101                     return true;
102                 } else {
103                     return false;
104                 }
105             },
106         }
107     );
108
109     /* This module is *not* OO. */
110     dojo.declare("openils.conify.BestHoldOrder", null, {});
111
112     var module = openils.conify.BestHoldOrder;
113
114     /* We could get these from the IDL, but if we add more fields to that
115      * later, we have no particular mechanism for determining what is or
116      * isn't metadata. */
117     module.fields = ["pprox", "hprox", "owning_lib_to_home_lib_prox",
118         "aprox", "priority", "cut", "depth", "htime", "rtime", "approx",
119         "shtime"];
120
121     module.init = function() {
122         module.progress_dialog = dijit.byId("progress-dialog");
123         module.existing_dialog = dijit.byId("cbho-existing");
124
125         dojo.connect(
126             dijit.byId("cbho-existing-edit-go"),
127             "onClick",
128             null,
129             module.editor_load_selected_cbho
130         );
131
132         module.field_labels = {};
133         dojo.forEach(
134             module.fields, function(f) {
135                 module.field_labels[f] = fieldmapper.IDL.fmclasses.cbho.
136                     field_map[f].label
137             }
138         );
139
140         module.set_orderer = new openils.conify.SetOrderer(
141             dojo.byId("cbho-field-order"),
142             module.field_labels,
143             localeStrings.CBHO_FIELD_DISPLAY
144         );
145
146         openils.Util.hide("cbho-loading");
147         openils.Util.show("cbho-main-body");
148     };
149
150     module.new_cbho = function() {
151         module.cbho = new fieldmapper.cbho();
152
153         module.editor_start();
154     };
155
156     module.edit_cbho = function() {
157         module.progress_dialog.show(true);
158
159         function proceed(w) {
160             module.edit_cbho_selector = w;
161             module.progress_dialog.hide();
162             module.existing_dialog.show();
163         };
164
165         if (module.edit_cbho_selector) {
166             proceed(module.edit_cbho_selector);
167         } else {
168             new openils.widget.AutoFieldWidget({
169                 "fmClass": "cbho",
170                 "selfReference": true,
171                 "dijitArgs": {"required": true},
172                 "parentNode": dojo.create(
173                     "span", null, dojo.byId("cbho-existing-selector")
174                 )
175             }).build(proceed);
176         }
177     };
178
179     /* Causes next use of Edit Existing button to recreate, thereby picking
180      * up any new objects */
181     module.clear_cbho_selector = function() {
182         if (module.edit_cbho_selector) {
183             module.edit_cbho_selector.destroy();
184             module.edit_cbho_selector = null;
185         }
186     };
187
188     module.editor_load_selected_cbho = function() {
189         var id = module.edit_cbho_selector.attr("value");
190
191         if (id) {
192             module.cbho = (new openils.PermaCrud()).retrieve("cbho", id);
193             module.editor_start();
194         } else {
195             alert(localeStrings.CBHO_NO_LOAD);
196         }
197     };
198
199     module.editor_start = function() {
200         dojo.byId("cbho-editing").innerHTML = module.cbho.id() ?
201             dojo.string.substitute(
202                 localeStrings.CBHO_EDITING_EXISTING,
203                 [module.cbho.id(), module.cbho.name()]
204             ) :
205             localeStrings.CBHO_EDITING_NEW;
206
207         dojo.byId("cbho-name").value = module.cbho.name() || "";
208         module.editor_reset_order();
209
210         openils.Util.show("cbho-edit-space");
211         module.editor_changed(false);
212     };
213
214     /* Used to set all <option> nodes in the set_orderer to appear disabled if
215      * they now come after rtime. */
216     module.set_pos_callback = function(opt_node, pos) {
217         var method = module.rtime_reached ? "addClass" : "removeClass";
218         dojo[method](opt_node, "post-rtime");
219
220         if (opt_node.value == "rtime")
221             module.rtime_reached = true;
222     };
223
224     module.stored_cbho_field_order = function() {
225         var obj = module.cbho;
226
227         return module.fields.sort(
228             function(a, b) {
229                 a = obj[a]();
230                 var left = (a === null || typeof a == "undefined") ?
231                     999 : Number(a);
232
233                 b = obj[b]();
234                 var right = (b === null || typeof b == "undefined") ?
235                     999 : Number(b);
236
237                 return left - right;
238             }
239         );
240     };
241
242     module.editor_reset_order = function() {
243         module.rtime_reached = false;
244         module.set_orderer.set(
245             module.stored_cbho_field_order(), module.set_pos_callback
246         );
247     };
248
249     module.editor_move = function(offset) {
250         module.rtime_reached = false;
251         if (module.set_orderer.move_selected(offset))
252             module.editor_changed(true);
253
254         /* Without this, focus is now on the up or down button, breaking
255          * the user's ability to select other rows with the arrow keys. */
256         module.set_orderer.focus();
257     };
258
259     module.editor_changed = function(changed) {
260         dojo.attr("cbho-save-changes", "disabled", !changed);
261         if (changed)
262             openils.Util.show("cbho-needs-saved", "inline");
263         else
264             openils.Util.hide("cbho-needs-saved");
265     };
266
267     module.editor_save = function() {
268         var name = dojo.byId("cbho-name").value;
269         if (!name || !name.length) {
270             alert(localeStrings.CBHO_NEEDS_NAME);
271             return false;
272         } else {
273             module.cbho.name(name);
274         }
275
276         module.progress_dialog.show(true);
277         var fields = module.set_orderer.get();
278         for (var i = 0; i < fields.length; i++)
279             module.cbho[fields[i]](i);
280
281         try {
282             var pcrud = new openils.PermaCrud();
283             pcrud[module.cbho.id() ? "update" : "create"](
284                 module.cbho, {
285                     "oncomplete": function(r, list) {
286                         module.progress_dialog.hide();
287                         openils.Util.readResponse(r); /* alert on exceptions? */
288
289                         if (dojo.isArray(list) && list.length) {
290                             if (typeof list[0] == "object")
291                                 module.cbho = list[0];
292
293                             module.clear_cbho_selector();
294                             module.editor_start();
295                         }
296
297                         pcrud.session.disconnect(); /* good hygiene? */
298                     }
299                 }
300             );
301         } catch (E) {
302             alert(E);   /* better than doing nothing? */
303         }
304     };
305
306 })();
307
308 }