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