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.requireLocalization('openils.serial', 'serial');
8 /* XXX These variables and functions preceding the call to dojo.declar()
9 * all pollute the window namespace. They're not written as methods for
10 * the openils.widget.HoldingCode "class," but they should probably move
14 var _localeStrings = dojo.i18n.getLocalization('openils.serial', 'serial');
16 var _needed_fields = "abcdefghijklm";
17 var _season_store = new dojo.data.ItemFileReadStore({
22 {"code": 21, "label": _localeStrings.SEASON_SPRING},
23 {"code": 22, "label": _localeStrings.SEASON_SUMMER},
24 {"code": 23, "label": _localeStrings.SEASON_FALL},
25 {"code": 24, "label": _localeStrings.SEASON_WINTER}
28 }); /* XXX i18n the above seasons. Also maybe don't
29 hardcode MFHD seasons here? */
32 function _prepare_ttip_dialog(div, wizard) {
35 var selector = wizard.args.scap_selector;
36 var caption_and_pattern = new scap().fromStoreItem(selector.item);
38 /* we're going to look for subfields a-h and i-m now. There may already
39 * be JS libs available to make this easier, but for now I'm doing this
40 * the fastest way I know. */
44 pattern_code = JSON2js(caption_and_pattern.pattern_code());
49 if (!dojo.isArray(pattern_code)) {
50 div.innerHTML = _localeStrings.SELECT_VALID_CAP;
55 for (var i = 0; i < pattern_code.length; i += 2) {
56 var subfield = pattern_code[i];
57 var value = pattern_code[i + 1];
59 if (_needed_fields.indexOf(subfield) != -1)
60 fields.push({"subfield": subfield, "caption": value, "pattern_value": value});
64 div.innerHTML = _localeStrings.NO_CAP_SUBFIELDS;
68 _prepare_ttip_dialog_fields(div, fields, wizard);
71 function _generate_dijit_for_field(field, tr) {
72 dojo.create("td", {"innerHTML": field.caption}, tr);
74 /* Any more special cases than this and we should switch to a dispatch
75 * table or something. */
77 if (field.pattern_value.match(/season/)) {
78 input = new dijit.form.FilteringSelect(
80 "name": field.subfield,
81 "store": _season_store,
82 "searchAttr": "label",
83 "scrollOnFocus": false
84 }, dojo.create("td", null, tr)
87 input = new dijit.form.TextBox(
88 {"name": field.subfield, "scrollOnFocus": false},
89 dojo.create("td", null, tr)
97 function _prepare_ttip_dialog_fields(div, fields, wizard) {
98 /* XXX TODO Don't assume these defaults for the indicators and $8, and
99 * provide reasonable control over them. */
100 var holding_code = ["4", "1", "8", "1"];
103 wizard.wizard_button.attr("disabled", true);
104 var table = dojo.create("table", {"className": "serial-holding-code"});
107 var tr = dojo.create("tr", null, table);
109 field.caption = field.caption.replace(/^\(?([^\)]+)\)?$/, "$1");
110 if (field.subfield > "h") {
111 field.caption = field.caption.slice(0,1).toUpperCase() +
112 field.caption.slice(1);
115 var input = _generate_dijit_for_field(field, tr);
116 wizard.preset_input_by_date(input, field.caption.toLowerCase());
117 inputs.push({"subfield": field.subfield, "input": input});
121 new dijit.form.Button(
123 "label": _localeStrings.COMPILE,
124 "onClick": function() {
127 var value = input.input.attr("value");
128 if (value === null || value === "") {
129 alert(_localeStrings.ERROR_BLANK_FIELDS);
131 holding_code.push(input.subfield);
132 holding_code.push(value);
135 wizard.code_text_box.attr("value", js2JSON(holding_code));
136 wizard.wizard_button.attr("disabled", false);
139 "scrollOnFocus": false
141 "span", null, dojo.create(
142 "td", {"colspan": 2},
143 dojo.create("tr", null, table)
147 dojo.place(table, div, "only");
150 /* Approximate a season value given a date using the same logic as
151 * OpenILS::Utils::MFHD::Holding::chron_to_date().
153 function _loose_season(D) {
154 var m = D.getMonth() + 1;
158 (m == 1 || m == 2) || (m == 12 && d >= 21) || (m == 3 && d < 20)
160 return 24; /* MFHD winter */
162 (m == 4 || m == 5) || (m == 3 && d >= 20) || (m == 6 && d < 21)
164 return 21; /* spring */
166 (m == 7 || m == 8) || (m == 6 && d >= 21) || (m == 9 && d < 22)
168 return 22; /* summer */
170 return 23; /* autumn */
175 "openils.widget.HoldingCode", dijit.layout.ContentPane, {
176 "constructor": function(args) {
177 this.args = args || {};
180 "startup": function() {
182 this.inherited(arguments);
184 var dialog_div = dojo.create(
186 "style": "padding:1em;margin:0;text-align:center;"
189 var target_div = dojo.create("div", null, this.domNode);
190 dojo.create("br", null, this.domNode);
192 this.wizard_button = new dijit.form.Button(
194 "label": _localeStrings.WIZARD,
195 "onClick": function() {
196 _prepare_ttip_dialog(target_div, self);
199 dojo.create("span", null, dialog_div)
202 this.code_text_box = new dijit.form.ValidationTextBox(
203 {}, dojo.create("div", null, this.domNode)
206 /* This by no means will fully validate plausible holding codes,
207 * but it will perhaps help users who experiment with typing
208 * the holding code in here freehand (a little). */
209 this.code_text_box.validator = function(value) {
211 return dojo.isArray(dojo.fromJson(value));
217 this.code_text_box.startup();
220 "attr": function(name, value) {
221 if (name == "value") {
222 /* XXX can this get called before any subdijits are
223 * built (before startup() is run)? */
225 this.code_text_box.attr(name, value);
227 return this.code_text_box.attr(name);
229 return this.inherited(arguments);
233 "update_scap_selector": function(selector) {
234 this.args.scap_selector = selector;
235 this.attr("value", "");
238 "preset_input_by_date": function(input, chron_part) {
240 input.attr("value", {
241 /* NOTE: week is specifically not covered. I'm
242 * not sure there's an acceptably standard way
243 * to number the weeks in a year. Do we count
244 * from the week of January 1? Or the first week
245 * with a day of the week matching our example
246 * date? Do weeks run Mon-Sun or Sun-Sat?
248 "year": function(d) { return d.getFullYear(); },
249 "season": function(d) { return _loose_season(d); },
250 "month": function(d) { return d.getMonth() + 1; },
251 "day": function(d) { return d.getDate(); },
252 "hour": function(d) { return d.getHours(); },
253 }[chron_part](this.date_widget.attr("value"))
256 ; /* Oh well; can't win them all. */