Bug 10480: Use the framework plugin object in cataloguing
[koha.git] / koha-tmpl / intranet-tmpl / prog / en / js / cataloging.js
blob9fa70a5f6cfe783aa357174f7f1043c54c68f823
1 /*
2  * Unified file for catalogue edition
3  */
5 /* Functions developed for addbiblio.tt and authorities.tt */
7 // returns the fieldcode based upon tag div id
8 function getFieldCode(tagDivId){
9     // format : tag_<tagnumber>_...
10     return tagDivId.substr(3+1,3);
13 //returns the field and subfieldcode based upon subfield div id
14 function getFieldAndSubfieldCode(subfieldDivId){
15  // format : subfield<tagnumber><subfieldnumber>...
16     return subfieldDivId.substr(8,3+1);
19 //returns the subfieldcode based upon subfieldid writing
20 function getSubfieldCode(tagsubfieldid){
21     // 3 : tag +3 : tagnumber +4 : number of _ +8 subfield -1 begins at 0
22     return tagsubfieldid.substr(3+3+4+8-1,1);
25 // Take the base of tagsubfield information (removing the subfieldcodes and subfieldindexes)
26 // returns the filter
27 function getTagInputnameFilter(tagsubfieldid){
28     var tagsubfield=tagsubfieldid.substr(0,tagsubfieldid.lastIndexOf("_"));
29     var tagcode=tagsubfield.substr(tagsubfield.lastIndexOf("_"));
30     tagsubfield=tagsubfield.substr(0,tagsubfield.lastIndexOf("_"));
31     tagsubfield=tagsubfield.substr(0,tagsubfield.lastIndexOf("_"));
32     tagsubfield=tagsubfield+"_."+tagcode;
33     return tagsubfield;
36 // if source is "auth", we are editing an authority otherwise it is a biblio
37 function openAuth(tagsubfieldid,authtype,source) {
38     // let's take the base of tagsubfield information (removing the indexes and the codes
39     var element=document.getElementById(tagsubfieldid);
40     var tagsubfield=getTagInputnameFilter(tagsubfieldid);
41     var elementsubfcode=getSubfieldCode(element.name);
42     var mainmainstring=element.value;
43     var mainstring="";
44     var inputs = element.parentNode.parentNode.getElementsByTagName("input");
46     for (var myindex =0; myindex<inputs.length;myindex++){
47         if (inputs[myindex].name && inputs[myindex].name.match(tagsubfield)){
48             var subfieldcode=getSubfieldCode(inputs[myindex].name);
49             if (isNaN(parseInt(subfieldcode)) && inputs[myindex].value != "" && subfieldcode!=elementsubfcode){
50                 mainstring=inputs[myindex].value+" "+mainstring;
51             }
52         }
53     }
54     newin=window.open("../authorities/auth_finder.pl?source="+source+"&authtypecode="+authtype+"&index="+tagsubfieldid+"&value_mainstr="+encodeURI(mainmainstring)+"&value_main="+encodeURI(mainstring), "_blank",'width=700,height=550,toolbar=false,scrollbars=yes');
57 function ExpandField(index) {
58     var original = document.getElementById(index); //original <div>
59     var divs = original.getElementsByTagName('div');
60     for(var i=0,divslen = divs.length ; i<divslen ; i++){   // foreach div
61         if(divs[i].getAttribute('id').match(/^subfield/)){  // if it s a subfield
62             if (!divs[i].style.display) {
63                 // first time => show all subfields
64                 divs[i].style.display = 'block';
65             } else if (divs[i].style.display == 'none') {
66                 // show
67                 divs[i].style.display = 'block';
68             } else {
69                 // hide
70                 divs[i].style.display = 'none';
71             }
72         }
73     }
75 /**
76  * To clone a field
77  * @param hideMarc '0' for false, '1' for true
78  * @param advancedMARCEditor '0' for false, '1' for true
79  */
80 function CloneField(index, hideMarc, advancedMARCEditor) {
81     var original = document.getElementById(index); //original <div>
82     var clone = original.cloneNode(true);
83     var new_key = CreateKey();
84     var new_id  = original.getAttribute('id')+new_key;
86     clone.setAttribute('id',new_id); // setting a new id for the parent div
88     var divs = clone.getElementsByTagName('div');
90     // if hide_marc, indicators are hidden fields
91     // setting a new name for the new indicator
92     for(var i=0; i < 2; i++) {
93         var indicator = clone.getElementsByTagName('input')[i];
94         indicator.setAttribute('name',indicator.getAttribute('name')+new_key);
95     }
97     // settings all subfields
98     for(var i=0,divslen = divs.length ; i<divslen ; i++){      // foreach div
99         if(divs[i].getAttribute("id").match(/^subfield/)){  // if it s a subfield
101             // set the attribute for the new 'div' subfields
102             divs[i].setAttribute('id',divs[i].getAttribute('id')+new_key);
104             var inputs   = divs[i].getElementsByTagName('input');
105             var id_input = "";
107             for( j = 0 ; j < inputs.length ; j++ ) {
108                 if(inputs[j].getAttribute("id") && inputs[j].getAttribute("id").match(/^tag_/) ){
109                     inputs[j].value = "";
110                 }
111             }
113             inputs[0].setAttribute('id',inputs[0].getAttribute('id')+new_key);
114             inputs[0].setAttribute('name',inputs[0].getAttribute('name')+new_key);
115             var id_input;
116             try {
117                 id_input = inputs[1].getAttribute('id')+new_key;
118                 inputs[1].setAttribute('id',id_input);
119                 inputs[1].setAttribute('name',inputs[1].getAttribute('name')+new_key);
120             } catch(e) {
121                 try{ // it s a select if it is not an input
122                     var selects = divs[i].getElementsByTagName('select');
123                     id_input = selects[0].getAttribute('id')+new_key;
124                     selects[0].setAttribute('id',id_input);
125                     selects[0].setAttribute('name',selects[0].getAttribute('name')+new_key);
126                 }catch(e2){ // it is a textarea if it s not a select or an input
127                     var textaeras = divs[i].getElementsByTagName('textarea');
128                     id_input = textaeras[0].getAttribute('id')+new_key;
129                     textaeras[0].setAttribute('id',id_input);
130                     textaeras[0].setAttribute('name',textaeras[0].getAttribute('name')+new_key);
131                 }
132             }
133             if( $(inputs[1]).hasClass('framework_plugin') ) {
134                 var oldcontrol= original.getElementsByTagName('input')[1];
135                 AddEventHandlers( oldcontrol,inputs[1],id_input );
136             }
138             if (advancedMARCEditor == '0') {
139                 // when cloning a subfield, re set its label too.
140                 var labels = divs[i].getElementsByTagName('label');
141                 labels[0].setAttribute('for',id_input);
142             }
144             if(hideMarc == '0') {
145                 // updating javascript parameters on button up
146                 var imgs = divs[i].getElementsByTagName('img');
147                 imgs[0].setAttribute('onclick',"upSubfield(\'"+divs[i].getAttribute('id')+"\');");
148             }
150             // setting its '+' and '-' buttons
151             try {
152                 var anchors = divs[i].getElementsByTagName('a');
153                 for (var j = 0; j < anchors.length; j++) {
154                     if(anchors[j].getAttribute('class') == 'buttonPlus'){
155                         anchors[j].setAttribute('onclick',"CloneSubfield('" + divs[i].getAttribute('id') + "','" + advancedMARCEditor + "'); return false;");
156                     } else if (anchors[j].getAttribute('class') == 'buttonMinus') {
157                         anchors[j].setAttribute('onclick',"UnCloneField('" + divs[i].getAttribute('id') + "'); return false;");
158                     }
159                 }
160             }
161             catch(e){
162                 // do nothig if ButtonPlus & CloneButtonPlus don t exist.
163             }
165             // button ...
166             var spans=0;
167             try {
168                 spans = divs[i].getElementsByTagName('a');
169             } catch(e) {
170                 // no spans
171             }
172             if(spans){
173                 var buttonDot;
174                 if(!CloneButtonPlus){ // it s impossible to have  + ... (buttonDot AND buttonPlus)
175                     buttonDot = spans[0];
176                     if(buttonDot){
177                         // 2 possibilities :
178                         try{
179                             if( $(buttonDot).hasClass('framework_plugin') ) {
180                                 var oldcontrol= original.getElementsByTagName('a')[0];
181                                 AddEventHandlers(oldcontrol,buttonDot,id_input);
182                             } else {
183                                 if(buttonDotOnClick.match('Dopop')) {  // -2- It's a auth value
184                                     var re1 = /&index=.*',/;
185                                     var re2 = /,.*\)/;
187                                     buttonDotOnClick = buttonDotOnClick.replace(re1,"&index="+inputs[1].getAttribute('id')+"',");
188                                     buttonDotOnClick = buttonDotOnClick.replace(re2,",'"+inputs[1].getAttribute('id')+"')");
190                                     if(buttonDotOnClick){
191                                             buttonDot.setAttribute('onclick',buttonDotOnClick);
192                                     }
193                                 }
194                             }
195                             try {
196                                 // do not copy the script section.
197                                 var script = spans[0].getElementsByTagName('script')[0];
198                                 spans[0].removeChild(script);
199                             } catch(e) {
200                                 // do nothing if there is no script
201                             }
202                         }catch(e){}
203                     }
204                 }
205             }
206             if(hideMarc == '0') {
207                 var buttonUp = divs[i].getElementsByTagName('img')[0];
208                 buttonUp.setAttribute('onclick',"upSubfield('" + divs[i].getAttribute('id') + "')");
209             }
211         } else { // it's a indicator div
212             if(divs[i].getAttribute('id').match(/^div_indicator/)){
214                 // setting a new id for the indicator div
215                 divs[i].setAttribute('id',divs[i].getAttribute('id')+new_key);
217                 var inputs = divs[i].getElementsByTagName('input');
218                 inputs[0].setAttribute('id',inputs[0].getAttribute('id')+new_key);
219                 inputs[1].setAttribute('id',inputs[1].getAttribute('id')+new_key);
221                 var CloneButtonPlus;
222                 try {
223                     var anchors = divs[i].getElementsByTagName('a');
224                     for (var j = 0; j < anchors.length; j++) {
225                         if (anchors[j].getAttribute('class') == 'buttonPlus') {
226                             anchors[j].setAttribute('onclick',"CloneField('" + new_id + "','" + hideMarc + "','" + advancedMARCEditor + "'); return false;");
227                         } else if (anchors[j].getAttribute('class') == 'buttonMinus') {
228                             anchors[j].setAttribute('onclick',"UnCloneField('" + new_id + "'); return false;");
229                         } else if (anchors[j].getAttribute('class') == 'expandfield') {
230                             anchors[j].setAttribute('onclick',"ExpandField('" + new_id + "'); return false;");
231                         }
232                     }
233                 }
234                 catch(e){
235                     // do nothig CloneButtonPlus doesn't exist.
236                 }
238             }
239         }
240     }
242     // insert this line on the page
243     original.parentNode.insertBefore(clone,original.nextSibling);
247  * To clone a subfield
248  * @param index
249  * @param advancedMARCEditor '0' for false, '1' for true
250  */
251 function CloneSubfield(index, advancedMARCEditor){
252     var original = document.getElementById(index); //original <div>
253     var clone = original.cloneNode(true);
254     var new_key = CreateKey();
256     // set the attribute for the new 'div' subfields
257     var inputs     = clone.getElementsByTagName('input');
258     var selects    = clone.getElementsByTagName('select');
259     var textareas  = clone.getElementsByTagName('textarea');
260     var linkid;
262     // input
263     var id_input = "";
264     for(var i=0,len=inputs.length; i<len ; i++ ){
265         id_input = inputs[i].getAttribute('id')+new_key;
266         inputs[i].setAttribute('id',id_input);
267         inputs[i].setAttribute('name',inputs[i].getAttribute('name')+new_key);
268         linkid = id_input;
269     }
270     // Plugin input
271     if( $(inputs[1]).hasClass('framework_plugin') ) {
272         var oldcontrol= original.getElementsByTagName('input')[1];
273         AddEventHandlers( oldcontrol, inputs[1], linkid );
274     }
276     // select
277     for(var i=0,len=selects.length; i<len ; i++ ){
278         id_input = selects[i].getAttribute('id')+new_key;
279         selects[i].setAttribute('id',selects[i].getAttribute('id')+new_key);
280         selects[i].setAttribute('name',selects[i].getAttribute('name')+new_key);
281     }
283     // textarea
284     for(var i=0,len=textareas.length; i<len ; i++ ){
285         id_input = textareas[i].getAttribute('id')+new_key;
286         textareas[i].setAttribute('id',textareas[i].getAttribute('id')+new_key);
287         textareas[i].setAttribute('name',textareas[i].getAttribute('name')+new_key);
288     }
290     // Handle click event on buttonDot for plugin
291     var links  = clone.getElementsByTagName('a');
292     if( $(links[0]).hasClass('framework_plugin') ) {
293         var oldcontrol= original.getElementsByTagName('a')[0];
294         AddEventHandlers( oldcontrol, links[0], linkid );
295     }
297     if(advancedMARCEditor == '0') {
298         // when cloning a subfield, reset its label too.
299         var label = clone.getElementsByTagName('label')[0];
300         label.setAttribute('for',id_input);
301     }
303     // setting a new id for the parent div
304     var new_id  = original.getAttribute('id')+new_key;
305     clone.setAttribute('id',new_id);
307     try {
308         var buttonUp = clone.getElementsByTagName('img')[0];
309         buttonUp.setAttribute('onclick',"upSubfield('" + new_id + "')");
310         var anchors = clone.getElementsByTagName('a');
311         if(anchors.length){
312             for(var i = 0 ,lenanchors = anchors.length ; i < lenanchors ; i++){
313                 if(anchors[i].getAttribute('class') == 'buttonPlus'){
314                     anchors[i].setAttribute('onclick',"CloneSubfield('" + new_id + "','" + advancedMARCEditor + "'); return false;");
315                 } else if (anchors[i].getAttribute('class') == 'buttonMinus') {
316                     anchors[i].setAttribute('onclick',"UnCloneField('" + new_id + "'); return false;");
317                 }
318             }
319         }
320     }
321     catch(e){
322         // do nothig if ButtonPlus & CloneButtonPlus don't exist.
323     }
324     // insert this line on the page
325     original.parentNode.insertBefore(clone,original.nextSibling);
328 function AddEventHandlers (oldcontrol, newcontrol, newinputid ) {
329 // This function is a helper for CloneField and CloneSubfield.
330 // It adds the event handlers from oldcontrol to newcontrol.
331 // newinputid is the id attribute of the cloned controlling input field
332 // Note: This code depends on the jQuery data for events; this structure
333 // is moved to _data as of jQuery 1.8.
334     var ev= $(oldcontrol).data('events');
335     if(typeof ev != 'undefined') {
336         $.each(ev, function(prop,val) {
337             $.each(val, function(prop2,val2) {
338                 $(newcontrol).off( val2.type );
339                 $(newcontrol).on( val2.type, {id: newinputid}, val2.handler );
340             });
341         });
342     }
345  /**
346  * This function removes or clears unwanted subfields
347  */
348 function UnCloneField(index) {
349     var original = document.getElementById(index);
350     var canUnclone = false;
351     if ($(original).hasClass("tag")) {
352         // unclone a field, check if there will remain one field
353         var fieldCode = getFieldCode(index);
354         // tag divs with id begining with original field code
355         var cloneFields = $('.tag[id^="tag_'+fieldCode+'"]');
356         if (cloneFields.length > 1) {
357             canUnclone = true;
358         }
359     } else {
360         // unclone a subfield, check if there will remain one subfield
361         var subfieldCode = getFieldAndSubfieldCode(index);
362         // subfield divs of same field with id begining with original field and subfield field code
363         var cloneSubfields = $(original).parent().children('.subfield_line[id^="subfield'+subfieldCode+'"]');
364         if (cloneSubfields.length > 1) {
365             canUnclone = true;
366         }
367     }
368     if (canUnclone) {
369         // remove clone
370         original.parentNode.removeChild(original);
371     } else {
372         // clear inputs, but don't delete
373         $(":input.input_marceditor", original).each(function(){
374             // thanks to http://www.learningjquery.com/2007/08/clearing-form-data for
375             // hint about clearing selects correctly
376             var type = this.type;
377             var tag = this.tagName.toLowerCase();
378             if (type == 'text' || type == 'password' || tag == 'textarea') {
379                 this.value = "";
380             } else if (type == 'checkbox' || type == 'radio') {
381                 this.checked = false;
382             } else if (tag == 'select') {
383                 this.selectedIndex = -1;
384             }
385         });
386         $(":input.indicator", original).val("");
387     }
391  * This function create a random number
392  */
393 function CreateKey(){
394     return parseInt(Math.random() * 100000);
398  * This function allows to move a subfield up by clickink on the 'up' button .
399  */
400 function upSubfield(index) {
401     try{
402         var line = document.getElementById(index); // get the line where the user has clicked.
403     } catch(e) {
404         return; // this line doesn't exist...
405     }
406     var tag = line.parentNode; // get the dad of this line. (should be "<div id='tag_...'>")
408     // getting all subfields for this tag
409     var subfields = tag.getElementsByTagName('div');
410     var subfieldsLength = subfields.length;
412     if(subfieldsLength<=1) return; // nothing to do if there is just one subfield.
414     // among all subfields
415     for(var i=0;i<subfieldsLength;i++){
416         if(subfields[i].getAttribute('id') == index){ //looking for the subfield which is clicked :
417             if(i==1){ // if the clicked subfield is on the top
418                 tag.appendChild(subfields[1]);
419                 return;
420             } else {
421                 var lineAbove = subfields[i-1];
422                 tag.insertBefore(line,lineAbove);
423                 return;
424             }
425         }
426     }
429 // FIXME :: is it used ?
430 function unHideSubfield(index,labelindex) {
431     subfield = document.getElementById(index);
432     subfield.style.display = 'block';
433     label = document.getElementById(labelindex);
434     label.style.display='none';
437 /* Functions developed for additem.tt */
440  * To clone a subfield.<br>
441  * @param original subfield div to clone
442  */
443 function CloneItemSubfield(original){
444     var clone = original.cloneNode(true);
445     var new_key = CreateKey();
447     // set the attribute for the new 'div' subfields
448     var inputs     = clone.getElementsByTagName('input');
449     var selects    = clone.getElementsByTagName('select');
450     var textareas  = clone.getElementsByTagName('textarea');
452     // input (except hidden type)
453     var id_input = "";
454     for(var i=0,len=inputs.length; i<len ; i++ ){
455         if (inputs[i].getAttribute('type') != 'hidden') {
456             id_input = inputs[i].getAttribute('id')+new_key;
457             inputs[i].setAttribute('id',id_input);
458         }
459     }
461     // select
462     for(var i=0,len=selects.length; i<len ; i++ ){
463         id_input = selects[i].getAttribute('id')+new_key;
464         selects[i].setAttribute('id',selects[i].getAttribute('id')+new_key);
465     }
467     // textarea
468     for(var i=0,len=textareas.length; i<len ; i++ ){
469         id_input = textareas[i].getAttribute('id')+new_key;
470         textareas[i].setAttribute('id',textareas[i].getAttribute('id')+new_key);
471     }
473     // when cloning a subfield, reset its label too.
474     var label = clone.getElementsByTagName('label')[0];
475     label.setAttribute('for',id_input);
477     // setting a new if for the parent div
478     var new_id = original.getAttribute('id')+new_key;
479     clone.setAttribute('id',new_id);
481     // insert this line on the page
482     original.parentNode.insertBefore(clone,original.nextSibling);
486  * Check mandatory subfields of a cataloging form and adds <code>missing</code> class to those who are empty.<br>
487  * @param p the parent object of subfields to check
488  * @return the number of empty mandatory subfields
489  */
490 function CheckMandatorySubfields(p){
491     var total = 0;
492     $(p).find(".subfield_line input[name='mandatory'][value='1']").each(function(i){
493         var editor = $(this).siblings("[name='field_value']");
494         if (!editor.val()) {
495             editor.addClass("missing");
496             total++;
497         }
498     });
499     return total;
502  $(document).ready(function() {
503     $("input.input_marceditor, input.indicator").addClass('noEnterSubmit');