Bug 29407: Make the pickup locations dropdown JS reusable
[koha.git] / koha-tmpl / intranet-tmpl / prog / js / xmlControlfield.js
1
2
3 // Add an option to a select form field
4 function add_option(select, text, value, selected)
5 {
6     var option = document.createElement('option');
7     option.text = text;
8     option.value = value;
9     if (selected) option.selected = true;
10     try {
11         select.add(option, null);
12     }
13     catch(ex) {
14         select.add(option);
15     }
16 }//add_option
17
18
19 // Return the value of a parameter from the url
20 function returnValueParam(param)
21 {
22     var params = location.search.substr(1);
23     var arr = params.split("&");
24     var pattern = param + "=";
25     for (var i=0; i < arr.length; i++) {
26         if (arr[i].indexOf(pattern) == 0) {
27             return unescape(arr[i].substr(pattern.length));
28         }
29     }
30     return "";
31 }//returnValueParam
32
33
34 // Return a value from a position on the result string
35 function returnValuePosFromResult(result, pos)
36 {
37     var index;
38     if ((index = pos.indexOf("-")) > 0) {
39         var ini = parseInt(pos.substring(0, index) ,10);
40         var end = parseInt(pos.substr(index + 1) ,10);
41         return result.substring(ini, end + 1);
42     } else {
43         return result.substr(pos, 1);
44     }
45 }//returnValuePosFromResult
46
47
48 // Build string from form fields
49 function returnResultFromValues(form)
50 {
51     var resultStr = form.result.value;
52     var pos;
53     var value;
54     for (var i=0; i < form.elements.length; i++) {
55         var pattern = new RegExp("f[0-9]+(?:[0-9]+)?");
56         if (pattern.test(form.elements[i].name)) {
57             pos = form.elements[i].name.substr(1);
58             value = (pos.indexOf("-") > 0)?form.elements[i].value:form.elements[i].options[form.elements[i].selectedIndex].value;
59             resultStr = changePosResult(pos, value, resultStr);
60         }
61     }
62     return resultStr;
63 }//returnResultFromValues
64
65
66 // Build/modify result string for a position and a value
67 function changePosResult(pos, value, resultStr)
68 {
69     var index;
70     var result = "";
71     if ((index = pos.indexOf("-")) > 0) {
72         var ini = parseInt(pos.substring(0, index) ,10);
73         var end = parseInt(pos.substr(index + 1) ,10);
74         var roffset = (1 + end - ini)- value.length;
75         if (roffset > 0) for (var i=0; i < roffset; i++) value += " ";
76         if (ini == 0)
77             result = value + resultStr.substr(end + 1);
78         else {
79             result = resultStr.substring(0, ini) + value;
80             if (end < resultStr.length)
81                 result += resultStr.substr(end + 1);
82         }
83     } else {
84         var ini = parseInt(pos, 10);
85         if (ini == 0)
86             result = value + resultStr.substr(1);
87         else {
88             result = resultStr.substring(0, ini) + value;
89             if (ini < resultStr.length)
90                 result += resultStr.substr(ini + 1);
91         }
92     }
93     result = result.replace(/#/g, " ");
94     return result;
95 }//changePosResult
96
97
98 // Display the result string on a row of a table indicating positions and coloring them if they are incorrect or they are selected
99 function renderResult(tr_result, result)
100 {
101     if (tr_result) {
102         var td;
103         if (tr_result.cells.length != result.length) {
104             for (var i = tr_result.cells.length - 1; i >= 0; i--)
105                 tr_result.deleteCell(i);
106             for (var i=0; i < result.length; i++) {
107                 value = result.charAt(i);
108                 td = tr_result.insertCell(tr_result.cells.length);
109             }
110         }
111         var value;
112         var ini = -1;
113         var end = -1;
114         var args = renderResult.arguments;
115         var whiteAllTD = false;
116         if (args.length > 2) {
117             if (typeof(args[2]) == "boolean") {
118                 whiteAllTD = args[2];
119             } else {
120                 var index;
121                 if ((index = args[2].indexOf("-")) > 0) {
122                     ini = parseInt(args[2].substring(0, index) ,10);
123                     end = parseInt(args[2].substr(index + 1) ,10);
124                 } else ini = parseInt(args[2], 10);
125             }
126         }
127         for (var i=0; i < result.length; i++) {
128             value = result.charAt(i);
129             td = tr_result.cells[i];
130             if (td.style.backgroundColor != "yellow" || whiteAllTD) td.style.backgroundColor = "white";
131             td.innerHTML = (value == " ")?"&nbsp;":value;
132             td.title = "Pos " + i + ". Value: \"" + value + "\"";
133             if (ini >= 0) {
134                 if (end > 0) {
135                     if (ini <= i && i <= end) td.style.backgroundColor = "#cccccc";
136                 } else if (i == ini) td.style.backgroundColor = "#cccccc";
137             } else {
138                 var pos = (i < 10)?'0' + i:i + '';
139                 var obj;
140                 if ((obj = document.getElementById('f' + pos)) != null) {
141                     var found = false;
142                     for (var j=0; j < obj.options.length && !found; j++)
143                         if (obj.options[j].value == value) found = true;
144                     if (!found) {
145                         td.style.backgroundColor = "yellow";
146                         td.title = "Pos " + i + ". Incorrect Value: \"" + value + "\"";
147                     }
148                 }
149             }
150         }//for
151     }
152 }//renderResult
153
154
155 // Change displaying of result in the page
156 function changeH4Result(form, h4_result, tr_result, pos, value)
157 {
158     var resultStr = form.result.value;
159     var result = changePosResult(pos, value, resultStr);
160     renderResult(tr_result, result, pos);
161     h4_result.innerHTML = "&quot;" + result + "&quot;";
162     form.result.value = result;
163 }//changeH4Result
164
165
166
167 // Class to read the xml and render the type of material
168 (function()
169 {
170
171     xmlControlField = function(tagfield, form_id, select, table, h4_result, tr_result, idMaterial, themelang, marcflavour)
172     {
173         this.tagfield = tagfield;
174         this.idMaterial = idMaterial;
175         this.form_id = form_id;
176         this.form = document.getElementById(form_id);
177         this.select = select;
178         this.table = table;
179         this.h4_result = h4_result;
180         this.tr_result = tr_result;
181         this.themelang = themelang;
182         this.marcflavour = marcflavour.toLowerCase();
183     };//xmlControlField
184
185
186     xmlControlField.prototype =
187     {
188         tagfield: "",
189         idMaterial: "",
190         root: null,
191         form_id: "",
192         form: null,
193         select: null,
194         table: null,
195         h4_result: "",
196         tr_result: "",
197         themelang: "",
198
199
200         setIdMaterial: function(idMaterial)
201         {
202             this.idMaterial = idMaterial;
203         },//setIdMaterial
204
205         loadXmlValues: function()
206         {
207             this.xmlDoc = $.ajax({
208                 type: "GET",
209                 url: this.themelang + "/data/" + this.marcflavour + "_field_" + this.tagfield + ".xml",
210                 dataType: "xml",
211                 async: false
212             }).responseXML;
213             if (this.xmlDoc) this.renderTemplate();
214             $("*").ajaxError(function(evt, request, settings){
215                 alert(_("AJAX error: receiving data from %s").format(settings.url));
216             });
217         },//loadXmlValues
218
219
220         renderTemplate: function()
221         {
222             this.root = this.xmlDoc.documentElement;
223             if (this.root.nodeName == "Tagfield" && this.root.nodeType == 1 && this.root.hasChildNodes()) {
224                 var tag = this.root.attributes.getNamedItem("tag").nodeValue;
225                 var nodeMaterial = this.root.getElementsByTagName('Material');
226                 if (nodeMaterial != null && nodeMaterial.length > 0) {
227                     if (this.idMaterial == "") this.idMaterial = nodeMaterial[0].attributes.getNamedItem("id").nodeValue;
228                     this.renderSelectMaterial(nodeMaterial);
229                     this.renderPositions(nodeMaterial, (this.form.result.value != "")?this.form.result.value:returnValueParam("result"));
230                 }
231             }
232         },//renderTemplate
233
234
235         renderSelectMaterial: function(nodeMaterial)
236         {
237             if (this.select != null && nodeMaterial != null && nodeMaterial.length > 0) {
238                 if (this.select.options.length <= 1) {
239                     var id;
240                     var name;
241                     var arrSort = new Array();
242                     var arrEquiv = new Array();
243                     for (var i=0; i < nodeMaterial.length; i++) {
244                         id = nodeMaterial[i].attributes.getNamedItem("id").nodeValue;
245                         name = nodeMaterial[i].getElementsByTagName('name')[0].textContent;
246                         arrEquiv[id] = i;
247                         arrSort.push(id);
248                     }
249                     arrSort.sort();
250                     var j;
251                     for (var i=0; i < arrSort.length; i++) {
252                         j = arrEquiv[arrSort[i]];
253                         add_option(this.select, arrSort[i] + " - " + nodeMaterial[j].getElementsByTagName('name')[0].textContent, arrSort[i], (this.idMaterial != "" && arrSort[i] == this.idMaterial)?true:false);
254                     }
255                 } else if (this.idMaterial != "") {
256                     for (var i=0; i < this.select.options.length; i++) {
257                         if (this.select.options[i].value == this.idMaterial) this.select.options[i].selected = true;
258                     }
259                 }
260             }
261         },//renderSelectMaterial
262
263
264         renderPositions: function(nodeMaterial, result)
265         {
266             var materialNode;
267             try {
268                 var resultXPath = this.xmlDoc.evaluate("//a:Material[@id='" + this.idMaterial + "']", this.xmlDoc.documentElement, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
269                 materialNode = resultXPath.singleNodeValue;
270             } catch (e) {
271                 for (var i=0; i < nodeMaterial.length; i++) {
272                     if (this.idMaterial == nodeMaterial[i].attributes.getNamedItem("id").nodeValue) {
273                         materialNode = nodeMaterial[i];
274                         break;
275                     }
276                 }
277             }
278             if (this.table != null) { // Render table
279                 var tbody = this.table.tBodies[0];
280                 // Clean up table
281                 if (tbody.rows.length > 0)
282                     for (var i = tbody.rows.length - 1; i >= 1; i--)
283                         tbody.deleteRow(i);
284                 // Parse Material node
285                 if (materialNode != undefined && materialNode != null && materialNode.nodeType == 1 && materialNode.hasChildNodes()) {
286                     var nodePos = materialNode.firstChild;
287                     var tr;
288                     var td;
289                     var title;
290                     var pos;
291                     var value;
292                     var strInnerHTML = "";
293                     var selected;
294                     var index;
295                     var url;
296                     var description;
297                     var name;
298                     while (nodePos != null) {
299                         if (nodePos.nodeType == 1 && nodePos.nodeName == "Position") {
300                             tr = tbody.insertRow(tbody.rows.length);
301                             td = tr.insertCell(tr.cells.length);
302                             pos = nodePos.attributes.getNamedItem("pos").nodeValue;
303                             // description is required by schema
304                             description = nodePos.getElementsByTagName('description')[0].textContent;
305                             name = nodePos.getElementsByTagName('name')[0].textContent
306                             title = ( description != "")?description:name;
307                             try {
308                                 url = ((nodePos.getAttributeNode("url") || nodePos.hasAttribute("url")) && nodePos.getAttribute("url") != "" && nodePos.getElementsByTagName('urltext')[0].textContent != "")?"&nbsp;<a href='" + nodePos.attributes.getNamedItem("url").nodeValue + "' target='_blank'>" + nodePos.getElementsByTagName('urltext')[0].textContent + "</a>":"";
309                             } catch (e) { url = "";}
310                             td.innerHTML = "<label for='" + pos + "' title='" + title + "'>" + pos + " - " + name + url + "</label>";
311                             td = tr.insertCell(tr.cells.length);
312                             value = returnValuePosFromResult(result, pos);
313                             if ((index = pos.indexOf("-")) > 0) { // Position interval
314                                 var ini = parseInt(pos.substring(0, index) ,10);
315                                 var end = parseInt(pos.substr(index + 1) ,10);
316                                 value = value.replace(/ /g, "#");
317                                 strInnerHTML = "<input type='text' name='f" + pos + "' id='f" + pos + "' value='" + value + "' size='" + (1 + end - ini) + "' maxlength='" + (1 + end - ini) + "' onkeyup='this.value = this.value.replace(/ /g, \"#\"); changeH4Result(document.getElementById(\"" + this.form_id + "\"), document.getElementById(\"" + this.h4_result + "\"), document.getElementById(\"" + this.tr_result + "\"), \"" + pos + "\", this.value)' onfocus='changeH4Result(document.getElementById(\"" + this.form_id + "\"), document.getElementById(\"" + this.h4_result + "\"), document.getElementById(\"" + this.tr_result + "\"), \"" + pos + "\", this.value)' />";
318                             } else {
319                                 strInnerHTML = "<select name='f" + pos + "' id='f" + pos + "' style='width:400px' onchange='changeH4Result(document.getElementById(\"" + this.form_id + "\"), document.getElementById(\"" + this.h4_result + "\"), document.getElementById(\"" + this.tr_result + "\"), \"" + pos + "\", this.options[this.selectedIndex].value)' onfocus='changeH4Result(document.getElementById(\"" + this.form_id + "\"), document.getElementById(\"" + this.h4_result + "\"), document.getElementById(\"" + this.tr_result + "\"), \"" + pos + "\", this.options[this.selectedIndex].value)'>";
320                                 value = value.replace("#", " ");
321                                 if (nodePos.getElementsByTagName("Value").length != 0) {
322                                     var nodeValue = nodePos.firstChild;
323                                     while (nodeValue != null) {
324                                         if (nodeValue.nodeType == 1 && nodeValue.nodeName == "Value" && nodeValue.hasChildNodes()) {
325                                             var code = nodeValue.attributes.getNamedItem("code").nodeValue;
326                                             description = nodeValue.getElementsByTagName('description')[0].textContent;
327                                             var valNode = code;
328                                             valNode = valNode.replace("#", " ");
329                                             selected = (value == valNode)?"selected='selected'":"";
330                                             strInnerHTML += "<option value='"  + valNode + "' " + selected + ">" + code + " - " + description +  "</option>";
331                                         }
332                                         nodeValue = nodeValue.nextSibling;
333                                     }
334                                 } else {
335                                     strInnerHTML += "<option value=' ' " + ((value == " ")?"selected='selected'":"") + "># - " + title +  "</option>";
336                                     strInnerHTML += "<option value='|' " + ((value == "|")?"selected='selected'":"") + ">| - " + title +  "</option>";
337                                 }
338                                 strInnerHTML += "</select>";
339                             }
340                             td.innerHTML = strInnerHTML;
341                         }
342                         nodePos = nodePos.nextSibling;
343                     }
344                 }
345             }
346         }//renderPositions
347     };
348
349 })();
350