]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/dojo/openils/widget/HoldingCode.js
Serials: In the holding code mini wizard of the alt serials controls, pre-
[working/Evergreen.git] / Open-ILS / web / js / dojo / openils / widget / HoldingCode.js
1 if (!dojo._hasResource["openils.widget.HoldingCode"]) {
2     dojo.provide("openils.widget.HoldingCode");
3     dojo.require("dijit.layout.ContentPane");
4     dojo.require("dijit.form.DropDownButton");
5     dojo.require("dijit.form.TextBox");
6     dojo.require("dijit.form.NumberTextBox");
7
8     var _needed_fields = "abcdefghijklm";
9
10     function _prepare_ttip_dialog(div, wizard) {
11         dojo.empty(div);
12
13         var selector = wizard.args.scap_selector;
14         var caption_and_pattern = new scap().fromStoreItem(selector.item);
15
16         /* we're going to look for subfields a-h and i-m now. There may already
17          * be JS libs available to make this easier, but for now I'm doing this
18          * the fastest way I know. */
19
20         var pattern_code;
21         try {
22             pattern_code = JSON2js(caption_and_pattern.pattern_code());
23         } catch (E) {
24             /* no-op */;
25         }
26
27         if (!dojo.isArray(pattern_code)) {
28             div.innerHTML =
29                 "Have you selected a valid caption and pattern?";/* XXX i18n */
30             return;
31         }
32
33         var fields = [];
34         for (var i = 0; i < pattern_code.length; i += 2) {
35             var subfield = pattern_code[i];
36             var value = pattern_code[i + 1];
37
38             if (_needed_fields.indexOf(subfield) != -1)
39                 fields.push({"subfield": subfield, "caption": value});
40         }
41
42         if (!fields.length) {
43             div.innerHTML = /* XXX i18n (below) */
44                 "No caption subfields in seleted caption and pattern";
45             return;
46         }
47
48         _prepare_ttip_dialog_fields(div, fields, wizard);
49     }
50
51     function _prepare_ttip_dialog_fields(div, fields, wizard) {
52         /* XXX TODO Don't assume these defaults for the indicators and $8, and
53          * provide reasonable control over them. */
54         var holding_code = ["4", "1", "8", "1"];
55         var inputs = [];
56
57         wizard.wizard_button.attr("disabled", true);
58         var table = dojo.create("table", {"className": "serial-holding-code"});
59         fields.forEach(
60             function(field) {
61                 var tr = dojo.create("tr", null, table);
62
63                 field.caption = field.caption.replace(/^\(?([^\)]+)\)?$/, "$1");
64                 if (field.subfield > "h") {
65                     field.caption = field.caption.slice(0,1).toUpperCase() +
66                         field.caption.slice(1);
67                 }
68
69                 dojo.create("td", {"innerHTML": field.caption}, tr);
70                 var dij = field.subfield > "h" ?
71                     dijit.form.NumberTextBox : dijit.form.TextBox;
72                 var input = new dij(
73                     {
74                         "name": field.subfield,
75                         "constraints": {"pattern": "####"}
76                     },
77                     dojo.create("td", null, tr)
78                 );
79                 input.startup();
80                 wizard.preset_input_by_date(input, field.caption.toLowerCase());
81                 inputs.push({"subfield": field.subfield, "input": input});
82             }
83         );
84
85         new dijit.form.Button(
86             {
87                 "label": "Compile",
88                 "onClick": function() {
89                     inputs.forEach(
90                         function(input) {
91                             var value = input.input.attr("value");
92                             if (value === null || isNaN(value)) {
93                                 /* XXX i18n */
94                                 alert("A valid holding code cannot be " +
95                                     "produced with any blank fields.");
96                             }
97                             holding_code.push(input.subfield);
98                             holding_code.push(value);
99                         }
100                     );
101                     wizard.code_text_box.attr("value", js2JSON(holding_code));
102                     wizard.wizard_button.attr("disabled", false);
103                     dojo.empty(div);
104                 }
105             }, dojo.create(
106                 "span", null, dojo.create(
107                     "td", {"colspan": 2},
108                     dojo.create("tr", null, table)
109                 )
110             )
111         );
112         dojo.place(table, div, "only");
113     }
114
115     /* Approximate a season value given a date using the same logic as
116      * OpenILS::Utils::MFHD::Holding::chron_to_date().
117      */
118     function _loose_season(D) {
119         var m = D.getMonth() + 1;
120         var d = D.getDate();
121
122         if (
123             (m == 1 || m == 2) || (m == 12 && d >= 21) || (m == 3 && d < 20)
124         ) {
125             return 24;  /* MFHD winter */
126         } else if (
127             (m == 4 || m == 5) || (m == 3 && d >= 20) || (m == 6 && d < 21)
128         ) {
129             return 21;  /* spring */
130         } else if (
131             (m == 7 || m == 8) || (m == 6 && d >= 21) || (m == 9 && d < 22)
132         ) {
133             return 22;  /* summer */
134         } else {
135             return 23;  /* autumn */
136         }
137     }
138
139     dojo.declare(
140         "openils.widget.HoldingCode", dijit.layout.ContentPane, {
141             "constructor": function(args) {
142                 this.args = args || {};
143             },
144
145             "startup": function() {
146                 var self = this;
147                 this.inherited(arguments);
148
149                 var dialog_div = dojo.create(
150                     "div", {
151                         "style": "padding:1em;margin:0;text-align:center;"
152                     }, this.domNode
153                 );
154                 var target_div = dojo.create("div", null, this.domNode);
155                 dojo.create("br", null, this.domNode);
156
157                 this.wizard_button = new dijit.form.Button(
158                     {
159                         "label": "Wizard" /* XXX i18n */,
160                         "onClick": function() {
161                             _prepare_ttip_dialog(target_div, self);
162                         }
163                     },
164                     dojo.create("span", null, dialog_div)
165                 );
166
167                 this.code_text_box = new dijit.form.TextBox(
168                     {}, dojo.create("div", null, this.domNode)
169                 );
170                 this.code_text_box.startup();
171             },
172
173             "attr": function(name, value) {
174                 if (name == "value") {
175                     /* XXX can this get called before any subdijits are
176                      * built (before startup() is run)? */
177                     if (value) {
178                         this.code_text_box.attr(name, value);
179                     }
180                     return this.code_text_box.attr(name);
181                 } else {
182                     return this.inherited(arguments);
183                 }
184             },
185
186             "update_scap_selector": function(selector) {
187                 this.args.scap_selector = selector;
188                 this.attr("value", "");
189             },
190
191             "preset_input_by_date": function(input, chron_part) {
192                 try {
193                     input.attr("value", {
194                             /* NOTE: week is specifically not covered. I'm
195                              * not sure there's an acceptably standard way
196                              * to number the weeks in a year.  Do we count
197                              * from the week of January 1? Or the first week
198                              * with a day of the week matching our example
199                              * date?  Do weeks run Mon-Sun or Sun-Sat?
200                              */
201                             "year": function(d) { return d.getFullYear(); },
202                             "season": function(d) { return _loose_season(d); },
203                             "month": function(d) { return d.getMonth() + 1; },
204                             "day": function(d) { return d.getDate(); },
205                             "hour": function(d) { return d.getHours(); },
206                         }[chron_part](this.date_widget.attr("value"))
207                     );
208                 } catch (E) {
209                     ; /* Oh well; can't win them all. */
210                 }
211             },
212
213             "date_widget": null
214         }
215     );
216 }