Bug 35554: Authority search popup width 800px
[koha.git] / koha-tmpl / intranet-tmpl / prog / js / cataloging.js
1 /* global __ */
2 /* exported openAuth ExpandField CloneField CloneSubfield UnCloneField CloneItemSubfield CheckMandatorySubfields */
3
4 /*
5  * Unified file for catalogue edition
6  */
7
8 /* Functions developed for addbiblio.tt and authorities.tt */
9
10 // returns the fieldcode based upon tag div id
11 function getFieldCode(tagDivId){
12     // format : tag_<tagnumber>_...
13     return tagDivId.substr(3+1,3);
14 }
15
16 //returns the field and subfieldcode based upon subfield div id
17 function getFieldAndSubfieldCode(subfieldDivId){
18     // format : subfield<tagnumber><subfieldnumber>...
19     return subfieldDivId.substr(8,3+1);
20 }
21
22 //returns the subfieldcode based upon subfieldid writing
23 function getSubfieldCode(tagsubfieldid){
24     // 3 : tag +3 : tagnumber +4 : number of _ +8 subfield -1 begins at 0
25     return tagsubfieldid.substr(3+3+4+8-1,1);
26 }
27
28 // Take the base of tagsubfield information (removing the subfieldcodes and subfieldindexes)
29 // returns the filter
30 function getTagInputnameFilter(tagsubfieldid){
31     var tagsubfield=tagsubfieldid.substr(0,tagsubfieldid.lastIndexOf("_"));
32     var tagcode=tagsubfield.substr(tagsubfield.lastIndexOf("_"));
33     tagsubfield=tagsubfield.substr(0,tagsubfield.lastIndexOf("_"));
34     tagsubfield=tagsubfield.substr(0,tagsubfield.lastIndexOf("_"));
35     tagsubfield=tagsubfield+"_."+tagcode;
36     return tagsubfield;
37 }
38
39 // if source is "auth", we are editing an authority otherwise it is a biblio
40 function openAuth(tagsubfieldid,authtype,source) {
41     // let's take the base of tagsubfield information (removing the indexes and the codes
42     var element=document.getElementById(tagsubfieldid);
43     var tagsubfield=getTagInputnameFilter(tagsubfieldid);
44     var elementsubfcode=getSubfieldCode(element.name);
45     var mainmainstring=element.value;
46     var mainstring = new Array();
47
48     var ul = element.closest('ul');
49     var inputs = ul ? ul.getElementsByTagName('input') : element.parentNode.getElementsByTagName('input');
50     for (var myindex =0; myindex<inputs.length;myindex++){
51         if (inputs[myindex].name && inputs[myindex].name.match(tagsubfield)){
52             var subfieldcode=getSubfieldCode(inputs[myindex].name);
53             if (isNaN(parseInt(subfieldcode)) && inputs[myindex].value != "" && subfieldcode!=elementsubfcode){
54                 mainstring.push(inputs[myindex].value);
55             }
56         }
57     }
58     mainstring = mainstring.join(' ');
59     window.open("../authorities/auth_finder.pl?source="+source+"&authtypecode="+authtype+"&index="+tagsubfieldid+"&value_mainstr="+encodeURIComponent(mainmainstring)+"&value_main="+encodeURIComponent(mainstring), "_blank",'width=800,height=550,toolbar=false,scrollbars=yes');
60 }
61
62 function ExpandField() {
63     let index = this.dataset.field_id;
64     var original = document.getElementById(index); //original <li>
65     var lis = original.getElementsByTagName('li');
66     for(var i=0,lislen = lis.length ; i<lislen ; i++){   // foreach li
67         if(lis[i].hasAttribute('id') == 0 ) {continue; } // li element is specific to Select2
68         if(lis[i].getAttribute('id').match(/^subfield/)){  // if it s a subfield
69             if (!lis[i].style.display) {
70                 // first time => show all subfields
71                 lis[i].style.display = 'flex';
72             } else if (lis[i].style.display == 'none') {
73                 // show
74                 lis[i].style.display = 'flex';
75             } else {
76                 // hide
77                 lis[i].style.display = 'none';
78             }
79         }
80     }
81     return false;
82 }
83
84 var current_select2;
85 var Select2Utils = {
86     removeSelect2: function(selects) {
87         if ($.fn.select2) {
88             $(selects).each(function(){
89                 $(this).select2('destroy');
90             });
91         }
92     },
93
94     initSelect2: function(selects) {
95         if ($.fn.select2) {
96             if ( window.auth_values_creation === undefined || ! auth_values_creation ) {
97                 $(selects).select2().on("select2:clear", function () {
98                     $(this).on("select2:opening.cancelOpen", function (evt) {
99                         evt.preventDefault();
100                         $(this).off("select2:opening.cancelOpen");
101                     });
102                 });
103             } else {
104                 $(selects).each(function(){
105                     if ( !$(this).data("category") ) {
106                         $(this).select2().on("select2:clear", function () {
107                             $(this).on("select2:opening.cancelOpen", function (evt) {
108                                 evt.preventDefault();
109                                 $(this).off("select2:opening.cancelOpen");
110                             });
111                         });
112                     } else {
113                         $(this).select2({
114                             tags: true,
115                             createTag: function (tag) {
116                                 return {
117                                     id: tag.term,
118                                     text: tag.term,
119                                     newTag: true
120                                 };
121                             },
122                             templateResult: function(state) {
123                                 if (state.newTag) {
124                                     return state.text + " " + __("(select to create)");
125                                 }
126                                 return state.text;
127                             }
128                         }).on("select2:select", function(e) {
129                             if(e.params.data.newTag){
130                                 current_select2 = this;
131                                 var category = $(this).data("category");
132                                 $("#avCreate #new_av_category").html(category);
133                                 $("#avCreate input[name='category']").val(category);
134                                 $("#avCreate input[name='value']").val('');
135                                 $("#avCreate input[name='description']").val(e.params.data.text);
136
137                                 $(this).val($(this).find("option:first").val()).trigger('change');
138                                 $('#avCreate').modal({show:true});
139                             }
140                         }).on("select2:clear", function () {
141                             $(this).on("select2:opening.cancelOpen", function (evt) {
142                                 evt.preventDefault();
143
144                                 $(this).off("select2:opening.cancelOpen");
145                             });
146                         });
147                     }
148                 });
149             }
150         }
151     }
152 };
153
154 /**
155  * To clone a field
156  * @param hideMarc '0' for false, '1' for true
157  * @param advancedMARCEditor '0' for false, '1' for true
158  */
159 function CloneField(index, hideMarc, advancedMARCEditor) {
160     var original = document.getElementById(index); //original <li>
161     Select2Utils.removeSelect2($(original).find('select'));
162
163     var clone = original.cloneNode(true);
164     var new_key = CreateKey();
165     var new_id  = original.getAttribute('id')+new_key;
166
167     clone.setAttribute('id',new_id); // setting a new id for the parent li
168
169     var divs = Array.from(clone.getElementsByTagName('li')).concat(Array.from(clone.getElementsByTagName('div')));
170
171     // if hide_marc, indicators are hidden fields
172     // setting a new name for the new indicator
173     for(var i=0; i < 2; i++) {
174         var indicator = clone.getElementsByTagName('input')[i];
175         indicator.setAttribute('name',indicator.getAttribute('name')+new_key);
176     }
177
178     // settings all subfields
179     var divslen = divs.length;
180     for( i=0; i < divslen ; i++ ){      // foreach div/li
181         if( divs[i].getAttribute("id") && divs[i].getAttribute("id").match(/^subfield/)){  // if it s a subfield
182
183             // set the attribute for the new 'li' subfields
184             divs[i].setAttribute('id',divs[i].getAttribute('id')+new_key);
185
186             var inputs   = divs[i].getElementsByTagName('input');
187             var id_input = "";
188             var olddiv;
189             var oldcontrol;
190
191             for( j = 0 ; j < inputs.length ; j++ ) {
192                 if(inputs[j].getAttribute("id") && inputs[j].getAttribute("id").match(/^tag_/) ){
193                     inputs[j].value = "";
194
195                     //Remove the color added by the automatic linker
196                     $(inputs[j]).removeClass("matching_authority_field no_matching_authority_field");
197                 }
198             }
199             var textareas = divs[i].getElementsByTagName('textarea');
200             for( j = 0 ; j < textareas.length ; j++ ) {
201                 if(textareas[j].getAttribute("id") && textareas[j].getAttribute("id").match(/^tag_/) ){
202                     textareas[j].value = "";
203                 }
204             }
205             // Remove the status icons added by the automatic linker
206             $(divs[i]).find('.subfield_status').remove();
207             if( inputs.length > 0 ){
208                 inputs[0].setAttribute('id',inputs[0].getAttribute('id')+new_key);
209                 inputs[0].setAttribute('name',inputs[0].getAttribute('name')+new_key);
210
211                 try {
212                     id_input = inputs[1].getAttribute('id')+new_key;
213                     inputs[1].setAttribute('id',id_input);
214                     inputs[1].setAttribute('name',inputs[1].getAttribute('name')+new_key);
215                 } catch(e) {
216                     try{ // it s a select if it is not an input
217                         var selects = divs[i].getElementsByTagName('select');
218                         id_input = selects[0].getAttribute('id')+new_key;
219                         selects[0].setAttribute('id',id_input);
220                         selects[0].setAttribute('name',selects[0].getAttribute('name')+new_key);
221                         selects[0].selectedIndex = -1;
222                     }catch(e2){ // it is a textarea if it s not a select or an input
223                         var textareas = divs[i].getElementsByTagName('textarea');
224                         if( textareas.length > 0 ){
225                             id_input = textareas[0].getAttribute('id')+new_key;
226                             textareas[0].setAttribute('id',id_input);
227                             textareas[0].setAttribute('name',textareas[0].getAttribute('name')+new_key);
228                         }
229                     }
230                 }
231                 if( $(inputs[1]).hasClass('framework_plugin') ) {
232                     olddiv= original.getElementsByTagName('li')[i];
233                     oldcontrol= olddiv.getElementsByTagName('input')[1];
234                     AddEventHandlers( oldcontrol,inputs[1],id_input );
235                 }
236             }
237             // when cloning a subfield, re set its label too.
238             try {
239                 var labels = divs[i].getElementsByTagName('label');
240                 labels[0].setAttribute('for', id_input);
241             }
242             catch(e) {
243                 // do nothing if label does not exist.
244             }
245
246             // setting its '+' and '-' buttons
247             try {
248                 var anchors = divs[i].getElementsByTagName('a');
249                 for (var j = 0; j < anchors.length; j++) {
250                     if(anchors[j].getAttribute('class') == 'buttonPlus'){
251                         anchors[j].setAttribute('onclick',"CloneSubfield('" + divs[i].getAttribute('id') + "','" + advancedMARCEditor + "'); return false;");
252                     } else if (anchors[j].getAttribute('class') == 'buttonMinus') {
253                         anchors[j].setAttribute('onclick',"UnCloneField('" + divs[i].getAttribute('id') + "'); return false;");
254                     }
255                 }
256             }
257             catch(e){
258                 // do nothig if ButtonPlus & CloneButtonPlus don t exist.
259             }
260
261             // button ...
262             var spans=0;
263             try {
264                 spans = divs[i].getElementsByTagName('a');
265             } catch(e) {
266                 // no spans
267             }
268             if(spans){
269                 var buttonDot;
270                 if(!CloneButtonPlus){ // it s impossible to have  + ... (buttonDot AND buttonPlus)
271                     buttonDot = spans[0];
272                     if(buttonDot){
273                         // 2 possibilities :
274                         try{
275                             if( $(buttonDot).hasClass('framework_plugin') ) {
276                                 olddiv= original.getElementsByTagName('li')[i];
277                                 oldcontrol= olddiv.getElementsByTagName('a')[0];
278                                 AddEventHandlers(oldcontrol,buttonDot,id_input);
279                             }
280                             try {
281                                 // do not copy the script section.
282                                 var script = spans[0].getElementsByTagName('script')[0];
283                                 spans[0].removeChild(script);
284                             } catch(e) {
285                                 // do nothing if there is no script
286                             }
287                         } catch(e){
288                             //
289                         }
290                     }
291                 }
292             }
293
294         } else { // it's a indicator div
295             if ( divs[i].getAttribute("id") && divs[i].getAttribute('id').match(/^div_indicator/)) {
296
297                 // setting a new id for the indicator div
298                 divs[i].setAttribute('id',divs[i].getAttribute('id')+new_key);
299
300                 inputs = divs[i].getElementsByTagName('input');
301                 inputs[0].setAttribute('id',inputs[0].getAttribute('id')+new_key);
302                 inputs[1].setAttribute('id',inputs[1].getAttribute('id')+new_key);
303
304                 var CloneButtonPlus;
305                 try {
306                     anchors = divs[i].getElementsByTagName('a');
307                     for ( j = 0; j < anchors.length; j++) {
308                         if (anchors[j].getAttribute('class') == 'buttonPlus') {
309                             anchors[j].setAttribute('onclick',"CloneField('" + new_id + "','" + hideMarc + "','" + advancedMARCEditor + "'); return false;");
310                         } else if (anchors[j].getAttribute('class') == 'buttonMinus') {
311                             anchors[j].setAttribute('onclick',"UnCloneField('" + new_id + "'); return false;");
312                         } else if (anchors[j].getAttribute('class') == 'expandfield') {
313                             anchors[j].setAttribute('data-field_id',new_id);
314                         }
315                     }
316                 }
317                 catch(e){
318                     // do nothig CloneButtonPlus doesn't exist.
319                 }
320
321             }
322         }
323     }
324
325     // insert this line on the page
326     original.parentNode.insertBefore(clone,original.nextSibling);
327
328     $(clone).find("ul.sortable_subfield").each((i, e) => {
329         Sortable.create(e, {
330             handle: '.handle',
331             direction: 'vertical',
332             animation: 150,
333         });
334     });
335
336     Select2Utils.initSelect2($(original).find('select'));
337     Select2Utils.initSelect2($(clone).find('select'));
338 }
339
340
341 /**
342  * To clone a subfield
343  * @param index
344  * @param advancedMARCEditor '0' for false, '1' for true
345  */
346 function CloneSubfield(index, advancedMARCEditor){
347     var original = document.getElementById(index); //original <div>
348     Select2Utils.removeSelect2($(original).find('select'));
349     var clone = original.cloneNode(true);
350     var new_key = CreateKey();
351     // set the attribute for the new 'li' subfields
352     var inputs     = clone.getElementsByTagName('input');
353     var selects    = clone.getElementsByTagName('select');
354     var textareas  = clone.getElementsByTagName('textarea');
355     var linkid;
356     var oldcontrol;
357
358     // input
359     var id_input = "";
360     for(var i=0,len=inputs.length; i<len ; i++ ){
361         id_input = inputs[i].getAttribute('id')+new_key;
362         inputs[i].setAttribute('id',id_input);
363         inputs[i].setAttribute('name',inputs[i].getAttribute('name')+new_key);
364         if(inputs[i].getAttribute("id") && inputs[i].getAttribute("id").match(/^tag_/) ){
365             inputs[i].value = "";
366         }
367         linkid = id_input;
368     }
369
370     // Plugin input
371     if( $(inputs[1]).hasClass('framework_plugin') ) {
372         oldcontrol= original.getElementsByTagName('input')[1];
373         AddEventHandlers( oldcontrol, inputs[1], linkid );
374     }
375
376     // select
377     for(i=0,len=selects.length; i<len ; i++ ){
378         id_input = selects[i].getAttribute('id')+new_key;
379         selects[i].setAttribute('id',selects[i].getAttribute('id')+new_key);
380         selects[i].setAttribute('name',selects[i].getAttribute('name')+new_key);
381         selects[i].selectedIndex = -1;
382         linkid = id_input;
383     }
384
385     // textarea
386     for( i=0,len=textareas.length; i<len ; i++ ){
387         id_input = textareas[i].getAttribute('id')+new_key;
388         textareas[i].setAttribute('id',textareas[i].getAttribute('id')+new_key);
389         textareas[i].setAttribute('name',textareas[i].getAttribute('name')+new_key);
390         if(textareas[i].getAttribute("id") && textareas[i].getAttribute("id").match(/^tag_/) ){
391             textareas[i].value = "";
392         }
393         linkid = id_input;
394     }
395
396     // Handle click event on buttonDot for plugin
397     var links  = clone.getElementsByTagName('a');
398     if( $(links[0]).hasClass('framework_plugin') ) {
399         oldcontrol= original.getElementsByTagName('a')[0];
400         AddEventHandlers( oldcontrol, links[0], linkid );
401     }
402
403     if(advancedMARCEditor == '0') {
404         // when cloning a subfield, reset its label too.
405         var label = clone.getElementsByTagName('label')[0];
406         if( label ){
407             label.setAttribute('for',id_input);
408         }
409     }
410
411     // setting a new id for the parent div
412     var new_id  = original.getAttribute('id')+new_key;
413     clone.setAttribute('id',new_id);
414
415     try {
416         var anchors = clone.getElementsByTagName('a');
417         if(anchors.length){
418             for( i = 0 ,len = anchors.length ; i < len ; i++){
419                 if(anchors[i].getAttribute('class') == 'buttonPlus'){
420                     anchors[i].setAttribute('onclick',"CloneSubfield('" + new_id + "','" + advancedMARCEditor + "'); return false;");
421                 } else if (anchors[i].getAttribute('class') == 'buttonMinus') {
422                     anchors[i].setAttribute('onclick',"UnCloneField('" + new_id + "'); return false;");
423                 }
424             }
425         }
426     }
427     catch(e){
428         // do nothig if ButtonPlus & CloneButtonPlus don't exist.
429     }
430     // insert this line on the page
431     original.parentNode.insertBefore(clone,original.nextSibling);
432
433     //Restablish select2 for the cloned elements.
434     Select2Utils.initSelect2($(original).find('select'));
435     Select2Utils.initSelect2($(clone).find('select'));
436
437     // delete data of cloned subfield
438     clone.querySelectorAll('input.input_marceditor').value = "";
439 }
440
441 function AddEventHandlers (oldcontrol, newcontrol, newinputid ) {
442 // This function is a helper for CloneField and CloneSubfield.
443 // It adds the event handlers from oldcontrol to newcontrol.
444 // newinputid is the id attribute of the cloned controlling input field
445 // Note: This code depends on the jQuery data for events; this structure
446 // is moved to _data as of jQuery 1.8.
447     var ev = $._data(oldcontrol, "events");
448     if(typeof ev != 'undefined') {
449         $.each(ev, function(prop,val) {
450             $.each(val, function(prop2,val2) {
451                 $(newcontrol).off( val2.type );
452                 $(newcontrol).on( val2.type, {id: newinputid}, val2.handler );
453             });
454         });
455     }
456 }
457
458 /**
459  * This function removes or clears unwanted subfields
460  */
461 function UnCloneField(index) {
462     var original = document.getElementById(index);
463     var canUnclone = false;
464     if ($(original).hasClass("tag")) {
465         // unclone a field, check if there will remain one field
466         var fieldCode = getFieldCode(index);
467         // tag divs with id begining with original field code
468         var cloneFields = $('.tag[id^="tag_'+fieldCode+'"]');
469         if (cloneFields.length > 1) {
470             canUnclone = true;
471         }
472     } else {
473         // unclone a subfield, check if there will remain one subfield
474         var subfieldCode = getFieldAndSubfieldCode(index);
475         // subfield divs of same field with id begining with original field and subfield field code
476         var cloneSubfields = $(original).parent().children('.subfield_line[id^="subfield'+subfieldCode+'"]');
477         if (cloneSubfields.length > 1) {
478             canUnclone = true;
479         }
480     }
481     if (canUnclone) {
482         // remove clone
483         original.parentNode.removeChild(original);
484     } else {
485         // clear inputs, but don't delete
486         $(":input.input_marceditor", original).each(function(){
487             // thanks to http://www.learningjquery.com/2007/08/clearing-form-data for
488             // hint about clearing selects correctly
489             var type = this.type;
490             var tag = this.tagName.toLowerCase();
491             if (type == 'text' || type == 'password' || tag == 'textarea') {
492                 this.value = "";
493             } else if (type == 'checkbox' || type == 'radio') {
494                 this.checked = false;
495             } else if (tag == 'select') {
496                 this.selectedIndex = -1;
497                 // required for Select2 to be able to update its control
498                 $(this).trigger('change');
499             }
500         });
501         $(":input.indicator", original).val("");
502     }
503 }
504
505 /**
506  * This function create a random number
507  */
508 function CreateKey(){
509     return parseInt(Math.random() * 100000);
510 }
511
512 /* Functions developed for additem.tt */
513
514 /**
515  * To clone a subfield.<br>
516  * @param original subfield div to clone
517  */
518 function CloneItemSubfield(original){
519     Select2Utils.removeSelect2($(original).find('select'));
520     var clone = original.cloneNode(true);
521     var new_key = CreateKey();
522
523     // set the attribute for the new 'li' subfields
524     var inputs     = clone.getElementsByTagName('input');
525     var selects    = clone.getElementsByTagName('select');
526     var textareas  = clone.getElementsByTagName('textarea');
527
528     // input (except hidden type)
529     var id_input = "";
530     for(var i=0,len=inputs.length; i<len ; i++ ){
531         if (inputs[i].getAttribute('type') != 'hidden') {
532             id_input = inputs[i].getAttribute('id')+new_key;
533             inputs[i].setAttribute('id',id_input);
534         }
535     }
536
537     // select
538     for( i=0,len=selects.length; i<len ; i++ ){
539         id_input = selects[i].getAttribute('id')+new_key;
540         selects[i].setAttribute('id',selects[i].getAttribute('id')+new_key);
541     }
542
543     // textarea
544     for( i=0,len=textareas.length; i<len ; i++ ){
545         id_input = textareas[i].getAttribute('id')+new_key;
546         textareas[i].setAttribute('id',textareas[i].getAttribute('id')+new_key);
547     }
548
549     // when cloning a subfield, reset its label too.
550     var label = clone.getElementsByTagName('label')[0];
551     label.setAttribute('for',id_input);
552
553     // setting a new if for the parent div
554     var new_id = original.getAttribute('id')+new_key;
555     clone.setAttribute('id',new_id);
556
557     // Don't clone "RegEx". We don't handle it for repeatable subfields
558     var links = clone.getElementsByTagName('a');
559     for( i = 0 ,len = links.length ; i < len ; i++){
560         if( $(links[i]).hasClass('field_regex') ) {
561             $(links[i]).remove();
562         }
563     }
564
565     // insert this line on the page
566     original.parentNode.insertBefore(clone,original.nextSibling);
567     Select2Utils.initSelect2($(original).find('select'));
568     Select2Utils.initSelect2($(clone).find('select'));
569 }
570
571 /**
572  * Check mandatory subfields of a cataloging form and adds <code>missing</code> class to those who are empty.<br>
573  * @param p the parent object of subfields to check
574  * @return the number of empty mandatory subfields
575  */
576 function CheckMandatorySubfields(p){
577     var total = 0;
578     $(p).find(".subfield_line input[name='mandatory'][value='1']").each(function(){
579         var editor = $(this).siblings(".input_marceditor");
580         if ( !editor.length ) { // Deal with date inputs
581             editor = $(this).siblings(".flatpickr_wrapper").find(".input_marceditor");
582         }
583         if (!editor.val()) {
584             editor.addClass("missing");
585             total++;
586         }
587     });
588     return total;
589 }
590
591 function CheckImportantSubfields(p){
592     var total = 0;
593     $(p).find(".subfield_line input[name='important'][value='1']").each(function(i){
594         var editor = $(this).siblings(".input_marceditor");
595         if ( !editor.length ) { // Deal with date inputs
596             editor = $(this).siblings(".flatpickr_wrapper").find(".input_marceditor");
597         }
598         if (!editor.val()) {
599             editor.addClass("missing");
600             total++;
601         }
602     });
603     return total;
604 }
605
606 $(document).ready(function() {
607     $("input.input_marceditor, input.indicator").addClass('noEnterSubmit');
608     $(document).ajaxSuccess(function() {
609         $("input.input_marceditor, input.indicator").addClass('noEnterSubmit');
610     });
611
612     if ( window.editor === undefined ) { // TODO This does not work with the advanced editor
613         Select2Utils.initSelect2($('.subfield_line select[data-category=""]')); // branches, itemtypes and cn_source
614         Select2Utils.initSelect2($('.subfield_line select[data-category!=""]'));
615     }
616
617     $("#avCreate").on("hidden.bs.modal", function(){
618         add_new_av.resetForm(); /* resets form state for jQuery Validate plugin */
619         $("#add_new_av")[0].reset();
620         $(".avCreate_error").hide();
621     });
622
623     var add_new_av = $("#add_new_av").validate({
624         submitHandler: function(form) {
625             var category         = form.category.value;
626             var value            = form.value.value;
627             var description      = form.description.value;
628             var opac_description = form.opac_description.value;
629
630             var data = "category="+encodeURIComponent(category)
631                 +"&value="+encodeURIComponent(value)
632                 +"&description="+encodeURIComponent(description)
633                 +"&opac_description="+encodeURIComponent(opac_description);
634             $.ajax({
635                 type: "POST",
636                 url: "/cgi-bin/koha/svc/authorised_values",
637                 data: data,
638                 success: function(response) {
639                     $('#avCreate').modal('hide');
640
641                     $(current_select2).append('<option selected value="'+response.value+'">'+response.description+'</option>');
642                     $("#avCreate").modal("hide");
643                 },
644                 error: function() {
645                     $(".avCreate_error").html(__("Something went wrong. Maybe the value already exists?")).show();
646                 }
647             });
648             return false;
649         }
650     });
651
652 });