View | Details | Raw Unified | Return to bug 41566
Collapse All | Expand All

(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers/tables/items/catalogue_detail.inc (-361 / +417 lines)
Lines 162-218 Link Here
162
            holdings: "[% PROCESS 'build_table' tab="holdings" | collapse | $tojson %]",
162
            holdings: "[% PROCESS 'build_table' tab="holdings" | collapse | $tojson %]",
163
            otherholdings: "[% PROCESS 'build_table' tab="otherholdings" | collapse | $tojson %]",
163
            otherholdings: "[% PROCESS 'build_table' tab="otherholdings" | collapse | $tojson %]",
164
        };
164
        };
165
166
    </script>
165
    </script>
167
168
    <script>
166
    <script>
169
        let items_selection = {};
167
        let items_selection = {};
170
168
171
        function _itemSelectionBuildLink(tab_id, link_class) {
169
        function _itemSelectionBuildLink(tab_id, link_class) {
172
173
            let itemnumbers = items_selection[tab_id];
170
            let itemnumbers = items_selection[tab_id];
174
            let tab = $("#" + tab_id + "_panel" );
171
            let tab = $("#" + tab_id + "_panel");
175
            let form = tab.find(link_class);
172
            let form = tab.find(link_class);
176
            $(form).find("input[name='itemnumber']").remove();
173
            $(form).find("input[name='itemnumber']").remove();
177
174
178
            $(itemnumbers).each(function() {
175
            $(itemnumbers).each(function () {
179
                $(form).append("<input name='itemnumber' type='hidden' value='%s'/>".format(this));
176
                $(form).append("<input name='itemnumber' type='hidden' value='%s'/>".format(this));
180
            });
177
            });
181
            return !!itemnumbers.length
178
            return !!itemnumbers.length;
182
        }
179
        }
183
        function itemSelectionBuildDeleteLink(tab_id) {
180
        function itemSelectionBuildDeleteLink(tab_id) {
184
            return _itemSelectionBuildLink(tab_id, '.itemselection_action_delete_form');
181
            return _itemSelectionBuildLink(tab_id, ".itemselection_action_delete_form");
185
        }
182
        }
186
        function itemSelectionBuildModifyLink(tab_id) {
183
        function itemSelectionBuildModifyLink(tab_id) {
187
            return _itemSelectionBuildLink(tab_id, '.itemselection_action_modify_form');
184
            return _itemSelectionBuildLink(tab_id, ".itemselection_action_modify_form");
188
        }
185
        }
189
186
190
        function itemSelectionBuildActionLinks(tab_id) {
187
        function itemSelectionBuildActionLinks(tab_id) {
191
            var delete_link_ok = itemSelectionBuildDeleteLink(tab_id);
188
            var delete_link_ok = itemSelectionBuildDeleteLink(tab_id);
192
            var modify_link_ok = itemSelectionBuildModifyLink(tab_id);
189
            var modify_link_ok = itemSelectionBuildModifyLink(tab_id);
193
            var tab = $("#" + tab_id + "_panel" );
190
            var tab = $("#" + tab_id + "_panel");
194
            if (modify_link_ok || delete_link_ok) {
191
            if (modify_link_ok || delete_link_ok) {
195
                $('.itemselection_actions', tab).show();
192
                $(".itemselection_actions", tab).show();
196
            } else {
193
            } else {
197
                $('.itemselection_actions', tab).hide();
194
                $(".itemselection_actions", tab).hide();
198
            }
195
            }
199
        }
196
        }
200
197
201
        function update_columns_visibility(table_dt, table_settings, user_colvis){
198
        function update_columns_visibility(table_dt, table_settings, user_colvis) {
202
            table_dt.columns().visible(true, false);
199
            table_dt.columns().visible(true, false);
203
            let hidden_ids = _dt_visibility(table_settings, table_dt);
200
            let hidden_ids = _dt_visibility(table_settings, table_dt);
204
            table_dt.columns(hidden_ids).visible(false, false);
201
            table_dt.columns(hidden_ids).visible(false, false);
205
            table_dt.columns().every(function(){
202
            table_dt.columns().every(function () {
206
                let i = this.index();
203
                let i = this.index();
207
                let is_empty = true;
204
                let is_empty = true;
208
                let nodes = this.nodes();
205
                let nodes = this.nodes();
209
                nodes.each((td, ii) => {
206
                nodes.each((td, ii) => {
210
                    if ( $(td).html() !== '' ) {
207
                    if ($(td).html() !== "") {
211
                        is_empty = false;
208
                        is_empty = false;
212
                        return;
209
                        return;
213
                    }
210
                    }
214
                });
211
                });
215
                if ( is_empty ) {
212
                if (is_empty) {
216
                    table_dt.columns(i).visible(false, false);
213
                    table_dt.columns(i).visible(false, false);
217
                }
214
                }
218
            });
215
            });
Lines 221-286 Link Here
221
            }
218
            }
222
        }
219
        }
223
220
224
221
        $(document).ready(function () {
225
        $(document).ready(function() {
222
            $(".SelectAll").on("click", function (e) {
226
227
            $(".SelectAll").on("click",function(e){
228
                e.preventDefault();
223
                e.preventDefault();
229
                let tab_id = $(this).data("tab");
224
                let tab_id = $(this).data("tab");
230
                let tab = $("#" + tab_id + "_panel" );
225
                let tab = $("#" + tab_id + "_panel");
231
                items_selection[tab_id] = [];
226
                items_selection[tab_id] = [];
232
                tab.find("input[name='itemnumber'][type='checkbox']").each( (i, input) => {
227
                tab.find("input[name='itemnumber'][type='checkbox']").each((i, input) => {
233
                    let itemnumber = parseInt($(input).val());
228
                    let itemnumber = parseInt($(input).val());
234
                    items_selection[tab_id].push(itemnumber);
229
                    items_selection[tab_id].push(itemnumber);
235
                    $(input).prop('checked', true);
230
                    $(input).prop("checked", true);
236
                });
231
                });
237
                itemSelectionBuildActionLinks(tab_id);
232
                itemSelectionBuildActionLinks(tab_id);
238
            });
233
            });
239
234
240
            $(".ClearAll").on("click",function(e){
235
            $(".ClearAll").on("click", function (e) {
241
                e.preventDefault();
236
                e.preventDefault();
242
                let tab_id = $(this).data("tab");
237
                let tab_id = $(this).data("tab");
243
                let tab = $("#" + tab_id + "_panel" );
238
                let tab = $("#" + tab_id + "_panel");
244
                items_selection[tab_id] = [];
239
                items_selection[tab_id] = [];
245
                $("input[name='itemnumber'][type='checkbox']", tab).prop('checked', false);
240
                $("input[name='itemnumber'][type='checkbox']", tab).prop("checked", false);
246
                itemSelectionBuildActionLinks(tab_id);
241
                itemSelectionBuildActionLinks(tab_id);
247
            });
242
            });
248
249
        });
243
        });
250
244
251
        let filters_shown = false;
245
        let filters_shown = false;
252
        $(document).ready(function() {
246
        $(document).ready(function () {
253
            $(".show_filters").on("click",function(e){
247
            $(".show_filters").on("click", function (e) {
254
                e.preventDefault();
248
                e.preventDefault();
255
                let tab_id = $(this).data("tab");
249
                let tab_id = $(this).data("tab");
256
                let tab = $("#" + tab_id + "_panel" );
250
                let tab = $("#" + tab_id + "_panel");
257
                tab.find(".show_filters").hide();
251
                tab.find(".show_filters").hide();
258
                tab.find(".hide_filters").show();
252
                tab.find(".hide_filters").show();
259
                filters_show = true;
253
                filters_show = true;
260
                $("#"+tab_id+"_table thead tr:eq(1)").remove();
254
                $("#" + tab_id + "_table thead tr:eq(1)").remove();
261
                build_items_table(tab_id, true, { destroy: true }, build_items_table_drawncallback );
255
                build_items_table(tab_id, true, { destroy: true }, build_items_table_drawncallback);
262
                itemSelectionBuildActionLinks(tab_id);
256
                itemSelectionBuildActionLinks(tab_id);
263
            });
257
            });
264
258
265
            $(".hide_filters").on("click",function(e){
259
            $(".hide_filters").on("click", function (e) {
266
                e.preventDefault();
260
                e.preventDefault();
267
                let tab_id = $(this).data("tab");
261
                let tab_id = $(this).data("tab");
268
                let tab = $("#" + tab_id + "_panel" );
262
                let tab = $("#" + tab_id + "_panel");
269
                tab.find(".hide_filters").hide();
263
                tab.find(".hide_filters").hide();
270
                tab.find(".show_filters").show();
264
                tab.find(".show_filters").show();
271
                filters_show = false;
265
                filters_show = false;
272
                $("#"+tab_id+"_table thead tr:eq(1)").remove();
266
                $("#" + tab_id + "_table thead tr:eq(1)").remove();
273
                build_items_table(tab_id, false, { destroy: true }, build_items_table_drawncallback );
267
                build_items_table(tab_id, false, { destroy: true }, build_items_table_drawncallback);
274
                itemSelectionBuildActionLinks(tab_id);
268
                itemSelectionBuildActionLinks(tab_id);
275
            });
269
            });
276
        });
270
        });
277
271
278
        const statuses = {checked_out: _("Checked out"), local_use: _("On-site checkout"), in_transit: _("In transit"), lost: _("Lost"), withdrawn: _("Withdrawn"), damaged:_("Damaged"), not_for_loan: _("Not for loan"), on_hold: _("On hold"), recalled: _("Recalled"), available: _("Available"), restricted: _("Restricted"), in_bundle: _("In bundle")};
272
        const statuses = {
279
        const all_statuses = Object.keys(statuses).map(k => {return {_id: k, _str: statuses[k]}});
273
            checked_out: _("Checked out"),
274
            local_use: _("On-site checkout"),
275
            in_transit: _("In transit"),
276
            lost: _("Lost"),
277
            withdrawn: _("Withdrawn"),
278
            damaged: _("Damaged"),
279
            not_for_loan: _("Not for loan"),
280
            on_hold: _("On hold"),
281
            recalled: _("Recalled"),
282
            available: _("Available"),
283
            restricted: _("Restricted"),
284
            in_bundle: _("In bundle"),
285
        };
286
        const all_statuses = Object.keys(statuses).map(k => {
287
            return { _id: k, _str: statuses[k] };
288
        });
280
289
281
        var coded_values = {
290
        var coded_values = {
282
            library: new Map(all_libraries.map( l => [l.branchname, l.branchcode] )),
291
            library: new Map(all_libraries.map(l => [l.branchname, l.branchcode])),
283
            item_type: new Map(all_item_types.map( i => [i.translated_description, i.itemtype] )),
292
            item_type: new Map(all_item_types.map(i => [i.translated_description, i.itemtype])),
284
            collection_code: av_ccode,
293
            collection_code: av_ccode,
285
            location: av_loc,
294
            location: av_loc,
286
        };
295
        };
Lines 297-429 Link Here
297
        // Do we need separate/new endpoints or do we hack the somewhere client-side?
306
        // Do we need separate/new endpoints or do we hack the somewhere client-side?
298
        let item_table_url = `/api/v1/biblios/${biblionumber}/items?`;
307
        let item_table_url = `/api/v1/biblios/${biblionumber}/items?`;
299
        let embed = ["+strings,_status,home_library,holding_library,checkout,checkout.patron,transfer,transfer+strings,first_hold,first_hold+strings,first_hold.patron,first_hold.desk"];
308
        let embed = ["+strings,_status,home_library,holding_library,checkout,checkout.patron,transfer,transfer+strings,first_hold,first_hold+strings,first_hold.patron,first_hold.desk"];
300
        if (prefs.LocalCoverImages){
309
        if (prefs.LocalCoverImages) {
301
            embed.push('cover_image_ids');
310
            embed.push("cover_image_ids");
302
        }
311
        }
303
        if (prefs.EnableItemGroups){
312
        if (prefs.EnableItemGroups) {
304
            embed.push('item_group_item.item_group.description');
313
            embed.push("item_group_item.item_group.description");
305
        }
314
        }
306
        if (is_serial){
315
        if (is_serial) {
307
            embed.push('serial_item.serial');
316
            embed.push("serial_item.serial");
308
        }
317
        }
309
        if (prefs.UseRecalls){
318
        if (prefs.UseRecalls) {
310
            embed.push('recall', 'recall+strings', 'recall.patron')
319
            embed.push("recall", "recall+strings", "recall.patron");
311
        }
320
        }
312
        embed.push('in_bundle', 'bundle_host', 'bundle_host.biblio', 'bundle_items_lost+count', 'bundle_items_not_lost+count');
321
        embed.push("in_bundle", "bundle_host", "bundle_host.biblio", "bundle_items_lost+count", "bundle_items_not_lost+count");
313
        if (prefs.UseCourseReserves){
322
        if (prefs.UseCourseReserves) {
314
            embed.push('course_item.course_reserves.course');
323
            embed.push("course_item.course_reserves.course");
315
        }
324
        }
316
        if (prefs.ClaimReturnedLostValue){
325
        if (prefs.ClaimReturnedLostValue) {
317
            embed.push('return_claims');
326
            embed.push("return_claims");
318
        }
327
        }
319
328
320
        if (prefs.EasyAnalyticalRecords){
329
        if (prefs.EasyAnalyticalRecords) {
321
            // For host records
330
            // For host records
322
            embed.push('biblio.title');
331
            embed.push("biblio.title");
323
        }
332
        }
324
333
325
        if (analyze){
334
        if (analyze) {
326
            embed.push('analytics_count');
335
            embed.push("analytics_count");
327
        }
336
        }
328
337
329
        let user_colvis = {holdings: {}, otherholdings: {}};
338
        let user_colvis = { holdings: {}, otherholdings: {} };
330
        function build_items_table (tab_id, add_filters, dt_options, drawcallback) {
339
        function build_items_table(tab_id, add_filters, dt_options, drawcallback) {
331
332
            let table_dt;
340
            let table_dt;
333
            if ( dt_options && dt_options.hasOwnProperty('destroy') ) {
341
            if (dt_options && dt_options.hasOwnProperty("destroy")) {
334
                // Keep a copy of the user settings, the destroy is going to trigger the column-visibility.dt event for all columns
342
                // Keep a copy of the user settings, the destroy is going to trigger the column-visibility.dt event for all columns
335
                let user_colvis_bak= Object.assign({}, user_colvis[tab_id]);
343
                let user_colvis_bak = Object.assign({}, user_colvis[tab_id]);
336
                let table_id = "#"+tab_id+"_table";
344
                let table_id = "#" + tab_id + "_table";
337
                if( $.fn.dataTable.isDataTable(table_id) ) {
345
                if ($.fn.dataTable.isDataTable(table_id)) {
338
                    $(table_id).DataTable().destroy();
346
                    $(table_id).DataTable().destroy();
339
                }
347
                }
340
                $(table_id).replaceWith(table_nodes[tab_id]);
348
                $(table_id).replaceWith(table_nodes[tab_id]);
341
                dt_options['destroy'] = null;
349
                dt_options["destroy"] = null;
342
                user_colvis[tab_id] = user_colvis_bak;
350
                user_colvis[tab_id] = user_colvis_bak;
343
            }
351
            }
344
            let default_filters = {};
352
            let default_filters = {};
345
            if (prefs.SeparateHoldings){
353
            if (prefs.SeparateHoldings) {
346
                let branch = prefs.SeparateHoldingsBranch == 'homebranch' ? 'me.home_library_id' : 'me.holding_library_id';
354
                let branch = prefs.SeparateHoldingsBranch == "homebranch" ? "me.home_library_id" : "me.holding_library_id";
347
                if ( tab_id == 'holdings' ) {
355
                if (tab_id == "holdings") {
348
                    default_filters[branch] = logged_in_branchcode;
356
                    default_filters[branch] = logged_in_branchcode;
349
                } else {
357
                } else {
350
                    default_filters[branch] = { '!=': logged_in_branchcode };
358
                    default_filters[branch] = { "!=": logged_in_branchcode };
351
                }
359
                }
352
            }
360
            }
353
361
354
            if (hidden_count){
362
            if (hidden_count) {
355
                default_filters.lost_status = "0";
363
                default_filters.lost_status = "0";
356
            }
364
            }
357
            if ( !items_selection.hasOwnProperty(tab_id) ){
365
            if (!items_selection.hasOwnProperty(tab_id)) {
358
                items_selection[tab_id] = [];
366
                items_selection[tab_id] = [];
359
            }
367
            }
360
368
361
            default_filters._status = function(){
369
            default_filters._status = function () {
362
                return $("#" + tab_id + "_status select").val();
370
                return $("#" + tab_id + "_status select").val();
363
            };
371
            };
364
372
365
var columns = [
373
            var columns = [
366
                {
374
                {
367
                    data: "me.item_id",
375
                    data: "me.item_id",
368
                    searchable: false,
376
                    searchable: false,
369
                    orderable: false,
377
                    orderable: false,
370
                    render: function (data, type, row, meta) {
378
                    render: function (data, type, row, meta) {
371
                        if ( can_edit_items_from.includes(row.home_library_id) || !can_edit_items_from.length ){
379
                        if (can_edit_items_from.includes(row.home_library_id) || !can_edit_items_from.length) {
372
                            if ( items_selection[tab_id].includes(row.item_id) ) {
380
                            if (items_selection[tab_id].includes(row.item_id)) {
373
                                return '<input type="checkbox" value="%s" name="itemnumber" checked />'.format(row.item_id);
381
                                return '<input type="checkbox" value="%s" name="itemnumber" checked />'.format(row.item_id);
374
                            } else {
382
                            } else {
375
                                return '<input type="checkbox" value="%s" name="itemnumber" />'.format(row.item_id);
383
                                return '<input type="checkbox" value="%s" name="itemnumber" />'.format(row.item_id);
376
                            }
384
                            }
377
                        } else {
385
                        } else {
378
                            return ''
386
                            return "";
379
                        }
387
                        }
380
                    }
388
                    },
381
                },
389
                },
382
                ...(prefs.LocalCoverImages ?
390
                ...(prefs.LocalCoverImages
383
                [{
391
                    ? [
384
                    data: "",
392
                          {
385
                    className: "cover",
393
                              data: "",
386
                    searchable: false,
394
                              className: "cover",
387
                    orderable: false,
395
                              searchable: false,
388
                    render: function (data, type, row, meta) {
396
                              orderable: false,
389
                        if ( !row.cover_image_ids.length > 0 ) {
397
                              render: function (data, type, row, meta) {
390
                            return '';
398
                                  if (!row.cover_image_ids.length > 0) {
391
                        }
399
                                      return "";
392
                        let node = '<div class="bookcoverimg">';
400
                                  }
393
                        node += '<div class="cover-slider">';
401
                                  let node = '<div class="bookcoverimg">';
394
                        row.cover_image_ids.forEach(id => {
402
                                  node += '<div class="cover-slider">';
395
                            node += '<div class="cover-image local-coverimg">';
403
                                  row.cover_image_ids.forEach(id => {
396
                            node += '<a href="/cgi-bin/koha/catalogue/image.pl?imagenumber=%s" title="%s">'.format(id, _("Local cover image"));
404
                                      node += '<div class="cover-image local-coverimg">';
397
                            node += '<img src="/cgi-bin/koha/catalogue/image.pl?thumbnail=1&imagenumber=%s" data-link="/cgi-bin/koha/catalogue/imageviewer.pl?itemnumber=%s&imagenumber=%s" alt="%s" />'.format(id, row.item_id, id, _("Local cover image"));
405
                                      node += '<a href="/cgi-bin/koha/catalogue/image.pl?imagenumber=%s" title="%s">'.format(id, _("Local cover image"));
398
                            node += '</a>';
406
                                      node += '<img src="/cgi-bin/koha/catalogue/image.pl?thumbnail=1&imagenumber=%s" data-link="/cgi-bin/koha/catalogue/imageviewer.pl?itemnumber=%s&imagenumber=%s" alt="%s" />'.format(
399
                            node += '</div>';
407
                                          id,
400
                        });
408
                                          row.item_id,
401
                        node += '</div>';
409
                                          id,
402
                        node += '</div>';
410
                                          _("Local cover image")
403
                        return node;
411
                                      );
404
                    }
412
                                      node += "</a>";
405
                }] : []),
413
                                      node += "</div>";
406
                ...(prefs.item_level_itypes ?
414
                                  });
407
                [{
415
                                  node += "</div>";
408
                    data: "me.item_type_id", // FIXME Cannot filter by biblioitem.itemtype
416
                                  node += "</div>";
409
                    datatype: "coded_value:item_type",
417
                                  return node;
410
                    dataFilter: "item_types",
418
                              },
411
                    className: "itype",
419
                          },
412
                    searchable: true,
420
                      ]
413
                    orderable: true,
421
                    : []),
414
                    render: function (data, type, row, meta) {
422
                ...(prefs.item_level_itypes
415
                        let node = '';
423
                    ? [
416
                        let item_type_description = row._strings.item_type_id ? row._strings.item_type_id.str : row.item_type_id;
424
                          {
417
                        if (prefs.noItemTypeImages){
425
                              data: "me.item_type_id", // FIXME Cannot filter by biblioitem.itemtype
418
                            let image_location = item_type_image_locations[row.item_type_id];
426
                              datatype: "coded_value:item_type",
419
                            node += image_location
427
                              dataFilter: "item_types",
420
                                ? '<img class="itemtype-image" src="%s" alt="" /> '.format(escape_str(image_location), escape_str(item_type_description), escape_str(item_type_description))
428
                              className: "itype",
421
                                : '';
429
                              searchable: true,
422
                        }
430
                              orderable: true,
423
                        node += '<span class="itypedesc itypetext">%s</span>'.format(escape_str(item_type_description));
431
                              render: function (data, type, row, meta) {
424
                        return node;
432
                                  let node = "";
425
                    }
433
                                  let item_type_description = row._strings.item_type_id ? row._strings.item_type_id.str : row.item_type_id;
426
                }] : []),
434
                                  if (prefs.noItemTypeImages) {
435
                                      let image_location = item_type_image_locations[row.item_type_id];
436
                                      node += image_location ? '<img class="itemtype-image" src="%s" alt="" /> '.format(escape_str(image_location), escape_str(item_type_description), escape_str(item_type_description)) : "";
437
                                  }
438
                                  node += '<span class="itypedesc itypetext">%s</span>'.format(escape_str(item_type_description));
439
                                  return node;
440
                              },
441
                          },
442
                      ]
443
                    : []),
427
                {
444
                {
428
                    data: "holding_library.name:me.holding_library_id",
445
                    data: "holding_library.name:me.holding_library_id",
429
                    datatype: "coded_value:library",
446
                    datatype: "coded_value:library",
Lines 433-439 var columns = [ Link Here
433
                    orderable: true,
450
                    orderable: true,
434
                    render: function (data, type, row, meta) {
451
                    render: function (data, type, row, meta) {
435
                        return escape_str(row._strings.holding_library_id ? row._strings.holding_library_id.str : row.holding_library_id);
452
                        return escape_str(row._strings.holding_library_id ? row._strings.holding_library_id.str : row.holding_library_id);
436
                    }
453
                    },
437
                },
454
                },
438
                {
455
                {
439
                    data: "home_library.name:me.home_library_id",
456
                    data: "home_library.name:me.home_library_id",
Lines 444-450 var columns = [ Link Here
444
                    orderable: true,
461
                    orderable: true,
445
                    render: function (data, type, row, meta) {
462
                    render: function (data, type, row, meta) {
446
                        return escape_str(row._strings.home_library_id ? row._strings.home_library_id.str : row.home_library_id);
463
                        return escape_str(row._strings.home_library_id ? row._strings.home_library_id.str : row.home_library_id);
447
                    }
464
                    },
448
                },
465
                },
449
                {
466
                {
450
                    data: "me.location",
467
                    data: "me.location",
Lines 457-471 var columns = [ Link Here
457
                        // display current location in parentheses. If not, display current location.
474
                        // display current location in parentheses. If not, display current location.
458
                        // Note that permanent location is a code, and location may be an authval.
475
                        // Note that permanent location is a code, and location may be an authval.
459
                        let loc_str = row._strings.location ? row._strings.location.str : row.location;
476
                        let loc_str = row._strings.location ? row._strings.location.str : row.location;
460
                        if ( row.permanent_location && row.permanent_location != row.location ) {
477
                        if (row.permanent_location && row.permanent_location != row.location) {
461
                            let permanent_loc_str = av_loc.get(row.permanent_location);
478
                            let permanent_loc_str = av_loc.get(row.permanent_location);
462
                            nodes += '%s (%s)'.format(escape_str(permanent_loc_str), escape_str(loc_str));
479
                            nodes += "%s (%s)".format(escape_str(permanent_loc_str), escape_str(loc_str));
463
                        } else {
480
                        } else {
464
                            nodes += escape_str(loc_str);
481
                            nodes += escape_str(loc_str);
465
                        }
482
                        }
466
                        nodes += '</span>';
483
                        nodes += "</span>";
467
                        return nodes;
484
                        return nodes;
468
                    }
485
                    },
469
                },
486
                },
470
                {
487
                {
471
                    data: "me.collection_code",
488
                    data: "me.collection_code",
Lines 474-495 var columns = [ Link Here
474
                    orderable: true,
491
                    orderable: true,
475
                    render: function (data, type, row, meta) {
492
                    render: function (data, type, row, meta) {
476
                        return escape_str(row._strings.collection_code ? row._strings.collection_code.str : row.collection_code);
493
                        return escape_str(row._strings.collection_code ? row._strings.collection_code.str : row.collection_code);
477
                    }
494
                    },
478
                },
495
                },
479
                ...(prefs.EnableItemGroups ?
496
                ...(prefs.EnableItemGroups
480
                [{
497
                    ? [
481
                    data: "item_group_item.item_group.description",
498
                          {
482
                    className: "item_group",
499
                              data: "item_group_item.item_group.description",
483
                    searchable: true,
500
                              className: "item_group",
484
                    orderable: true,
501
                              searchable: true,
485
                    render: function (data, type, row, meta) {
502
                              orderable: true,
486
                        if ( row.item_group_item ) {
503
                              render: function (data, type, row, meta) {
487
                            return escape_str(row.item_group_item.item_group.description);
504
                                  if (row.item_group_item) {
488
                        } else {
505
                                      return escape_str(row.item_group_item.item_group.description);
489
                            return "";
506
                                  } else {
490
                        }
507
                                      return "";
491
                    }
508
                                  }
492
                }] : []),
509
                              },
510
                          },
511
                      ]
512
                    : []),
493
                {
513
                {
494
                    data: "me.callnumber",
514
                    data: "me.callnumber",
495
                    className: "itemcallnumber",
515
                    className: "itemcallnumber",
Lines 497-504 var columns = [ Link Here
497
                    orderable: true,
517
                    orderable: true,
498
                    render: function (data, type, row, meta) {
518
                    render: function (data, type, row, meta) {
499
                        return escape_str(row.callnumber);
519
                        return escape_str(row.callnumber);
500
                    }
520
                    },
501
502
                },
521
                },
503
                {
522
                {
504
                    data: "me.serial_issue_number",
523
                    data: "me.serial_issue_number",
Lines 509-532 var columns = [ Link Here
509
                        let nodes = "";
528
                        let nodes = "";
510
                        // FIXME Previously we displayed the column if at least one item of the biblio had an enumchron/serial_issue_number. Now it's only if one item of the ones displayed on the current page, how is that bad? How can it be fixed in an elegant way? Should we display the column only if biblio.serial?
529
                        // FIXME Previously we displayed the column if at least one item of the biblio had an enumchron/serial_issue_number. Now it's only if one item of the ones displayed on the current page, how is that bad? How can it be fixed in an elegant way? Should we display the column only if biblio.serial?
511
                        let serial = row.serial_item ? row.serial_item.serial : null;
530
                        let serial = row.serial_item ? row.serial_item.serial : null;
512
                        if ( row.serial_issue_number && serial && serial.serialseq ) {
531
                        if (row.serial_issue_number && serial && serial.serialseq) {
513
                            nodes += '<span class="enum">%s</span>'.format(escape_str(row.serial_issue_number));
532
                            nodes += '<span class="enum">%s</span>'.format(escape_str(row.serial_issue_number));
514
                            if ( serial.serialseq && row.serial_issue_number != serial.serialseq ) {
533
                            if (serial.serialseq && row.serial_issue_number != serial.serialseq) {
515
                                nodes += ' <span class="sep"> -- </span>'
534
                                nodes += ' <span class="sep"> -- </span>';
516
                                nodes += ' <span class="serialseq">%s</span>'.format(escape_str(serial.serialseq));
535
                                nodes += ' <span class="serialseq">%s</span>'.format(escape_str(serial.serialseq));
517
                            }
536
                            }
518
                        } else if ( row.serial_issue_number ) {
537
                        } else if (row.serial_issue_number) {
519
                            nodes += ' <span class="enum">%s</span>'.format(escape_str(row.serial_issue_number));
538
                            nodes += ' <span class="enum">%s</span>'.format(escape_str(row.serial_issue_number));
520
                        } else if ( serial && serial.serialseq ) {
539
                        } else if (serial && serial.serialseq) {
521
                            nodes += '<span class="serialseq">%s</span>'.format(escape_str(serial.serialseq));
540
                            nodes += '<span class="serialseq">%s</span>'.format(escape_str(serial.serialseq));
522
                        }
541
                        }
523
                        if (prefs.DisplayPublishedDate){
542
                        if (prefs.DisplayPublishedDate) {
524
                            if ( serial && serial.publisheddate ) {
543
                            if (serial && serial.publisheddate) {
525
                                nodes += ' <span class="pubdate">(%s)</span>'.format($date(serial.publisheddate));
544
                                nodes += ' <span class="pubdate">(%s)</span>'.format($date(serial.publisheddate));
526
                            }
545
                            }
527
                        }
546
                        }
528
                        return nodes;
547
                        return nodes;
529
                    }
548
                    },
530
                },
549
                },
531
                {
550
                {
532
                    data: "",
551
                    data: "",
Lines 536-602 var columns = [ Link Here
536
                    orderable: false,
555
                    orderable: false,
537
                    render: function (data, type, row, meta) {
556
                    render: function (data, type, row, meta) {
538
                        let nodes = "";
557
                        let nodes = "";
539
                        row._status.forEach( status => {
558
                        row._status.forEach(status => {
540
                            if ( status == 'checked_out' || status == 'local_use') {
559
                            if (status == "checked_out" || status == "local_use") {
541
                                nodes += '<span>';
560
                                nodes += "<span>";
542
561
543
                                // Hacky for patron_to_html in case we simply want to display the patron's library name
562
                                // Hacky for patron_to_html in case we simply want to display the patron's library name
544
                                row.checkout.patron.library = { name: libraries_names.get(row.checkout.patron.library_id) };
563
                                row.checkout.patron.library = { name: libraries_names.get(row.checkout.patron.library_id) };
545
                                let patron_to_html = $patron_to_html(row.checkout.patron, { url: true, display_cardnumber: true, hide_patron_name });
564
                                let patron_to_html = $patron_to_html(row.checkout.patron, { url: true, display_cardnumber: true, hide_patron_name });
546
565
547
                                if ( status == 'local_use' ) {
566
                                if (status == "local_use") {
548
                                    nodes += _("Currently in local use by %s").format(patron_to_html);
567
                                    nodes += _("Currently in local use by %s").format(patron_to_html);
549
                                } else {
568
                                } else {
550
                                    nodes += '<span class="datedue">';
569
                                    nodes += '<span class="datedue">';
551
                                    nodes += _("Checked out to %s").format(patron_to_html);
570
                                    nodes += _("Checked out to %s").format(patron_to_html);
552
                                }
571
                                }
553
                                nodes += ': ';
572
                                nodes += ": ";
554
                                nodes += _("due %s").format($date(row.checkout.due_date, { as_due_date: true }));
573
                                nodes += _("due %s").format($date(row.checkout.due_date, { as_due_date: true }));
555
                                nodes += "</span>"
574
                                nodes += "</span>";
556
557
                            }
575
                            }
558
                            if ( status == 'in_transit' ) {
576
                            if (status == "in_transit") {
559
                                if ( row.transfer.datesent ) {
577
                                if (row.transfer.datesent) {
560
                                    nodes += '<span class="intransit">%s</span>'.format(_("In transit from %s to %s since %s").format(escape_str(row.transfer._strings.from_library.str), escape_str(row.transfer._strings.to_library.str), $date(row.transfer.datesent)));
578
                                    nodes += '<span class="intransit">%s</span>'.format(
579
                                        _("In transit from %s to %s since %s").format(escape_str(row.transfer._strings.from_library.str), escape_str(row.transfer._strings.to_library.str), $date(row.transfer.datesent))
580
                                    );
561
                                } else {
581
                                } else {
562
                                    nodes += '<span class="transitrequested">%s</span>'.format(_("Transit pending from %s to %s since %s").format(escape_str(row.transfer._strings.from_library.str), escape_str(row.transfer._strings.to_library.str), $date(row.transfer.daterequested)));
582
                                    nodes += '<span class="transitrequested">%s</span>'.format(
583
                                        _("Transit pending from %s to %s since %s").format(escape_str(row.transfer._strings.from_library.str), escape_str(row.transfer._strings.to_library.str), $date(row.transfer.daterequested))
584
                                    );
563
                                }
585
                                }
564
                            }
586
                            }
565
587
566
                            if ( status == 'lost' ) {
588
                            if (status == "lost") {
567
                                let lost_lib = av_lost.get(row.lost_status.toString()) || _("Unavailable (lost or missing");
589
                                let lost_lib = av_lost.get(row.lost_status.toString()) || _("Unavailable (lost or missing");
568
                                nodes += '<span class="lost">%s</span>'.format(escape_str(lost_lib));
590
                                nodes += '<span class="lost">%s</span>'.format(escape_str(lost_lib));
569
591
570
                                const hasReturnClaims = row.return_claims && row.return_claims.filter(rc => !rc.resolution).length > 0 ? true : false
592
                                const hasReturnClaims = row.return_claims && row.return_claims.filter(rc => !rc.resolution).length > 0 ? true : false;
571
                                if(hasReturnClaims) {
593
                                if (hasReturnClaims) {
572
                                    nodes += '<span class="holding_status claimed_returned">' + _("(Claimed returned)") + '</span>';
594
                                    nodes += '<span class="holding_status claimed_returned">' + _("(Claimed returned)") + "</span>";
573
                                }
595
                                }
574
                            }
596
                            }
575
597
576
                            if ( status == 'withdrawn' ) {
598
                            if (status == "withdrawn") {
577
                                let withdrawn_lib = av_withdrawn.get(row.withdrawn.toString()) || _("Withdrawn");
599
                                let withdrawn_lib = av_withdrawn.get(row.withdrawn.toString()) || _("Withdrawn");
578
                                nodes += '<span class="wdn">%s</span>'.format(escape_str(withdrawn_lib));
600
                                nodes += '<span class="wdn">%s</span>'.format(escape_str(withdrawn_lib));
579
                            }
601
                            }
580
602
581
                            if ( status == 'damaged' ) {
603
                            if (status == "damaged") {
582
                                let damaged_lib = av_damaged.get(row.damaged_status.toString()) || _("Damaged");
604
                                let damaged_lib = av_damaged.get(row.damaged_status.toString()) || _("Damaged");
583
                                nodes += '<span class="dmg">%s</span>'.format(escape_str(damaged_lib));
605
                                nodes += '<span class="dmg">%s</span>'.format(escape_str(damaged_lib));
584
                            }
606
                            }
585
607
586
                            if ( status == 'not_for_loan' ) {
608
                            if (status == "not_for_loan") {
587
                                let not_for_loan_lib = av_not_for_loan.get(row.not_for_loan_status.toString());
609
                                let not_for_loan_lib = av_not_for_loan.get(row.not_for_loan_status.toString());
588
                                nodes += '<span class="notforloan">%s'.format(_("Not for loan")) + ( not_for_loan_lib ? '<span class="reason"> (%s)</span>'.format(escape_str(not_for_loan_lib)) : '' ) + '</span>';
610
                                nodes += '<span class="notforloan">%s'.format(_("Not for loan")) + (not_for_loan_lib ? '<span class="reason"> (%s)</span>'.format(escape_str(not_for_loan_lib)) : "") + "</span>";
589
                            }
611
                            }
590
612
591
                            if ( status == 'on_hold') {
613
                            if (status == "on_hold") {
592
                                if ( row.first_hold.waiting_date ) {
614
                                if (row.first_hold.waiting_date) {
593
                                    if ( row.first_hold.desk ) {
615
                                    if (row.first_hold.desk) {
594
                                        nodes += '<span class="waitingat">%s</span>'.format(_("Waiting at %s, %s since %s.").format(row.first_hold._strings.pickup_library_id.str, row.first_hold.desk.name, $date(row.first_hold.waiting_date)));
616
                                        nodes += '<span class="waitingat">%s</span>'.format(
617
                                            _("Waiting at %s, %s since %s.").format(row.first_hold._strings.pickup_library_id.str, row.first_hold.desk.name, $date(row.first_hold.waiting_date))
618
                                        );
595
                                    } else {
619
                                    } else {
596
                                        nodes += '<span class="waitingat">%s</span>'.format(_("Waiting at %s since %s.").format(row.first_hold._strings.pickup_library_id.str, $date(row.first_hold.waiting_date)));
620
                                        nodes += '<span class="waitingat">%s</span>'.format(_("Waiting at %s since %s.").format(row.first_hold._strings.pickup_library_id.str, $date(row.first_hold.waiting_date)));
597
                                    }
621
                                    }
598
                                    if (prefs.canreservefromotherbranches){
622
                                    if (prefs.canreservefromotherbranches) {
599
                                        if ( row.first_hold.waiting_date || row.first_hold.priority == 1 ) {
623
                                        if (row.first_hold.waiting_date || row.first_hold.priority == 1) {
600
                                            // Hacky for patron_to_html in case we simply want to display the patron's library name
624
                                            // Hacky for patron_to_html in case we simply want to display the patron's library name
601
                                            row.first_hold.patron.library = { name: libraries_names.get(row.first_hold.patron.library_id) };
625
                                            row.first_hold.patron.library = { name: libraries_names.get(row.first_hold.patron.library_id) };
602
626
Lines 609-640 var columns = [ Link Here
609
                                }
633
                                }
610
                            }
634
                            }
611
635
612
                        if (prefs.UseRecalls){
636
                            if (prefs.UseRecalls) {
613
                            if ( row.recall && ( row.item_id === row.recall.item_id ) ) {
637
                                if (row.recall && row.item_id === row.recall.item_id) {
614
                                if ( row.recall.waiting_date ) {
638
                                    if (row.recall.waiting_date) {
615
                                    nodes += '<span class="holding_status recallwaiting">%s</span>'.format(_("Waiting recall at %s since %s").format(escape_str(row.recall._strings.pickup_library_id.str), $date(row.recall.waiting_date)));
639
                                        nodes += '<span class="holding_status recallwaiting">%s</span>'.format(
616
                                } else {
640
                                            _("Waiting recall at %s since %s").format(escape_str(row.recall._strings.pickup_library_id.str), $date(row.recall.waiting_date))
617
                                    // Hacky for patron_to_html in case we simply want to display the patron's library name
641
                                        );
618
                                    row.recall.patron.library = { name: libraries_names.get(row.recall.patron.library_id) };
642
                                    } else {
643
                                        // Hacky for patron_to_html in case we simply want to display the patron's library name
644
                                        row.recall.patron.library = { name: libraries_names.get(row.recall.patron.library_id) };
619
645
620
                                    let patron_to_html = $patron_to_html(row.recall.patron, {url: true, display_cardnumber: true, hide_patron_name });
646
                                        let patron_to_html = $patron_to_html(row.recall.patron, { url: true, display_cardnumber: true, hide_patron_name });
621
                                    nodes += '<span class="holding_status recalledby">%s</span>'.format(_("Recalled by %s on %s").format(patron_to_html, $date(row.recall.created_date)))
647
                                        nodes += '<span class="holding_status recalledby">%s</span>'.format(_("Recalled by %s on %s").format(patron_to_html, $date(row.recall.created_date)));
648
                                    }
622
                                }
649
                                }
623
                            }
650
                            }
624
                        }
651
                            if (status == "available") {
625
                            if ( status == 'available' ) {
652
                                nodes += " <span>%s</span>".format(_("Available"));
626
                                nodes += ' <span>%s</span>'.format(_("Available"))
627
                            }
653
                            }
628
654
629
                            if ( status == 'restricted') {
655
                            if (status == "restricted") {
630
                                nodes += '<span class="restricted">(%s)</span>'.format(escape_str(av_restricted.get(row.restricted_status.toString())));
656
                                nodes += '<span class="restricted">(%s)</span>'.format(escape_str(av_restricted.get(row.restricted_status.toString())));
631
                            }
657
                            }
632
                            if ( status == 'in_bundle') {
658
                            if (status == "in_bundle") {
633
                                nodes += '<span class="bundled">%s</span>'.format(_("In bundle: %s").format($biblio_to_html(row.bundle_host.biblio, { link: true })));
659
                                nodes += '<span class="bundled">%s</span>'.format(_("In bundle: %s").format($biblio_to_html(row.bundle_host.biblio, { link: true })));
634
                            }
660
                            }
635
                        });
661
                        });
636
                        return nodes;
662
                        return nodes;
637
                    }
663
                    },
638
                },
664
                },
639
                {
665
                {
640
                    data: "me.last_seen_date",
666
                    data: "me.last_seen_date",
Lines 644-650 var columns = [ Link Here
644
                    orderable: true,
670
                    orderable: true,
645
                    render: function (data, type, row, meta) {
671
                    render: function (data, type, row, meta) {
646
                        return $datetime(row.last_seen_date);
672
                        return $datetime(row.last_seen_date);
647
                    }
673
                    },
648
                },
674
                },
649
                {
675
                {
650
                    data: "me.checkouts_count",
676
                    data: "me.checkouts_count",
Lines 653-659 var columns = [ Link Here
653
                    orderable: true,
679
                    orderable: true,
654
                    render: function (data, type, row, meta) {
680
                    render: function (data, type, row, meta) {
655
                        return row.checkouts_count || 0;
681
                        return row.checkouts_count || 0;
656
                    }
682
                    },
657
                },
683
                },
658
                {
684
                {
659
                    data: "me.renewals_count",
685
                    data: "me.renewals_count",
Lines 662-668 var columns = [ Link Here
662
                    orderable: true,
688
                    orderable: true,
663
                    render: function (data, type, row, meta) {
689
                    render: function (data, type, row, meta) {
664
                        return row.renewals_count || 0;
690
                        return row.renewals_count || 0;
665
                    }
691
                    },
666
                },
692
                },
667
                {
693
                {
668
                    data: "me.localuse",
694
                    data: "me.localuse",
Lines 671-677 var columns = [ Link Here
671
                    orderable: true,
697
                    orderable: true,
672
                    render: function (data, type, row, meta) {
698
                    render: function (data, type, row, meta) {
673
                        return row.localuse || 0;
699
                        return row.localuse || 0;
674
                    }
700
                    },
675
                },
701
                },
676
                {
702
                {
677
                    data: "me.acquisition_date",
703
                    data: "me.acquisition_date",
Lines 681-687 var columns = [ Link Here
681
                    orderable: true,
707
                    orderable: true,
682
                    render: function (data, type, row, meta) {
708
                    render: function (data, type, row, meta) {
683
                        return $date(row.acquisition_date);
709
                        return $date(row.acquisition_date);
684
                    }
710
                    },
685
                },
711
                },
686
                {
712
                {
687
                    data: "me.last_checkout_date",
713
                    data: "me.last_checkout_date",
Lines 691-697 var columns = [ Link Here
691
                    orderable: true,
717
                    orderable: true,
692
                    render: function (data, type, row, meta) {
718
                    render: function (data, type, row, meta) {
693
                        return $date(row.last_checkout_date);
719
                        return $date(row.last_checkout_date);
694
                    }
720
                    },
695
                },
721
                },
696
                {
722
                {
697
                    data: "me.acquisition_source",
723
                    data: "me.acquisition_source",
Lines 700-706 var columns = [ Link Here
700
                    orderable: true,
726
                    orderable: true,
701
                    render: function (data, type, row, meta) {
727
                    render: function (data, type, row, meta) {
702
                        return escape_str(row._strings.acquisition_source ? row._strings.acquisition_source.str : row.acquisition_source);
728
                        return escape_str(row._strings.acquisition_source ? row._strings.acquisition_source.str : row.acquisition_source);
703
                    }
729
                    },
704
                },
730
                },
705
                {
731
                {
706
                    data: "me.external_id",
732
                    data: "me.external_id",
Lines 708-718 var columns = [ Link Here
708
                    searchable: true,
734
                    searchable: true,
709
                    orderable: true,
735
                    orderable: true,
710
                    render: function (data, type, row, meta) {
736
                    render: function (data, type, row, meta) {
711
                        if ( row.external_id != null ) {
737
                        if (row.external_id != null) {
712
                            return '<a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=%s&itemnumber=%s#item%s">%s</a>'.format(row.biblio_id, row.item_id, row.item_id, row.external_id);
738
                            return '<a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=%s&itemnumber=%s#item%s">%s</a>'.format(row.biblio_id, row.item_id, row.item_id, row.external_id);
713
                        }
739
                        }
714
                        return '';
740
                        return "";
715
                    }
741
                    },
716
                },
742
                },
717
                {
743
                {
718
                    data: "me.uri",
744
                    data: "me.uri",
Lines 720-739 var columns = [ Link Here
720
                    searchable: true,
746
                    searchable: true,
721
                    orderable: true,
747
                    orderable: true,
722
                    render: function (data, type, row, meta) {
748
                    render: function (data, type, row, meta) {
723
                        if ( !row.uri ) return "";
749
                        if (!row.uri) return "";
724
750
725
                        let nodes = '';
751
                        let nodes = "";
726
                        if ( row.uri.split(' \| ').length > 1 ) {
752
                        if (row.uri.split(" \| ").length > 1) {
727
                            row.uri.split(' \| ').forEach((uri, i) => {
753
                            row.uri.split(" \| ").forEach((uri, i) => {
728
                                let node = safe_link(uri,uri);
754
                                let node = safe_link(uri, uri);
729
                                nodes += node.outerHTML + "<br>";
755
                                nodes += node.outerHTML + "<br>";
730
                            });
756
                            });
731
                        } else {
757
                        } else {
732
                            let node = safe_link(row.uri,url_link_text);
758
                            let node = safe_link(row.uri, url_link_text);
733
                            nodes += node.outerHTML;
759
                            nodes += node.outerHTML;
734
                        }
760
                        }
735
                        return nodes;
761
                        return nodes;
736
                    }
762
                    },
737
                },
763
                },
738
                {
764
                {
739
                    data: "me.copy_number",
765
                    data: "me.copy_number",
Lines 742-748 var columns = [ Link Here
742
                    orderable: true,
768
                    orderable: true,
743
                    render: function (data, type, row, meta) {
769
                    render: function (data, type, row, meta) {
744
                        return escape_str(row._strings.copy_number ? row._strings.copy_number.str : row.copy_number);
770
                        return escape_str(row._strings.copy_number ? row._strings.copy_number.str : row.copy_number);
745
                    }
771
                    },
746
                },
772
                },
747
                {
773
                {
748
                    data: "me.inventory_number",
774
                    data: "me.inventory_number",
Lines 751-757 var columns = [ Link Here
751
                    orderable: true,
777
                    orderable: true,
752
                    render: function (data, type, row, meta) {
778
                    render: function (data, type, row, meta) {
753
                        return escape_str(row.inventory_number);
779
                        return escape_str(row.inventory_number);
754
                    }
780
                    },
755
                },
781
                },
756
                {
782
                {
757
                    data: "me.materials_notes",
783
                    data: "me.materials_notes",
Lines 760-766 var columns = [ Link Here
760
                    orderable: true,
786
                    orderable: true,
761
                    render: function (data, type, row, meta) {
787
                    render: function (data, type, row, meta) {
762
                        return escape_str(row.materials_notes);
788
                        return escape_str(row.materials_notes);
763
                    }
789
                    },
764
                },
790
                },
765
                {
791
                {
766
                    data: "me.public_notes",
792
                    data: "me.public_notes",
Lines 768-775 var columns = [ Link Here
768
                    searchable: true,
794
                    searchable: true,
769
                    orderable: true,
795
                    orderable: true,
770
                    render: function (data, type, row, meta) {
796
                    render: function (data, type, row, meta) {
771
                        return row.public_notes ? escape_str(row.public_notes).replaceAll('\n', '<br />') : '';
797
                        return row.public_notes ? escape_str(row.public_notes).replaceAll("\n", "<br />") : "";
772
                    }
798
                    },
773
                },
799
                },
774
                {
800
                {
775
                    data: "me.internal_notes",
801
                    data: "me.internal_notes",
Lines 778-958 var columns = [ Link Here
778
                    orderable: true,
804
                    orderable: true,
779
                    render: function (data, type, row, meta) {
805
                    render: function (data, type, row, meta) {
780
                        return escape_str(row.internal_notes);
806
                        return escape_str(row.internal_notes);
781
                    }
807
                    },
782
                },
783
                ...(prefs.EasyAnalyticalRecords?
784
                [{
785
                    data: "biblio.title",
786
                    searchable: false,
787
                    orderable: true,
788
                    render: function (data, type, row, meta) {
789
                        if ( row.biblio_id == biblionumber ) return "";
790
                        return '<a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=%s">%s</a>'.format(row.biblio_id, row.biblio.title);
791
                    }
792
                }]:[]),
793
                ...(analyze ?
794
                [{
795
                    data: "analytics_count",
796
                    searchable: false,
797
                    orderable: false,
798
                    render: function (data, type, row, meta) {
799
                        if (row.analytics_count == 0) return ""
800
                        return '<a href="/cgi-bin/koha/catalogue/search.pl?idx=hi&amp;q=%s">%s</a>'.format(row.item_id, _("%s analytics").format(row.analytics_count));
801
                    }
802
                },
808
                },
809
                ...(prefs.EasyAnalyticalRecords
810
                    ? [
811
                          {
812
                              data: "biblio.title",
813
                              searchable: false,
814
                              orderable: true,
815
                              render: function (data, type, row, meta) {
816
                                  if (row.biblio_id == biblionumber) return "";
817
                                  return '<a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=%s">%s</a>'.format(row.biblio_id, row.biblio.title);
818
                              },
819
                          },
820
                      ]
821
                    : []),
822
                ...(analyze
823
                    ? [
824
                          {
825
                              data: "analytics_count",
826
                              searchable: false,
827
                              orderable: false,
828
                              render: function (data, type, row, meta) {
829
                                  if (row.analytics_count == 0) return "";
830
                                  return '<a href="/cgi-bin/koha/catalogue/search.pl?idx=hi&amp;q=%s">%s</a>'.format(row.item_id, _("%s analytics").format(row.analytics_count));
831
                              },
832
                          },
833
                          {
834
                              data: "analytics_count", // create analytics link
835
                              searchable: false,
836
                              orderable: false,
837
                              render: function (data, type, row, meta) {
838
                                  return '<a href="/cgi-bin/koha/cataloguing/addbiblio.pl?hostbiblionumber=%s&amp;hostitemnumber=%s">%s</a>'.format(row.biblio_id, row.item_id, _("Create analytics"));
839
                              },
840
                          },
841
                      ]
842
                    : []),
843
                ...(prefs.UseCourseReserves
844
                    ? [
845
                          {
846
                              data: "course_item.course_reserves.course.course_name",
847
                              searchable: true,
848
                              orderable: true,
849
                              render: function (data, type, row, meta) {
850
                                  let nodes = "";
851
                                  if (!row.course_item) return nodes;
852
                                  row.course_item.course_reserves.forEach((cr, i) => {
853
                                      let c = cr.course;
854
                                      if (c.enabled != "yes") return;
855
                                      nodes += "<p>";
856
                                      nodes += '<a href="/cgi-bin/koha/course_reserves/course-details.pl?course_id=%s">'.format(c.course_id);
857
                                      nodes += escape_str(c.course_name);
858
                                      if (c.section) {
859
                                          nodes += " " + escape_str(c.section);
860
                                      }
861
                                      if (c.term) {
862
                                          nodes += " " + av_courses_term.get(c.term.toString());
863
                                      }
864
                                      nodes += "</p>";
865
                                  });
866
                                  return nodes;
867
                              },
868
                          },
869
                      ]
870
                    : []),
871
                ...(prefs.SpineLabelShowPrintOnBibDetails
872
                    ? [
873
                          {
874
                              data: "",
875
                              searchable: false,
876
                              orderable: false,
877
                              render: function (data, type, row, meta) {
878
                                  return '<a class="btn btn-default btn-xs print-label" href="/cgi-bin/koha/labels/spinelabel-print.pl?barcode=%s"><i class="fa fa-print"></i> Print label</a>'.format(escape_str(row.external_id));
879
                              },
880
                          },
881
                      ]
882
                    : []),
883
                ...(permissions.CAN_user_editcatalogue_edit_items
884
                    ? [
885
                          {
886
                              data: function (row, type, val, meta) {
887
                                  let nodes = "";
888
                                  if (can_edit_items_from.includes(row.home_library_id) || !can_edit_items_from.length) {
889
                                      if (prefs.LocalCoverImages || prefs.OPACLocalCoverImages) {
890
                                          nodes += '<div class="btn-group dropup">';
891
                                          nodes +=
892
                                              ' <a class="btn btn-default btn-xs" href="/cgi-bin/koha/cataloguing/additem.pl?op=edititem&biblionumber=%s&itemnumber=%s#edititem"><i class="fa-solid fa-pencil"></i> %s</a><a class="btn btn-default btn-xs dropdown-toggle" data-bs-toggle="dropdown"><span class="caret"></span></a>'.format(
893
                                                  row.biblio_id,
894
                                                  row.item_id,
895
                                                  _("Edit")
896
                                              );
897
                                          nodes += ' <ul class="dropdown-menu">';
898
                                          nodes += '  <li><a class="dropdown-item" href="/cgi-bin/koha/tools/upload-cover-image.pl?itemnumber=%s&amp;filetype=image"><i class="fa fa-upload"></i> %s</a></li>'.format(
899
                                              row.item_id,
900
                                              _("Upload image")
901
                                          );
902
                                          nodes += " </ul>";
903
                                          nodes += "</div>";
904
                                      } else {
905
                                          nodes += '<a class="btn btn-default btn-xs" href="/cgi-bin/koha/cataloguing/additem.pl?op=edititem&biblionumber=%s&itemnumber=%s#edititem"><i class="fa-solid fa-pencil"></i> %s</a>'.format(
906
                                              row.biblio_id,
907
                                              row.item_id,
908
                                              _("Edit")
909
                                          );
910
                                      }
911
                                  }
912
                                  if (bundlesEnabled) {
913
                                      nodes += '<button class="btn btn-default btn-xs details-control"><i class="fa fa-folder"></i> %s</button>'.format(
914
                                          _("Manage bundle (%s|%s)").format(row.bundle_items_not_lost_count, row.bundle_items_lost_count)
915
                                      );
916
                                  }
917
918
                                  return nodes;
919
                              },
920
                              className: "actions",
921
                              searchable: false,
922
                              orderable: false,
923
                          },
924
                      ]
925
                    : []),
926
            ];
927
            var items_table = $("#" + tab_id + "_table").kohaTable(
803
                {
928
                {
804
                    data: "analytics_count", // create analytics link
929
                    ajax: { url: item_table_url },
805
                    searchable: false,
930
                    order: [],
806
                    orderable: false,
931
                    embed,
807
                    render: function (data, type, row, meta) {
932
                    autoWidth: false,
808
                        return '<a href="/cgi-bin/koha/cataloguing/addbiblio.pl?hostbiblionumber=%s&amp;hostitemnumber=%s">%s</a>'.format(row.biblio_id, row.item_id, _("Create analytics"));
933
                    bKohaColumnsUseNames: true,
809
                    }
934
                    columns,
810
                }]:[]),
935
                    initComplete: function (settings, json) {
811
                ...(prefs.UseCourseReserves?
936
                        itemSelectionBuildActionLinks(tab_id);
812
                [{
937
                    },
813
                    data: "course_item.course_reserves.course.course_name",
938
                    drawCallback: function (settings) {
814
                    searchable: true,
939
                        let api = this.api();
815
                    orderable: true,
940
                        $.each($(this).find("tbody tr td:first-child"), function (index, e) {
816
                    render: function (data, type, row, meta) {
941
                            let tr = $(this).parent();
817
                        let nodes = '';
942
                            let row = api.row(tr).data();
818
                        if (!row.course_item) return nodes;
943
                            if (!row) return; // Happen if the table is empty
819
                        row.course_item.course_reserves.forEach((cr, i) => {
944
                            $(this)
820
                            let c = cr.course;
945
                                .find("input[name='itemnumber'][type='checkbox']")
821
                            if ( c.enabled != 'yes' ) return;
946
                                .on("change", function () {
822
                            nodes += '<p>';
947
                                    let itemnumber = parseInt($(this).val());
823
                            nodes += '<a href="/cgi-bin/koha/course_reserves/course-details.pl?course_id=%s">'.format(c.course_id);
948
                                    if ($(this).prop("checked")) {
824
                            nodes += escape_str(c.course_name);
949
                                        items_selection[tab_id].push(itemnumber);
825
                            if ( c.section ) {
950
                                    } else {
826
                                nodes += ' ' + escape_str(c.section);
951
                                        items_selection[tab_id] = items_selection[tab_id].filter(id => id != itemnumber);
827
                            }
952
                                    }
828
                            if ( c.term ) {
953
                                    itemSelectionBuildActionLinks(tab_id);
829
                                nodes += ' ' + av_courses_term.get(c.term.toString());
954
                                });
830
                            }
831
                            nodes += '</p>';
832
                        });
955
                        });
833
                        return nodes;
956
834
                    }
957
                        if (!add_filters && settings._iRecordsDisplay == settings._iRecordsTotal && settings._iDisplayLength >= settings._iRecordsDisplay) {
835
                }]:[]),
958
                            let container = $(this).parent();
836
                ...(prefs.SpineLabelShowPrintOnBibDetails?
959
                            container.find(".dt-info").remove();
837
                [{
960
                            container.find(".table_entries").remove();
838
                    data: "",
961
                            container.find(".dataTables_filter").remove();
839
                    searchable: false,
962
                            container.find(".dt_button_clear_filter").remove();
840
                    orderable: false,
963
                            container.find(".bottom.pager").remove();
841
                    render: function (data, type, row, meta) {
842
                        return '<a class="btn btn-default btn-xs print-label" href="/cgi-bin/koha/labels/spinelabel-print.pl?barcode=%s"><i class="fa fa-print"></i> Print label</a>'.format(escape_str(row.external_id));
843
                    }
844
                }]:[]),
845
                ...(permissions.CAN_user_editcatalogue_edit_items ?
846
                [{
847
                    data: function( row, type, val, meta ) {
848
                        let nodes = '';
849
                        if ( can_edit_items_from.includes(row.home_library_id) || !can_edit_items_from.length ){
850
                            if (prefs.LocalCoverImages || prefs.OPACLocalCoverImages){
851
                                nodes += '<div class="btn-group dropup">';
852
                                nodes += ' <a class="btn btn-default btn-xs" href="/cgi-bin/koha/cataloguing/additem.pl?op=edititem&biblionumber=%s&itemnumber=%s#edititem"><i class="fa-solid fa-pencil"></i> %s</a><a class="btn btn-default btn-xs dropdown-toggle" data-bs-toggle="dropdown"><span class="caret"></span></a>'.format(row.biblio_id, row.item_id, _("Edit"));
853
                                nodes += ' <ul class="dropdown-menu">';
854
                                nodes += '  <li><a class="dropdown-item" href="/cgi-bin/koha/tools/upload-cover-image.pl?itemnumber=%s&amp;filetype=image"><i class="fa fa-upload"></i> %s</a></li>'.format(row.item_id, _("Upload image"));
855
                                nodes += ' </ul>';
856
                                nodes += '</div>';
857
                            } else {
858
                                nodes += '<a class="btn btn-default btn-xs" href="/cgi-bin/koha/cataloguing/additem.pl?op=edititem&biblionumber=%s&itemnumber=%s#edititem"><i class="fa-solid fa-pencil"></i> %s</a>'.format(row.biblio_id, row.item_id, _("Edit"));
859
                            }
860
                        }
861
                        if (bundlesEnabled){
862
                            nodes += '<button class="btn btn-default btn-xs details-control"><i class="fa fa-folder"></i> %s</button>'.format(_("Manage bundle (%s|%s)").format(row.bundle_items_not_lost_count, row.bundle_items_lost_count));
863
                        }
964
                        }
864
965
865
                        return nodes;
966
                        if (prefs.SpineLabelShowPrintOnBibDetails) {
866
                    },
967
                            $(".print-label").on("click", function (e) {
867
                    className: "actions",
968
                                e.preventDefault();
868
                    searchable: false,
969
                                link = $(this).attr("href");
869
                    orderable: false
970
                                openWindow(link, "Print spine label", 400, 400);
870
                }]:[])
871
                ];
872
            var items_table = $("#" + tab_id + '_table').kohaTable({
873
                ajax: { url: item_table_url },
874
                order: [],
875
                embed,
876
                autoWidth: false,
877
                bKohaColumnsUseNames: true,
878
                columns,
879
                initComplete: function( settings, json ){
880
                    itemSelectionBuildActionLinks(tab_id);
881
                },
882
                drawCallback: function(settings){
883
                    let api = this.api();
884
                    $.each(
885
                        $(this).find("tbody tr td:first-child"),
886
                        function (index, e) {
887
                            let tr = $(this).parent()
888
                            let row = api.row(tr).data()
889
                            if (!row) return // Happen if the table is empty
890
                            $(this).find("input[name='itemnumber'][type='checkbox']").on("change", function(){
891
                                let itemnumber = parseInt($(this).val());
892
                                if( $(this).prop("checked") ){
893
                                    items_selection[tab_id].push(itemnumber);
894
                                } else {
895
                                    items_selection[tab_id] = items_selection[tab_id].filter( id => id != itemnumber );
896
                                }
897
                                itemSelectionBuildActionLinks(tab_id);
898
                            });
971
                            });
899
                        }
972
                        }
900
                    );
901
902
                    if (!add_filters && settings._iRecordsDisplay == settings._iRecordsTotal && settings._iDisplayLength >= settings._iRecordsDisplay){
903
                        let container = $(this).parent();
904
                        container.find(".dt-info").remove();
905
                        container.find(".table_entries").remove();
906
                        container.find(".dataTables_filter").remove();
907
                        container.find(".dt_button_clear_filter").remove();
908
                        container.find(".bottom.pager").remove();
909
                    }
910
973
911
                    if (prefs.SpineLabelShowPrintOnBibDetails){
974
                        if (api.data().length) {
912
                         $(".print-label").on("click", function(e){
975
                            update_columns_visibility(api, items_table_settings[tab_id], user_colvis[tab_id]);
913
                            e.preventDefault();
976
                        }
914
                            link = $(this).attr("href");
915
                            openWindow(link,"Print spine label",400,400);
916
                        });
917
                    }
918
919
                    if ( api.data().length ) {
920
                        update_columns_visibility(api, items_table_settings[tab_id], user_colvis[tab_id]);
921
                    }
922
977
923
                    if ( drawcallback ) { drawcallback(this); }
978
                        if (drawcallback) {
979
                            drawcallback(this);
980
                        }
981
                    },
982
                    ...dt_options,
924
                },
983
                },
925
                ...dt_options,
984
                items_table_settings[tab_id],
926
            },
985
                add_filters,
927
            items_table_settings[tab_id],
986
                default_filters,
928
            add_filters,
987
                filters_options
929
            default_filters,
930
            filters_options,
931
            );
988
            );
932
989
933
            table_dt = items_table.DataTable();
990
            table_dt = items_table.DataTable();
934
            table_dt.on("column-visibility.dt", function(e, settings, column, state, recalc ){
991
            table_dt.on("column-visibility.dt", function (e, settings, column, state, recalc) {
935
                if (recalc === false) return;
992
                if (recalc === false) return;
936
993
937
                if ( filters_shown ) {
994
                if (filters_shown) {
938
                    _dt_add_filters(this, table_dt, filters_options);
995
                    _dt_add_filters(this, table_dt, filters_options);
939
                }
996
                }
940
997
941
                user_colvis[tab_id][column] = state;
998
                user_colvis[tab_id][column] = state;
942
943
            });
999
            });
944
            return items_table;
1000
            return items_table;
945
        }
1001
        }
946
        function safe_link(uri,link_text) {
1002
        function safe_link(uri, link_text) {
947
            let node = document.createElement('a');
1003
            let node = document.createElement("a");
948
            let url_str = '#';
1004
            let url_str = "#";
949
            try {
1005
            try {
950
                const safe_url = new URL(uri);
1006
                const safe_url = new URL(uri);
951
                url_str = safe_url.href;
1007
                url_str = safe_url.href;
952
            } catch (e) {
1008
            } catch (e) {
953
                //console.error('Invalid URL:', e);
1009
                //console.error('Invalid URL:', e);
954
            }
1010
            }
955
            node.setAttribute('href',url_str);
1011
            node.setAttribute("href", url_str);
956
            node.textContent = link_text;
1012
            node.textContent = link_text;
957
            return node;
1013
            return node;
958
        }
1014
        }
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt (-547 / +565 lines)
Lines 1294-1453 Link Here
1294
            var table_settings = [% TablesSettings.GetTableSettings( 'catalogue', 'concerns', 'table_concerns', 'json' ) | $raw %];
1294
            var table_settings = [% TablesSettings.GetTableSettings( 'catalogue', 'concerns', 'table_concerns', 'json' ) | $raw %];
1295
            const biblio_id = "[% biblionumber | html %]";
1295
            const biblio_id = "[% biblionumber | html %]";
1296
        </script>
1296
        </script>
1297
1298
        <script>
1297
        <script>
1299
            $(document).ready(function() {
1298
            $(document).ready(function () {
1300
                $("#bibliodetails a:first").tab("show");
1299
                $("#bibliodetails a:first").tab("show");
1301
1300
1302
                let additional_filters = {
1301
                let additional_filters = {
1303
                    resolved_date: function(){
1302
                    resolved_date: function () {
1304
                        if ( $("#hide_resolved_concerns").is(":checked") ) {
1303
                        if ($("#hide_resolved_concerns").is(":checked")) {
1305
                            return { "=": null };
1304
                            return { "=": null };
1306
                        } else {
1305
                        } else {
1307
                            return;
1306
                            return;
1308
                        }
1307
                        }
1309
                    },
1308
                    },
1310
                    source: 'catalog',
1309
                    source: "catalog",
1311
                    biblio_id,
1310
                    biblio_id,
1312
                };
1311
                };
1313
                let external_filter_nodes = {
1312
                let external_filter_nodes = {
1314
                    hide_resolved_concerns: "#hide_resolved_concerns",
1313
                    hide_resolved_concerns: "#hide_resolved_concerns",
1315
                };
1314
                };
1316
1315
1317
                var tickets_url = '/api/v1/tickets';
1316
                var tickets_url = "/api/v1/tickets";
1318
                var tickets = $("#table_concerns").kohaTable({
1317
                var tickets = $("#table_concerns").kohaTable(
1319
                    ajax: {
1318
                    {
1320
                        "url": tickets_url
1319
                        ajax: {
1321
                    },
1320
                            url: tickets_url,
1322
                    embed: [
1323
                        "assignee",
1324
                        "reporter",
1325
                        "resolver",
1326
                        "biblio",
1327
                        "updates+count",
1328
                        "+strings"
1329
                    ],
1330
                    emptyTable: '<div class="alert alert-info">' + _("Congratulations, there are no catalog concerns.") + '</div>',
1331
                    columnDefs: [ {
1332
                        targets: [0,1,2,3],
1333
                        render: function (data, type, row, meta) {
1334
                            if ( type == 'display' ) {
1335
                                if ( data != null ) {
1336
                                    return data.escapeHtml();
1337
                                }
1338
                                else {
1339
                                    return "";
1340
                                }
1341
                            }
1342
                            return data;
1343
                        }
1344
                    } ],
1345
                    columns: [
1346
                        {
1347
                            data: "reported_date:reporter.firstname",
1348
                            render: function(data, type, row, meta) {
1349
                                let reported = '<div class="d-flex justify-content-between align-items-start">';
1350
                                reported += '<span class="reporter">' + $patron_to_html(row.reporter, {
1351
                                    display_cardnumber: false,
1352
                                    url: true
1353
                                }) + '</span>';
1354
                                reported += '<span class="date text-muted">' + $datetime(row.reported_date) + '</span>';
1355
                                reported += '</div>';
1356
                                return reported;
1357
                            },
1358
                            searchable: true,
1359
                            orderable: true
1360
                        },
1321
                        },
1361
                        {
1322
                        embed: ["assignee", "reporter", "resolver", "biblio", "updates+count", "+strings"],
1362
                            data: "title:body",
1323
                        emptyTable: '<div class="alert alert-info">' + _("Congratulations, there are no catalog concerns.") + "</div>",
1363
                            render: function(data, type, row, meta) {
1324
                        columnDefs: [
1364
                                let result = '<div class="d-flex justify-content-between align-items-start">';
1325
                            {
1326
                                targets: [0, 1, 2, 3],
1327
                                render: function (data, type, row, meta) {
1328
                                    if (type == "display") {
1329
                                        if (data != null) {
1330
                                            return data.escapeHtml();
1331
                                        } else {
1332
                                            return "";
1333
                                        }
1334
                                    }
1335
                                    return data;
1336
                                },
1337
                            },
1338
                        ],
1339
                        columns: [
1340
                            {
1341
                                data: "reported_date:reporter.firstname",
1342
                                render: function (data, type, row, meta) {
1343
                                    let reported = '<div class="d-flex justify-content-between align-items-start">';
1344
                                    reported +=
1345
                                        '<span class="reporter">' +
1346
                                        $patron_to_html(row.reporter, {
1347
                                            display_cardnumber: false,
1348
                                            url: true,
1349
                                        }) +
1350
                                        "</span>";
1351
                                    reported += '<span class="date text-muted">' + $datetime(row.reported_date) + "</span>";
1352
                                    reported += "</div>";
1353
                                    return reported;
1354
                                },
1355
                                searchable: true,
1356
                                orderable: true,
1357
                            },
1358
                            {
1359
                                data: "title:body",
1360
                                render: function (data, type, row, meta) {
1361
                                    let result = '<div class="d-flex justify-content-between align-items-start">';
1365
1362
1366
                                // Title link on the left
1363
                                    // Title link on the left
1367
                                result += '<a id="title_' + row.ticket_id + '" role="button" href="#" class="detail-trigger">' + row.title + '</a>';
1364
                                    result += '<a id="title_' + row.ticket_id + '" role="button" href="#" class="detail-trigger">' + row.title + "</a>";
1368
1365
1369
                                // Updates count on the right, if it exists
1366
                                    // Updates count on the right, if it exists
1370
                                if (row.updates_count) {
1367
                                    if (row.updates_count) {
1371
                                    result += '<span><a role="button" href="#" class="detail-trigger"><i class="fa fa-comment" aria-hidden="true"></i> ' + row.updates_count + '</a></span>';
1368
                                        result += '<span><a role="button" href="#" class="detail-trigger"><i class="fa fa-comment" aria-hidden="true"></i> ' + row.updates_count + "</a></span>";
1372
                                }
1369
                                    }
1373
1370
1374
                                // Hidden detail content
1371
                                    // Hidden detail content
1375
                                result += '</div>';
1372
                                    result += "</div>";
1376
                                result += '<div id="detail_' + row.ticket_id + '" style="display:none">' + row.body + '</div>';
1373
                                    result += '<div id="detail_' + row.ticket_id + '" style="display:none">' + row.body + "</div>";
1377
1374
1378
                                return result;
1375
                                    return result;
1376
                                },
1377
                                searchable: true,
1378
                                orderable: true,
1379
                            },
1379
                            },
1380
                            searchable: true,
1380
                            {
1381
                            orderable: true
1381
                                data: "biblio.title",
1382
                        },
1382
                                render: function (data, type, row, meta) {
1383
                        {
1383
                                    return $biblio_to_html(row.biblio, {
1384
                            data: "biblio.title",
1384
                                        link: 1,
1385
                            render: function(data, type, row, meta) {
1385
                                    });
1386
                                return $biblio_to_html(row.biblio, {
1386
                                },
1387
                                    link: 1
1387
                                searchable: true,
1388
                                });
1388
                                orderable: true,
1389
                            },
1389
                            },
1390
                            searchable: true,
1390
                            {
1391
                            orderable: true
1391
                                data: "assignee.firstname:assignee.surname:resolver.firstname:resolver.surname:resolved_date:status",
1392
                        },
1392
                                render: function (data, type, row, meta) {
1393
                        {
1393
                                    let result = "";
1394
                            data: "assignee.firstname:assignee.surname:resolver.firstname:resolver.surname:resolved_date:status",
1394
                                    if (row.resolved_date) {
1395
                            render: function(data, type, row, meta) {
1395
                                        result += "<div>";
1396
                                let result = '';
1396
                                        result +=
1397
                                if (row.resolved_date) {
1397
                                            _("Resolved by") +
1398
                                    result += "<div>";
1398
                                            " <span>" +
1399
                                    result += _("Resolved by") + ' <span>' + $patron_to_html(row.resolver, {
1399
                                            $patron_to_html(row.resolver, {
1400
                                        display_cardnumber: false,
1400
                                                display_cardnumber: false,
1401
                                        url: true
1401
                                                url: true,
1402
                                    }) + '</span>';
1402
                                            }) +
1403
                                    result += "</div>";
1403
                                            "</span>";
1404
                                    if (row.status) {
1404
                                        result += "</div>";
1405
                                        result += '<div>';
1405
                                        if (row.status) {
1406
                                        result += ' ' + _("as") + ' ';
1406
                                            result += "<div>";
1407
                                        result += row._strings.status ? escape_str(row._strings.status.str) : "";
1407
                                            result += " " + _("as") + " ";
1408
                                        result += '</div>';
1408
                                            result += row._strings.status ? escape_str(row._strings.status.str) : "";
1409
                                    }
1409
                                            result += "</div>";
1410
                                    result += '<div>' + $datetime(row.resolved_date) + '</div>';
1410
                                        }
1411
                                } else {
1411
                                        result += "<div>" + $datetime(row.resolved_date) + "</div>";
1412
                                    result += '<div>';
1413
                                    if (row.status) {
1414
                                        result += row._strings.status ? escape_str(row._strings.status.str) : "";
1415
                                    } else {
1412
                                    } else {
1416
                                        result += _("Open");
1413
                                        result += "<div>";
1417
                                    }
1414
                                        if (row.status) {
1418
                                    result += '</div>';
1415
                                            result += row._strings.status ? escape_str(row._strings.status.str) : "";
1419
                                    if (row.assignee) {
1416
                                        } else {
1420
                                        result += '<div>';
1417
                                            result += _("Open");
1421
                                        result += _("Assigned to: ") + ' <span>' + $patron_to_html(row.assignee, {
1418
                                        }
1422
                                            display_cardnumber: false,
1419
                                        result += "</div>";
1423
                                            url: true
1420
                                        if (row.assignee) {
1424
                                        }) + '</span>';
1421
                                            result += "<div>";
1425
                                        result += '</div>';
1422
                                            result +=
1423
                                                _("Assigned to: ") +
1424
                                                " <span>" +
1425
                                                $patron_to_html(row.assignee, {
1426
                                                    display_cardnumber: false,
1427
                                                    url: true,
1428
                                                }) +
1429
                                                "</span>";
1430
                                            result += "</div>";
1431
                                        }
1426
                                    }
1432
                                    }
1427
                                }
1433
                                    return result;
1428
                                return result;
1434
                                },
1435
                                searchable: true,
1436
                                orderable: true,
1429
                            },
1437
                            },
1430
                            searchable: true,
1438
                            {
1431
                            orderable: true
1439
                                data: function (row, type, val, meta) {
1432
                        },
1440
                                    let resolved = row.resolved_date ? true : false;
1433
                        {
1441
                                    let result =
1434
                            data: function(row, type, val, meta) {
1442
                                        '<a class="btn btn-default btn-xs main-trigger" role="button" href="#" data-bs-toggle="modal" data-bs-target="#ticketDetailsModal" data-concern="' +
1435
                                let resolved = ( row.resolved_date ) ? true : false;
1443
                                        encodeURIComponent(row.ticket_id) +
1436
                                let result = '<a class="btn btn-default btn-xs main-trigger" role="button" href="#" data-bs-toggle="modal" data-bs-target="#ticketDetailsModal" data-concern="' + encodeURIComponent(row.ticket_id) + '" data-resolved="' + resolved + '" data-assignee="'+$patron_to_html(row.assignee, { display_cardnumber: false, url: false })+'"><i class="fa-solid fa-eye" aria-hidden="true"></i> ' + _("Details") + '</a>';
1444
                                        '" data-resolved="' +
1437
                                return result;
1445
                                        resolved +
1446
                                        '" data-assignee="' +
1447
                                        $patron_to_html(row.assignee, { display_cardnumber: false, url: false }) +
1448
                                        '"><i class="fa-solid fa-eye" aria-hidden="true"></i> ' +
1449
                                        _("Details") +
1450
                                        "</a>";
1451
                                    return result;
1452
                                },
1453
                                searchable: false,
1454
                                orderable: false,
1438
                            },
1455
                            },
1439
                            searchable: false,
1456
                        ],
1440
                            orderable: false
1457
                    },
1441
                        },
1458
                    table_settings,
1442
                    ]
1459
                    0,
1443
                }, table_settings, 0, additional_filters, undefined, external_filter_nodes);
1460
                    additional_filters,
1461
                    undefined,
1462
                    external_filter_nodes
1463
                );
1444
1464
1445
                $('#hideResolved').on("click", function() {
1465
                $("#hideResolved").on("click", function () {
1446
                    $("#hide_resolved_concerns").prop("checked", true);
1466
                    $("#hide_resolved_concerns").prop("checked", true);
1447
                    tickets.DataTable().draw();
1467
                    tickets.DataTable().draw();
1448
                });
1468
                });
1449
1469
1450
                $('#showAll').on("click", function() {
1470
                $("#showAll").on("click", function () {
1451
                    $("#hide_resolved_concerns").prop("checked", false);
1471
                    $("#hide_resolved_concerns").prop("checked", false);
1452
                    tickets.DataTable().draw();
1472
                    tickets.DataTable().draw();
1453
                });
1473
                });
Lines 1741-1747 Link Here
1741
    [% IF Koha.Preference('EnableBooking') %]
1761
    [% IF Koha.Preference('EnableBooking') %]
1742
        [% Asset.js("js/modals/place_booking.js") | $raw %]
1762
        [% Asset.js("js/modals/place_booking.js") | $raw %]
1743
    [% END %]
1763
    [% END %]
1744
1745
    <script>
1764
    <script>
1746
        var browser;
1765
        var browser;
1747
        browser = KOHA.browser("[% searchid | html %]", parseInt(biblionumber, 10));
1766
        browser = KOHA.browser("[% searchid | html %]", parseInt(biblionumber, 10));
Lines 1761-1925 Link Here
1761
            CAN_user_editcatalogue_manage_item_groups: [% CAN_user_editcatalogue_manage_item_groups ? 1 : 0 | html %],
1780
            CAN_user_editcatalogue_manage_item_groups: [% CAN_user_editcatalogue_manage_item_groups ? 1 : 0 | html %],
1762
        });
1781
        });
1763
    </script>
1782
    </script>
1764
1765
    <script>
1783
    <script>
1766
        let items_tab_ids = [ 'holdings', 'otherholdings' ];
1784
        let items_tab_ids = ["holdings", "otherholdings"];
1767
        items_tab_ids.forEach( function( tab_id, index ) {
1785
        items_tab_ids.forEach(function (tab_id, index) {
1768
1769
            // Early return if the tab is not shown (ie. no table)
1786
            // Early return if the tab is not shown (ie. no table)
1770
            if (!$("#%s_table".format(tab_id)).length) return;
1787
            if (!$("#%s_table".format(tab_id)).length) return;
1771
            if (prefs.AlwaysShowHoldingsTableFilters){
1788
            if (prefs.AlwaysShowHoldingsTableFilters) {
1772
                build_items_table(tab_id, true, {}, build_items_table_drawncallback);
1789
                build_items_table(tab_id, true, {}, build_items_table_drawncallback);
1773
            } else {
1790
            } else {
1774
                build_items_table(tab_id, false, {}, build_items_table_drawncallback);
1791
                build_items_table(tab_id, false, {}, build_items_table_drawncallback);
1775
            }
1792
            }
1776
1793
1777
            if (prefs.bundlesEnabled){
1794
            if (prefs.bundlesEnabled) {
1778
                // Add event listener for opening and closing bundle details
1795
                // Add event listener for opening and closing bundle details
1779
                $('#' + tab_id + '_table tbody').on('click', 'button.details-control', function () {
1796
                $("#" + tab_id + "_table tbody").on("click", "button.details-control", function () {
1780
                    var button = $(this);
1797
                    var button = $(this);
1781
                    var tr = button.closest('tr');
1798
                    var tr = button.closest("tr");
1782
                    var dTable = button.closest('table').DataTable({ 'retrieve': true });
1799
                    var dTable = button.closest("table").DataTable({ retrieve: true });
1783
1800
1784
                    let row = dTable.row( tr );
1801
                    let row = dTable.row(tr);
1785
                    let data = row.data();
1802
                    let data = row.data();
1786
                    let itemnumber = data.item_id;
1803
                    let itemnumber = data.item_id;
1787
                    let duedate = (data.checkout&&data.checkout.due_date) || null;
1804
                    let duedate = (data.checkout && data.checkout.due_date) || null;
1788
1805
1789
                    if ( row.child.isShown() ) {
1806
                    if (row.child.isShown()) {
1790
                        // This row is already open - close it
1807
                        // This row is already open - close it
1791
                        row.child.hide();
1808
                        row.child.hide();
1792
                        tr.removeClass('shown');
1809
                        tr.removeClass("shown");
1793
                        button.removeClass('active');
1810
                        button.removeClass("active");
1794
                    } else {
1811
                    } else {
1795
                        // Open this row
1812
                        // Open this row
1796
                        createChild(row, itemnumber, duedate);
1813
                        createChild(row, itemnumber, duedate);
1797
                        tr.addClass('shown');
1814
                        tr.addClass("shown");
1798
                        button.addClass('active');
1815
                        button.addClass("active");
1799
                    }
1816
                    }
1800
                });
1817
                });
1801
            }
1818
            }
1802
        });
1819
        });
1803
1820
1804
        if (bundlesEnabled){ // Bundle handling
1821
        if (bundlesEnabled) {
1805
            function createChild ( row, itemnumber, duedate ) {
1822
            // Bundle handling
1823
            function createChild(row, itemnumber, duedate) {
1806
                // Toolbar
1824
                // Toolbar
1807
                var bundle_toolbar = $('<div id="toolbar" class="btn-toolbar"></div>');
1825
                var bundle_toolbar = $('<div id="toolbar" class="btn-toolbar"></div>');
1808
                bundle_toolbar.append('<a class="btn btn-default" data-bs-toggle="modal" data-bs-target="#addToBundleModal" data-item="' + itemnumber + '"><i class="fa fa-plus"></i> ' + _("Add to bundle") + '</a>');
1826
                bundle_toolbar.append('<a class="btn btn-default" data-bs-toggle="modal" data-bs-target="#addToBundleModal" data-item="' + itemnumber + '"><i class="fa fa-plus"></i> ' + _("Add to bundle") + "</a>");
1809
                bundle_toolbar.append('<a class="btn btn-default" data-bs-toggle="modal" data-bs-target="#removeFromBundleModal" data-item="' + itemnumber + '"><i class="fa fa-minus"></i> ' + _("Remove from bundle") + '</a>');
1827
                bundle_toolbar.append('<a class="btn btn-default" data-bs-toggle="modal" data-bs-target="#removeFromBundleModal" data-item="' + itemnumber + '"><i class="fa fa-minus"></i> ' + _("Remove from bundle") + "</a>");
1810
1828
1811
            // Toolbar
1829
                // Toolbar
1812
            var bundle_toolbar = $('<div id="toolbar" class="btn-toolbar"></div>');
1830
                var bundle_toolbar = $('<div id="toolbar" class="btn-toolbar"></div>');
1813
            bundle_toolbar.append('<a class="btn btn-default" data-bs-toggle="modal" data-bs-target="#addToBundleModal" data-item="' + itemnumber + '"><i class="fa fa-plus"></i> ' + _("Add to bundle") + '</a>');
1831
                bundle_toolbar.append('<a class="btn btn-default" data-bs-toggle="modal" data-bs-target="#addToBundleModal" data-item="' + itemnumber + '"><i class="fa fa-plus"></i> ' + _("Add to bundle") + "</a>");
1814
            bundle_toolbar.append('<a class="btn btn-default" data-bs-toggle="modal" data-bs-target="#removeFromBundleModal" data-item="' + itemnumber + '"><i class="fa fa-minus"></i> ' + _("Remove from bundle") + '</a>');
1832
                bundle_toolbar.append('<a class="btn btn-default" data-bs-toggle="modal" data-bs-target="#removeFromBundleModal" data-item="' + itemnumber + '"><i class="fa fa-minus"></i> ' + _("Remove from bundle") + "</a>");
1815
1833
1816
                // This is the table we'll convert into a DataTable
1834
                // This is the table we'll convert into a DataTable
1817
                var bundles_table = $('<table class="display tbundle" data-itemnumber="'+itemnumber+'" id="bundle_table_'+itemnumber+'" width="100%"/>');
1835
                var bundles_table = $('<table class="display tbundle" data-itemnumber="' + itemnumber + '" id="bundle_table_' + itemnumber + '" width="100%"/>');
1818
1836
1819
                // Display it the child row
1837
                // Display it the child row
1820
                row.child( bundle_toolbar.add(bundles_table), 'bundle' ).show();
1838
                row.child(bundle_toolbar.add(bundles_table), "bundle").show();
1821
1839
1822
                // Initialise as a DataTable
1840
                // Initialise as a DataTable
1823
                var bundle_table_url = "/api/v1/items/" + itemnumber + "/bundled_items?";
1841
                var bundle_table_url = "/api/v1/items/" + itemnumber + "/bundled_items?";
1824
                var bundle_table = bundles_table.kohaTable({
1842
                var bundle_table = bundles_table.kohaTable(
1825
                    "ajax": {
1843
                    {
1826
                        "url": bundle_table_url
1844
                        ajax: {
1827
                    },
1845
                            url: bundle_table_url,
1828
                    "embed": [
1829
                        "biblio",
1830
                        "return_claim.patron"
1831
                    ],
1832
                    "order": [[ 1, "asc" ]],
1833
                    "columnDefs": [ {
1834
                        "targets": [0,1,2,3],
1835
                        "render": function (data, type, row, meta) {
1836
                            if ( data && type == 'display' ) {
1837
                                return data.escapeHtml();
1838
                            }
1839
                            return data;
1840
                        }
1841
                    } ],
1842
                    "columns": [
1843
                        {
1844
                            "data": "biblio.title:biblio.subtitle:biblio.medium",
1845
                            "title": _("Title"),
1846
                            "searchable": true,
1847
                            "orderable": true,
1848
                            "render": function(data, type, row, meta) {
1849
                                return $biblio_to_html(row.biblio, { link: 1 });
1850
                            }
1851
                        },
1852
                        {
1853
                            "data": "biblio.author",
1854
                            "title": _("Author"),
1855
                            "searchable": true,
1856
                            "orderable": true,
1857
                        },
1858
                        {
1859
                            "data": "copy_number",
1860
                            "title": _("Copy number"),
1861
                            "searchable": true,
1862
                            "orderable": true,
1863
                        },
1864
                        {
1865
                            "data": "callnumber",
1866
                            "title": _("Callnumber"),
1867
                            "searchable": true,
1868
                            "orderable": true,
1869
                        },
1870
                        {
1871
                            "data": "external_id",
1872
                            "title": _("Barcode"),
1873
                            "searchable": true,
1874
                            "orderable": true,
1875
                        },
1846
                        },
1876
                        {
1847
                        embed: ["biblio", "return_claim.patron"],
1877
                            "data": "lost_status:last_seen_date:return_claim.patron",
1848
                        order: [[1, "asc"]],
1878
                            "title": _("Status"),
1849
                        columnDefs: [
1879
                            "searchable": false,
1850
                            {
1880
                            "orderable": false,
1851
                                targets: [0, 1, 2, 3],
1881
                            "render": function(data, type, row, meta) {
1852
                                render: function (data, type, row, meta) {
1882
                                if ( row.lost_status == prefs.BundleLostValue ) {
1853
                                    if (data && type == "display") {
1883
                                    let out = '<span class="lost">' + _("Last seen") + ': ' + $date(row.last_seen_date) + '</span>';
1854
                                        return data.escapeHtml();
1884
                                    if ( row.return_claim ) {
1885
                                        out = out + '<span class="claims_return">' + _("Claims returned by") + ': ' + $patron_to_html( row.return_claim.patron, { display_cardnumber: false, url: true } ) + '</span>';
1886
                                    }
1855
                                    }
1887
                                    return out;
1856
                                    return data;
1888
                                }
1857
                                },
1889
                                else if ( row.lost_status !== 0 ) {
1890
                                    return '<span class="lost">' + _("Lost") + ': ' + row.lost_status + '</span>';
1891
                                }
1892
                                return '<span class="available">' + _("Present") + '</span>';
1893
                            }
1894
                        },
1895
                        {
1896
                            "data": function( row, type, val, meta ) {
1897
                                var result;
1898
                                if (duedate) {
1899
                                    result = '<button class="btn btn-default btn-xs remove disabled" role="button" data-itemnumber="'+row.item_id+'" title="%s"><i class="fa fa-minus" aria-hidden="true"></i> %s</button>\n'.format(_("This bundle is checked out, it cannot be modified"), _("Remove"));
1900
                                } else {
1901
                                    result = '<button class="btn btn-default btn-xs remove" role="button" data-itemnumber="'+row.item_id+'"><i class="fa fa-minus" aria-hidden="true"></i> '+_("Remove")+'</button>\n';
1902
                                }
1903
                                return result;
1904
                            },
1858
                            },
1905
                            "title": _("Actions"),
1859
                        ],
1906
                            "searchable": false,
1860
                        columns: [
1907
                            "orderable": false,
1861
                            {
1908
                            "class": "no-export"
1862
                                data: "biblio.title:biblio.subtitle:biblio.medium",
1909
                        }
1863
                                title: _("Title"),
1910
                    ]
1864
                                searchable: true,
1911
                }, bundle_settings, 1);
1865
                                orderable: true,
1912
                $(".tbundle").on("click", ".remove:not(.disabled)", function(){
1866
                                render: function (data, type, row, meta) {
1913
                    var bundle_table = $(this).closest('table');
1867
                                    return $biblio_to_html(row.biblio, { link: 1 });
1914
                    var host_itemnumber = bundle_table.data('itemnumber');
1868
                                },
1915
                    var component_itemnumber = $(this).data('itemnumber');
1869
                            },
1870
                            {
1871
                                data: "biblio.author",
1872
                                title: _("Author"),
1873
                                searchable: true,
1874
                                orderable: true,
1875
                            },
1876
                            {
1877
                                data: "copy_number",
1878
                                title: _("Copy number"),
1879
                                searchable: true,
1880
                                orderable: true,
1881
                            },
1882
                            {
1883
                                data: "callnumber",
1884
                                title: _("Callnumber"),
1885
                                searchable: true,
1886
                                orderable: true,
1887
                            },
1888
                            {
1889
                                data: "external_id",
1890
                                title: _("Barcode"),
1891
                                searchable: true,
1892
                                orderable: true,
1893
                            },
1894
                            {
1895
                                data: "lost_status:last_seen_date:return_claim.patron",
1896
                                title: _("Status"),
1897
                                searchable: false,
1898
                                orderable: false,
1899
                                render: function (data, type, row, meta) {
1900
                                    if (row.lost_status == prefs.BundleLostValue) {
1901
                                        let out = '<span class="lost">' + _("Last seen") + ": " + $date(row.last_seen_date) + "</span>";
1902
                                        if (row.return_claim) {
1903
                                            out = out + '<span class="claims_return">' + _("Claims returned by") + ": " + $patron_to_html(row.return_claim.patron, { display_cardnumber: false, url: true }) + "</span>";
1904
                                        }
1905
                                        return out;
1906
                                    } else if (row.lost_status !== 0) {
1907
                                        return '<span class="lost">' + _("Lost") + ": " + row.lost_status + "</span>";
1908
                                    }
1909
                                    return '<span class="available">' + _("Present") + "</span>";
1910
                                },
1911
                            },
1912
                            {
1913
                                data: function (row, type, val, meta) {
1914
                                    var result;
1915
                                    if (duedate) {
1916
                                        result =
1917
                                            '<button class="btn btn-default btn-xs remove disabled" role="button" data-itemnumber="' +
1918
                                            row.item_id +
1919
                                            '" title="%s"><i class="fa fa-minus" aria-hidden="true"></i> %s</button>\n'.format(_("This bundle is checked out, it cannot be modified"), _("Remove"));
1920
                                    } else {
1921
                                        result = '<button class="btn btn-default btn-xs remove" role="button" data-itemnumber="' + row.item_id + '"><i class="fa fa-minus" aria-hidden="true"></i> ' + _("Remove") + "</button>\n";
1922
                                    }
1923
                                    return result;
1924
                                },
1925
                                title: _("Actions"),
1926
                                searchable: false,
1927
                                orderable: false,
1928
                                class: "no-export",
1929
                            },
1930
                        ],
1931
                    },
1932
                    bundle_settings,
1933
                    1
1934
                );
1935
                $(".tbundle").on("click", ".remove:not(.disabled)", function () {
1936
                    var bundle_table = $(this).closest("table");
1937
                    var host_itemnumber = bundle_table.data("itemnumber");
1938
                    var component_itemnumber = $(this).data("itemnumber");
1916
                    var unlink_item_url = "/api/v1/items/" + host_itemnumber + "/bundled_items/" + component_itemnumber;
1939
                    var unlink_item_url = "/api/v1/items/" + host_itemnumber + "/bundled_items/" + component_itemnumber;
1917
                    $.ajax({
1940
                    $.ajax({
1918
                        type: "DELETE",
1941
                        type: "DELETE",
1919
                        url: unlink_item_url,
1942
                        url: unlink_item_url,
1920
                        success: function(){
1943
                        success: function () {
1921
                            bundle_table.DataTable({ 'retrieve': true }).draw(false);
1944
                            bundle_table.DataTable({ retrieve: true }).draw(false);
1922
                        }
1945
                        },
1923
                    });
1946
                    });
1924
                });
1947
                });
1925
1948
Lines 1928-2017 Link Here
1928
1951
1929
            var bundle_changed;
1952
            var bundle_changed;
1930
            var bundle_form_active;
1953
            var bundle_form_active;
1931
            $("#addToBundleModal").on("shown.bs.modal", function(e){
1954
            $("#addToBundleModal").on("shown.bs.modal", function (e) {
1932
                var button = $(e.relatedTarget);
1955
                var button = $(e.relatedTarget);
1933
                var item_id = button.data('item');
1956
                var item_id = button.data("item");
1934
                $("#addResult").replaceWith('<div id="addResult"></div>');
1957
                $("#addResult").replaceWith('<div id="addResult"></div>');
1935
                $("#addToBundleForm").attr('action', '/api/v1/items/' + item_id + '/bundled_items');
1958
                $("#addToBundleForm").attr("action", "/api/v1/items/" + item_id + "/bundled_items");
1936
                $("#external_id").focus();
1959
                $("#external_id").focus();
1937
                bundle_changed = 0;
1960
                bundle_changed = 0;
1938
                bundle_form_active = item_id;
1961
                bundle_form_active = item_id;
1939
            });
1962
            });
1940
1963
1941
            function addToBundle (url, data) {
1964
            function addToBundle(url, data) {
1942
                /* Send the data using post with external_id */
1965
                /* Send the data using post with external_id */
1943
                var posting = $.post({
1966
                var posting = $.post({
1944
                    url: url,
1967
                    url: url,
1945
                    data: JSON.stringify(data),
1968
                    data: JSON.stringify(data),
1946
                    contentType: "application/json; charset=utf-8",
1969
                    contentType: "application/json; charset=utf-8",
1947
                    dataType: "json"
1970
                    dataType: "json",
1948
                });
1971
                });
1949
1972
1950
                const barcode = data.external_id;
1973
                const barcode = data.external_id;
1951
                const marc_link = data.marc_link;
1974
                const marc_link = data.marc_link;
1952
1975
1953
                /* Report the results */
1976
                /* Report the results */
1954
                posting.done(function(data) {
1977
                posting.done(function (data) {
1955
                    $('#addResult').replaceWith('<div id="addResult" class="alert alert-success">'+_("Success: Added '%s'").format(barcode)+'</div>');
1978
                    $("#addResult").replaceWith('<div id="addResult" class="alert alert-success">' + _("Success: Added '%s'").format(barcode) + "</div>");
1956
                    $('#external_id').val('').focus();
1979
                    $("#external_id").val("").focus();
1957
                    bundle_changed = 1;
1980
                    bundle_changed = 1;
1958
                });
1981
                });
1959
                posting.fail(function(data) {
1982
                posting.fail(function (data) {
1960
                    if ( data.status === 409 ) {
1983
                    if (data.status === 409) {
1961
                        var response = data.responseJSON;
1984
                        var response = data.responseJSON;
1962
                        if ( response.error_code === 'already_bundled' ) {
1985
                        if (response.error_code === "already_bundled") {
1963
                            $('#addResult').replaceWith('<div id="addResult" class="alert alert-warning">'+_("Warning: Item '%s' already attached").format(barcode)+'</div>');
1986
                            $("#addResult").replaceWith('<div id="addResult" class="alert alert-warning">' + _("Warning: Item '%s' already attached").format(barcode) + "</div>");
1964
                        } else if (response.error_code === 'bundle_checkout_out') {
1987
                        } else if (response.error_code === "bundle_checkout_out") {
1965
                            $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Bundle is currently checked out")+'</div>');
1988
                            $("#addResult").replaceWith('<div id="addResult" class="alert alert-danger">' + _("Failure: Bundle is currently checked out") + "</div>");
1966
                        } else if (response.error_code === 'checked_out') {
1989
                        } else if (response.error_code === "checked_out") {
1967
                            const button = $('<button type="button">')
1990
                            const button = $('<button type="button">')
1968
                                .addClass('btn btn-xs')
1991
                                .addClass("btn btn-xs")
1969
                                .text(_("Check in and add to bundle"))
1992
                                .text(_("Check in and add to bundle"))
1970
                                .on('click', function () {
1993
                                .on("click", function () {
1971
                                    addToBundle(url, { external_id: barcode, force_checkin: true, marc_link: marc_link });
1994
                                    addToBundle(url, { external_id: barcode, force_checkin: true, marc_link: marc_link });
1972
                                });
1995
                                });
1973
                            $('#addResult')
1996
                            $("#addResult").empty().attr("class", "alert alert-warning").append(__x("Warning: Item {barcode} is checked out", { barcode })).append(" ", button);
1974
                                .empty()
1997
                        } else if (response.error_code === "failed_checkin") {
1975
                                .attr('class', 'alert alert-warning')
1998
                            $("#addResult").empty().attr("class", "alert alert-danger").append(__x("Failure: Item {barcode} cannot be checked in", { barcode }));
1976
                                .append(__x('Warning: Item {barcode} is checked out', { barcode }))
1999
                        } else if (response.error_code === "reserved") {
1977
                                .append(' ', button);
1978
                        } else if (response.error_code === 'failed_checkin') {
1979
                            $('#addResult')
1980
                                .empty()
1981
                                .attr('class', 'alert alert-danger')
1982
                                .append(__x('Failure: Item {barcode} cannot be checked in', { barcode }))
1983
                        } else if (response.error_code === 'reserved') {
1984
                            const button = $('<button type="button">')
2000
                            const button = $('<button type="button">')
1985
                                .addClass('btn btn-xs')
2001
                                .addClass("btn btn-xs")
1986
                                .text(_("Ignore holds and add to bundle"))
2002
                                .text(_("Ignore holds and add to bundle"))
1987
                                .on('click', function () {
2003
                                .on("click", function () {
1988
                                    addToBundle(url, { external_id: barcode, ignore_holds: true, marc_link: marc_link });
2004
                                    addToBundle(url, { external_id: barcode, ignore_holds: true, marc_link: marc_link });
1989
                                });
2005
                                });
1990
                            $('#addResult')
2006
                            $("#addResult").empty().attr("class", "alert alert-warning").append(__x("Warning: Item {barcode} is on hold", { barcode })).append(" ", button);
1991
                                .empty()
1992
                                .attr('class', 'alert alert-warning')
1993
                                .append(__x('Warning: Item {barcode} is on hold', { barcode }))
1994
                                .append(' ', button);
1995
                        } else {
2007
                        } else {
1996
                            $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Item '%s' belongs to another bundle").format(barcode)+'</div>');
2008
                            $("#addResult").replaceWith('<div id="addResult" class="alert alert-danger">' + _("Failure: Item '%s' belongs to another bundle").format(barcode) + "</div>");
1997
                        }
2009
                        }
1998
                    } else if ( data.status === 404 ) {
2010
                    } else if (data.status === 404) {
1999
                        $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Item '%s' not found").format(barcode)+'</div>');
2011
                        $("#addResult").replaceWith('<div id="addResult" class="alert alert-danger">' + _("Failure: Item '%s' not found").format(barcode) + "</div>");
2000
                    } else if ( data.status === 400 ) {
2012
                    } else if (data.status === 400) {
2001
                        var response = data.responseJSON;
2013
                        var response = data.responseJSON;
2002
                        if ( response.error_code === "failed_nesting" ) {
2014
                        if (response.error_code === "failed_nesting") {
2003
                            $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Item '%s' is a bundle and bundles cannot be nested").format(barcode)+'</div>');
2015
                            $("#addResult").replaceWith('<div id="addResult" class="alert alert-danger">' + _("Failure: Item '%s' is a bundle and bundles cannot be nested").format(barcode) + "</div>");
2004
                        } else {
2016
                        } else {
2005
                            $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Check the logs for details.")+'</div>');
2017
                            $("#addResult").replaceWith('<div id="addResult" class="alert alert-danger">' + _("Failure: Check the logs for details.") + "</div>");
2006
                        }
2018
                        }
2007
                    } else {
2019
                    } else {
2008
                        $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Check the logs for details.")+'</div>');
2020
                        $("#addResult").replaceWith('<div id="addResult" class="alert alert-danger">' + _("Failure: Check the logs for details.") + "</div>");
2009
                    }
2021
                    }
2010
                    $('#external_id').val('').focus();
2022
                    $("#external_id").val("").focus();
2011
                });
2023
                });
2012
            }
2024
            }
2013
2025
2014
            $("#addToBundleForm").submit(function(event) {
2026
            $("#addToBundleForm").submit(function (event) {
2015
                /* stop form from submitting normally */
2027
                /* stop form from submitting normally */
2016
                event.preventDefault();
2028
                event.preventDefault();
2017
2029
Lines 2021-2109 Link Here
2021
                addToBundle(url, data);
2033
                addToBundle(url, data);
2022
            });
2034
            });
2023
2035
2024
            $("#addToBundleModal").on("hidden.bs.modal", function(e){
2036
            $("#addToBundleModal").on("hidden.bs.modal", function (e) {
2025
                if ( bundle_changed ) {
2037
                if (bundle_changed) {
2026
                    $('#bundle_table_'+bundle_form_active).DataTable({ 'retrieve': true }).ajax.reload();
2038
                    $("#bundle_table_" + bundle_form_active)
2039
                        .DataTable({ retrieve: true })
2040
                        .ajax.reload();
2027
                }
2041
                }
2028
                bundle_form_active = 0;
2042
                bundle_form_active = 0;
2029
                bundle_changed = 0;
2043
                bundle_changed = 0;
2030
            });
2044
            });
2031
2045
2032
            $("#removeFromBundleModal").on("shown.bs.modal", function(e){
2046
            $("#removeFromBundleModal").on("shown.bs.modal", function (e) {
2033
                var button = $(e.relatedTarget);
2047
                var button = $(e.relatedTarget);
2034
                var item_id = button.data('item');
2048
                var item_id = button.data("item");
2035
                $("#removeResult").replaceWith('<div id="removeResult"></div>');
2049
                $("#removeResult").replaceWith('<div id="removeResult"></div>');
2036
                $("#removeFromBundleForm").attr('action', '/api/v1/items/' + item_id + '/bundled_items/');
2050
                $("#removeFromBundleForm").attr("action", "/api/v1/items/" + item_id + "/bundled_items/");
2037
                $("#rm_external_id").focus();
2051
                $("#rm_external_id").focus();
2038
                bundle_changed = 0;
2052
                bundle_changed = 0;
2039
                bundle_form_active = item_id;
2053
                bundle_form_active = item_id;
2040
            });
2054
            });
2041
2055
2042
            $("#removeFromBundleForm").submit(function(event) {
2056
            $("#removeFromBundleForm").submit(function (event) {
2043
2044
                /* stop form from submitting normally */
2057
                /* stop form from submitting normally */
2045
                event.preventDefault();
2058
                event.preventDefault();
2046
2059
2047
                /* get the action attribute from the <form action=""> element */
2060
                /* get the action attribute from the <form action=""> element */
2048
                var $form = $(this),
2061
                var $form = $(this),
2049
                url = $form.attr('action');
2062
                    url = $form.attr("action");
2050
2063
2051
                var barcode = $('#rm_external_id').val();
2064
                var barcode = $("#rm_external_id").val();
2052
2065
2053
                /* Fetch itemnumber using rm_external_id */
2066
                /* Fetch itemnumber using rm_external_id */
2054
                var itemReq = $.get('/api/v1/items', { q: JSON.stringify({
2067
                var itemReq = $.get(
2055
                    external_id: barcode
2068
                    "/api/v1/items",
2056
                }) }, null, "json");
2069
                    {
2070
                        q: JSON.stringify({
2071
                            external_id: barcode,
2072
                        }),
2073
                    },
2074
                    null,
2075
                    "json"
2076
                );
2057
2077
2058
                var itemnumber;
2078
                var itemnumber;
2059
                itemReq.done(function(data) {
2079
                itemReq.done(function (data) {
2060
                    if (data.length === 1) {
2080
                    if (data.length === 1) {
2061
                        itemnumber = data[0].item_id;
2081
                        itemnumber = data[0].item_id;
2062
2082
2063
                        /* Remove link using fetch itemnumber */
2083
                        /* Remove link using fetch itemnumber */
2064
                        var deleteReq = $.ajax( url + itemnumber, {
2084
                        var deleteReq = $.ajax(url + itemnumber, {
2065
                            type : 'DELETE'
2085
                            type: "DELETE",
2066
                        });
2086
                        });
2067
2087
2068
                        /* Report the results */
2088
                        /* Report the results */
2069
                        deleteReq.done(function(data) {
2089
                        deleteReq.done(function (data) {
2070
                            var barcode = $('#rm_external_id').val();
2090
                            var barcode = $("#rm_external_id").val();
2071
                            $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-success">'+_("Success: Removed '%s'").format(barcode)+'</div>');
2091
                            $("#removeResult").replaceWith('<div id="removeResult" class="alert alert-success">' + _("Success: Removed '%s'").format(barcode) + "</div>");
2072
                            $('#rm_external_id').val('').focus();
2092
                            $("#rm_external_id").val("").focus();
2073
                            bundle_changed = 1;
2093
                            bundle_changed = 1;
2074
                        });
2094
                        });
2075
                        deleteReq.fail(function(data) {
2095
                        deleteReq.fail(function (data) {
2076
                            var barcode = $('#rm_external_id').val();
2096
                            var barcode = $("#rm_external_id").val();
2077
                            if ( data.status === 409 ) {
2097
                            if (data.status === 409) {
2078
                                var response = data.responseJSON;
2098
                                var response = data.responseJSON;
2079
                                if (response.error_code === 'bundle_checkout_out') {
2099
                                if (response.error_code === "bundle_checkout_out") {
2080
                                    $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failure: Bundle is currently checked out")+'</div>');
2100
                                    $("#removeResult").replaceWith('<div id="removeResult" class="alert alert-danger">' + _("Failure: Bundle is currently checked out") + "</div>");
2081
                                } else if ( response.key === "PRIMARY" ) {
2101
                                } else if (response.key === "PRIMARY") {
2082
                                    $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-warning">'+_("Warning: Item '%s' already attached").format(barcode)+'</div>');
2102
                                    $("#removeResult").replaceWith('<div id="removeResult" class="alert alert-warning">' + _("Warning: Item '%s' already attached").format(barcode) + "</div>");
2083
                                } else {
2103
                                } else {
2084
                                    $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failure: Item '%s' belongs to another bundle").format(barcode)+'</div>');
2104
                                    $("#removeResult").replaceWith('<div id="removeResult" class="alert alert-danger">' + _("Failure: Item '%s' belongs to another bundle").format(barcode) + "</div>");
2085
                                }
2105
                                }
2086
                            } else if ( data.status === 404 ) {
2106
                            } else if (data.status === 404) {
2087
                                $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Item '%s' not found").format(barcode)+'</div>');
2107
                                $("#addResult").replaceWith('<div id="addResult" class="alert alert-danger">' + _("Failure: Item '%s' not found").format(barcode) + "</div>");
2088
                            } else {
2108
                            } else {
2089
                                $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failure: Check the logs for details")+'</div>');
2109
                                $("#removeResult").replaceWith('<div id="removeResult" class="alert alert-danger">' + _("Failure: Check the logs for details") + "</div>");
2090
                            }
2110
                            }
2091
                            $('#rm_external_id').val('').focus();
2111
                            $("#rm_external_id").val("").focus();
2092
                        });
2112
                        });
2093
                    } else {
2113
                    } else {
2094
                        $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failed: Barcode matched more than one item '%s'").format(barcode)+'</div>');
2114
                        $("#removeResult").replaceWith('<div id="removeResult" class="alert alert-danger">' + _("Failed: Barcode matched more than one item '%s'").format(barcode) + "</div>");
2095
                    }
2115
                    }
2096
                });
2116
                });
2097
                itemReq.fail(function(data) {
2117
                itemReq.fail(function (data) {
2098
                    $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failed: Item not found '%s'").format(barcode)+'</div>');
2118
                    $("#removeResult").replaceWith('<div id="removeResult" class="alert alert-danger">' + _("Failed: Item not found '%s'").format(barcode) + "</div>");
2099
                    $('#rm_external_id').val('').focus();
2119
                    $("#rm_external_id").val("").focus();
2100
2101
                });
2120
                });
2102
            });
2121
            });
2103
2122
2104
            $("#removeFromBundleModal").on("hidden.bs.modal", function(e){
2123
            $("#removeFromBundleModal").on("hidden.bs.modal", function (e) {
2105
                if ( bundle_changed ) {
2124
                if (bundle_changed) {
2106
                    $('#bundle_table_'+bundle_form_active).DataTable({ 'retrieve': true }).ajax.reload();
2125
                    $("#bundle_table_" + bundle_form_active)
2126
                        .DataTable({ retrieve: true })
2127
                        .ajax.reload();
2107
                }
2128
                }
2108
                bundle_form_active = 0;
2129
                bundle_form_active = 0;
2109
                bundle_changed = 0;
2130
                bundle_changed = 0;
Lines 2111-2124 Link Here
2111
            // End bundle handling
2132
            // End bundle handling
2112
        }
2133
        }
2113
    </script>
2134
    </script>
2114
2115
    [% IF Koha.Preference('AcquisitionDetails') %]
2135
    [% IF Koha.Preference('AcquisitionDetails') %]
2116
        <script>
2136
        <script>
2117
            var table_settings = [% TablesSettings.GetTableSettings('catalogue', 'detail', 'acquisitiondetails-table', 'json') | $raw %];
2137
            var table_settings = [% TablesSettings.GetTableSettings('catalogue', 'detail', 'acquisitiondetails-table', 'json') | $raw %];
2118
        </script>
2138
        </script>
2119
2120
        <script>
2139
        <script>
2121
            $(document).ready(function() {
2140
            $(document).ready(function () {
2122
                var acquisitiondetails_table = $("#orders").kohaTable(
2141
                var acquisitiondetails_table = $("#orders").kohaTable(
2123
                    {
2142
                    {
2124
                        dom: 'C<"top pager"ilpfB><"#filter_c">tr<"bottom pager"ip>',
2143
                        dom: 'C<"top pager"ilpfB><"#filter_c">tr<"bottom pager"ip>',
Lines 2134-2140 Link Here
2134
2153
2135
    [% IF suggestions.count %]
2154
    [% IF suggestions.count %]
2136
        <script>
2155
        <script>
2137
            $(document).ready(function() {
2156
            $(document).ready(function () {
2138
                $("#suggestions").kohaTable({
2157
                $("#suggestions").kohaTable({
2139
                    pagingType: "full",
2158
                    pagingType: "full",
2140
                });
2159
                });
Lines 2146-2155 Link Here
2146
        <script>
2165
        <script>
2147
            var comment_table_settings = [% TablesSettings.GetTableSettings('catalogue', 'detail', 'comments-table', 'json') | $raw %];
2166
            var comment_table_settings = [% TablesSettings.GetTableSettings('catalogue', 'detail', 'comments-table', 'json') | $raw %];
2148
        </script>
2167
        </script>
2149
2150
        <script>
2168
        <script>
2151
            $(document).ready(function() {
2169
            $(document).ready(function () {
2152
2153
                var comments_table = $("#comments_table").kohaTable(
2170
                var comments_table = $("#comments_table").kohaTable(
2154
                    {
2171
                    {
2155
                        paging: false,
2172
                        paging: false,
Lines 2164-2427 Link Here
2164
2181
2165
    [% IF found1 && Koha.Preference('RetainCatalogSearchTerms') %]
2182
    [% IF found1 && Koha.Preference('RetainCatalogSearchTerms') %]
2166
        <script>
2183
        <script>
2167
            $(document).ready(function() {
2184
            $(document).ready(function () {
2168
                var search_index = localStorage.getItem("cat_search_pulldown_selection");
2185
                var search_index = localStorage.getItem("cat_search_pulldown_selection");
2169
                var search_value = localStorage.getItem("searchbox_value");
2186
                var search_value = localStorage.getItem("searchbox_value");
2170
                if ( search_index ){ $('#cat-search-block select.advsearch').val(search_index)};
2187
                if (search_index) {
2171
                if ( search_value ){ $('#cat-search-block #search-form').val(search_value)};
2188
                    $("#cat-search-block select.advsearch").val(search_index);
2189
                }
2190
                if (search_value) {
2191
                    $("#cat-search-block #search-form").val(search_value);
2192
                }
2172
            });
2193
            });
2173
        </script>
2194
        </script>
2174
    [% END %]
2195
    [% END %]
2175
2196
2176
    [% IF Koha.Preference('EnableItemGroups') %]
2197
    [% IF Koha.Preference('EnableItemGroups') %]
2177
        <script>
2198
        <script>
2178
            $(document).ready(function() {
2199
            $(document).ready(function () {
2179
2200
                // Load item groups table
2180
            // Load item groups table
2201
                var itemGroupsTable = $("#items-group-table").kohaTable({
2181
            var itemGroupsTable = $("#items-group-table").kohaTable({
2202
                    autoWidth: false,
2182
                autoWidth: false,
2203
                    dom: '<"top pager"ilp>t<"bottom pager"ip>r',
2183
                dom: '<"top pager"ilp>t<"bottom pager"ip>r',
2204
                    columns: [
2184
                columns: [
2205
                        {
2185
                    {
2206
                            data: "display_order",
2186
                        data: "display_order",
2207
                            title: _("Display order"),
2187
                        title: _("Display order"),
2208
                            searchable: true,
2188
                        searchable: true,
2209
                            orderable: true,
2189
                        orderable: true,
2210
                        },
2190
                    },
2211
                        {
2191
                    {
2212
                            data: "description",
2192
                        data: "description",
2213
                            title: _("Description"),
2193
                        title: _("Description"),
2214
                            searchable: true,
2194
                        searchable: true,
2215
                            orderable: true,
2195
                        orderable: true,
2216
                        },
2196
                    },
2217
                        {
2197
                    {
2218
                            data: function (oObj) {
2198
                        data: function( oObj ) {
2219
                                if (permissions.CAN_user_editcatalogue_manage_item_groups) {
2199
                            if (permissions.CAN_user_editcatalogue_manage_item_groups){
2220
                                    return (
2200
                                return `<button class='item-group-edit btn btn-default btn-xs' data-item-group-id='${oObj.item_group_id}'>
2221
                                        `<button class='item-group-edit btn btn-default btn-xs' data-item-group-id='${oObj.item_group_id}'>
2201
                                    <i class="fa-solid fa-pencil" aria-hidden="true"></i> ${_("Edit")}
2222
                                    <i class="fa-solid fa-pencil" aria-hidden="true"></i> ${_("Edit")}
2223
                                </button>` +
2224
                                        "&nbsp" +
2225
                                        `<button class='item-group-delete btn btn-default btn-xs' data-item-group-id='${oObj.item_group_id}'>
2226
                                    <i class='fa fa-trash-can'></i> ${"Delete"}
2202
                                </button>`
2227
                                </button>`
2203
                                + '&nbsp'
2228
                                    );
2204
                                + `<button class='item-group-delete btn btn-default btn-xs' data-item-group-id='${oObj.item_group_id}'>
2229
                                } else {
2205
                                    <i class='fa fa-trash-can'></i> ${('Delete')}
2230
                                    return "";
2206
                                </button>`;
2231
                                }
2207
                            } else {
2232
                            },
2208
                                return "";
2233
                            searchable: false,
2209
                            }
2234
                            orderable: false,
2210
                        },
2235
                        },
2211
                        searchable: false,
2236
                    ],
2212
                        orderable: false,
2237
                    paging: false,
2238
                    ajax: { url: `/api/v1/biblios/${biblionumber}/item_groups?_per_page=-1` },
2239
                });
2240
2241
                // Create new item groups
2242
                $(".item-group-create").on("click", function () {
2243
                    $("#modal-item-group-create-form-description").val("");
2244
                    $("#modal-item-group-create-submit").removeAttr("disabled");
2245
                    $("#modal-item-group-create").modal("show");
2246
                });
2247
2248
                $("#modal-item-group-create-form").validate({
2249
                    submitHandler: function (form) {
2250
                        $.ajax({
2251
                            url: `/api/v1/biblios/${biblionumber}/item_groups`,
2252
                            headers: { "x-koha-embed": "items" },
2253
                            success: function (item_groups) {
2254
                                $("#modal-item-group-create-submit").attr("disabled", "disabled");
2255
2256
                                var settings = {
2257
                                    url: `/api/v1/biblios/${biblionumber}/item_groups`,
2258
                                    method: "POST",
2259
                                    headers: {
2260
                                        "Content-Type": "application/json",
2261
                                    },
2262
                                    data: JSON.stringify({
2263
                                        description: $("#modal-item-group-create-form-description").val(),
2264
                                        display_order: $("#modal-item-group-create-form-display_order").val(),
2265
                                    }),
2266
                                };
2267
2268
                                $.ajax(settings)
2269
                                    .done(function (response) {
2270
                                        $("#item-group-add-form-select").append(
2271
                                            $("<option>", {
2272
                                                value: response.item_group_id,
2273
                                                text: response.description,
2274
                                            })
2275
                                        );
2276
2277
                                        $("#modal-item-group-create").modal("hide");
2278
                                        if (item_groups.length == 0) {
2279
                                            // This bib has no previous item groups, reload the page
2280
                                            window.location.replace(`/cgi-bin/koha/catalogue/detail.pl?biblionumber=${biblionumber}`);
2281
                                        } else {
2282
                                            // Has other item groups, just reload the table
2283
                                            itemGroupsTable.api().ajax.reload();
2284
                                        }
2285
                                    })
2286
                                    .fail(function (err) {
2287
                                        var message = err.responseJSON.error;
2288
                                        alert(message);
2289
                                    });
2290
                            },
2291
                        });
2213
                    },
2292
                    },
2214
                ],
2293
                });
2215
                paging: false,
2216
                ajax: { url: `/api/v1/biblios/${biblionumber}/item_groups?_per_page=-1` },
2217
            });
2218
2294
2219
            // Create new item groups
2295
                $("#modal-item-group-create").on("shown.bs.modal", function () {
2220
            $('.item-group-create').on('click', function(){
2296
                    $("#modal-item-group-create-form-description").focus();
2221
                $('#modal-item-group-create-form-description').val("");
2297
                });
2222
                $('#modal-item-group-create-submit').removeAttr('disabled');
2223
                $('#modal-item-group-create').modal('show');
2224
            });
2225
2298
2226
            $("#modal-item-group-create-form").validate({
2299
                // Edit existing item groups
2227
                submitHandler: function(form) {
2300
                $("body").on("click", ".item-group-edit", function () {
2228
                    $.ajax({
2301
                    const item_group_id = $(this).data("item-group-id");
2229
                        url: `/api/v1/biblios/${biblionumber}/item_groups`,
2302
                    const url = `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`;
2230
                        headers: { "x-koha-embed": "items" },
2303
                    $.get(url, function (data) {
2231
                        success: function(item_groups){
2304
                        $("#modal-item-group-edit-form-description").val(data.description);
2232
                            $('#modal-item-group-create-submit').attr('disabled', 'disabled');
2305
                        $("#modal-item-group-edit-form-display_order").val(data.display_order);
2233
2306
                        $("#modal-item-group-edit-submit").data("item-group-id", item_group_id);
2234
                            var settings = {
2307
                        $("#modal-item-group-edit-submit").removeAttr("disabled");
2235
                              "url": `/api/v1/biblios/${biblionumber}/item_groups`,
2308
                        $("#modal-item-group-edit").modal("show");
2236
                              "method": "POST",
2309
                    });
2237
                              "headers": {
2310
                });
2238
                                "Content-Type": "application/json"
2311
2239
                              },
2312
                $("#modal-item-group-edit-form").validate({
2240
                              "data": JSON.stringify(
2313
                    submitHandler: function (form) {
2241
                                  {
2314
                        $("#modal-item-group-edit-submit").attr("disabled", "disabled");
2242
                                      "description": $("#modal-item-group-create-form-description").val(),
2315
2243
                                      "display_order": $("#modal-item-group-create-form-display_order").val(),
2316
                        const item_group_id = $("#modal-item-group-edit-submit").data("item-group-id");
2244
                                  }
2317
                        const url = `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`;
2245
                              ),
2318
2246
                            };
2319
                        var settings = {
2247
2320
                            url: url,
2248
                            $.ajax(settings)
2321
                            method: "PUT",
2322
                            headers: {
2323
                                "Content-Type": "application/json",
2324
                            },
2325
                            data: JSON.stringify({
2326
                                description: $("#modal-item-group-edit-form-description").val(),
2327
                                display_order: $("#modal-item-group-edit-form-display_order").val(),
2328
                            }),
2329
                        };
2330
2331
                        $.ajax(settings)
2249
                            .done(function (response) {
2332
                            .done(function (response) {
2250
                                $('#item-group-add-form-select').append($('<option>', {
2333
                                $("#modal-item-group-edit").modal("hide");
2251
                                    value: response.item_group_id,
2334
                                itemGroupsTable.api().ajax.reload();
2252
                                    text: response.description
2253
                                }));
2254
2255
                                $('#modal-item-group-create').modal('hide');
2256
                                if ( item_groups.length == 0 ) {
2257
                                    // This bib has no previous item groups, reload the page
2258
                                    window.location.replace(`/cgi-bin/koha/catalogue/detail.pl?biblionumber=${biblionumber}`);
2259
                                } else {
2260
                                    // Has other item groups, just reload the table
2261
                                    itemGroupsTable.api().ajax.reload();
2262
                                }
2263
                            })
2335
                            })
2264
                            .fail(function(err) {
2336
                            .fail(function (err) {
2265
                                var message = err.responseJSON.error;
2337
                                var message = err.responseJSON.error;
2266
                                alert(message);
2338
                                alert(message);
2267
                            });
2339
                            });
2268
                        }
2340
                    },
2269
                    });
2341
                });
2270
                }
2271
            });
2272
2342
2273
            $('#modal-item-group-create').on('shown.bs.modal', function () {
2343
                $("#modal-item-group-edit").on("shown.bs.modal", function () {
2274
                $('#modal-item-group-create-form-description').focus();
2344
                    $("#modal-item-group-edit-form-description").focus();
2275
            });
2345
                });
2276
2346
2277
            // Edit existing item groups
2347
                // Delete existing item groups
2278
            $('body').on( 'click', '.item-group-edit', function(){
2348
                $("body").on("click", ".item-group-delete", function () {
2279
                const item_group_id = $(this).data('item-group-id');
2349
                    const item_group_id = $(this).data("item-group-id");
2280
                const url = `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`;
2350
                    $("#modal-item-group-delete-submit").data("item-group-id", item_group_id);
2281
                $.get( url, function( data ) {
2351
                    $("#modal-item-group-delete-submit").removeAttr("disabled");
2282
                    $('#modal-item-group-edit-form-description').val( data.description );
2352
                    $("#modal-item-group-delete").modal("show");
2283
                    $('#modal-item-group-edit-form-display_order').val( data.display_order );
2284
                    $('#modal-item-group-edit-submit').data('item-group-id', item_group_id );
2285
                    $('#modal-item-group-edit-submit').removeAttr('disabled');
2286
                    $('#modal-item-group-edit').modal('show');
2287
                });
2353
                });
2288
            });
2354
                $("#modal-item-group-delete-submit").on("click", function () {
2355
                    $("#modal-item-group-delete-submit").attr("disabled", "disabled");
2356
                    const item_group_id = $("#modal-item-group-delete-submit").data("item-group-id");
2289
2357
2290
            $("#modal-item-group-edit-form").validate({
2358
                    $.ajax({
2291
                submitHandler: function(form) {
2359
                        url: `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`,
2292
                    $('#modal-item-group-edit-submit').attr('disabled', 'disabled');
2360
                        headers: { "x-koha-embed": "items" },
2361
                        success: function (item_group_data) {
2362
                            $.ajax({
2363
                                url: `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`,
2364
                                method: "DELETE",
2365
                            })
2366
                                .done(function (response) {
2367
                                    $("#modal-item-group-delete").modal("hide");
2368
                                    $(`#item-group-add-form-select option[value='${item_group_id}']`).remove();
2369
                                    if (item_group_data.items === null) {
2370
                                        // No items for this item group, we can just refresh the table
2371
                                        itemGroupsTable.api().ajax.reload();
2372
                                    } else {
2373
                                        // This item group had items attached to it, we need to reload the page
2374
                                        window.location.replace(`/cgi-bin/koha/catalogue/detail.pl?biblionumber=${biblionumber}`);
2375
                                    }
2376
                                })
2377
                                .fail(function (err) {
2378
                                    var message = err.responseJSON.error;
2379
                                    alert(message);
2380
                                });
2381
                        },
2382
                    });
2383
                });
2293
2384
2294
                    const item_group_id = $('#modal-item-group-edit-submit').data('item-group-id');
2385
                // Add item(s) to a item group
2295
                    const url = `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`;
2386
                $(".itemselection_action_item_group_set").on("click", function () {
2387
                    $("#modal-item-group-set").modal("show");
2388
                });
2296
2389
2297
                    var settings = {
2390
                $("#modal-item-group-set-form").validate({
2298
                      "url": url,
2391
                    submitHandler: function (form) {
2299
                      "method": "PUT",
2392
                        $("#modal-item-group-set-submit").attr("disabled", "disabled");
2300
                      "headers": {
2301
                        "Content-Type": "application/json"
2302
                      },
2303
                      "data": JSON.stringify(
2304
                          {
2305
                              "description": $("#modal-item-group-edit-form-description").val(),
2306
                              "display_order": $("#modal-item-group-edit-form-display_order").val(),
2307
                          }
2308
                      ),
2309
                    };
2310
2311
                    $.ajax(settings)
2312
                    .done(function (response) {
2313
                        $('#modal-item-group-edit').modal('hide');
2314
                        itemGroupsTable.api().ajax.reload();
2315
                    })
2316
                    .fail(function(err) {
2317
                        var message = err.responseJSON.error;
2318
                        alert(message);
2319
                    });
2320
                }
2321
            });
2322
2393
2323
            $('#modal-item-group-edit').on('shown.bs.modal', function () {
2394
                        const item_group_id = $("#item-group-add-form-select").val();
2324
                $('#modal-item-group-edit-form-description').focus();
2325
            })
2326
2395
2327
            // Delete existing item groups
2396
                        let itemnumbers = new Array();
2328
            $('body').on( 'click', '.item-group-delete', function(){
2397
                        $("input[name='itemnumber'][type='checkbox']:checked").each(function () {
2329
                const item_group_id = $(this).data('item-group-id');
2398
                            const itemnumber = $(this).val();
2330
                $('#modal-item-group-delete-submit').data('item-group-id', item_group_id );
2399
                            itemnumbers.push(itemnumber);
2331
                $('#modal-item-group-delete-submit').removeAttr('disabled');
2332
                $('#modal-item-group-delete').modal('show');
2333
            });
2334
            $("#modal-item-group-delete-submit").on('click', function(){
2335
                $('#modal-item-group-delete-submit').attr('disabled', 'disabled');
2336
                const item_group_id = $("#modal-item-group-delete-submit").data('item-group-id');
2337
2338
                $.ajax({
2339
                    url: `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`,
2340
                    headers: { "x-koha-embed": "items" },
2341
                    success: function(item_group_data){
2342
                        $.ajax({
2343
                          "url": `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`,
2344
                          "method": "DELETE",
2345
                        })
2346
                        .done(function (response) {
2347
                            $('#modal-item-group-delete').modal('hide');
2348
                            $(`#item-group-add-form-select option[value='${item_group_id}']`).remove();
2349
                            if ( item_group_data.items === null ) {
2350
                                // No items for this item group, we can just refresh the table
2351
                                itemGroupsTable.api().ajax.reload();
2352
                            } else {
2353
                                // This item group had items attached to it, we need to reload the page
2354
                                window.location.replace(`/cgi-bin/koha/catalogue/detail.pl?biblionumber=${biblionumber}`);
2355
                            }
2356
                        })
2357
                        .fail(function(err) {
2358
                            var message = err.responseJSON.error;
2359
                            alert(message);
2360
                        });
2400
                        });
2361
                    }
2401
                        if (itemnumbers.length > 0) {
2362
                });
2402
                            let url = "/cgi-bin/koha/catalogue/detail.pl?op=set_item_group";
2363
            });
2403
                            url += "&itemnumber=" + itemnumbers.join("&itemnumber=");
2404
                            url += "&biblionumber=" + biblionumber;
2405
                            url += `&item_group_id=${item_group_id}`;
2364
2406
2365
            // Add item(s) to a item group
2407
                            window.location.replace(url);
2366
            $('.itemselection_action_item_group_set').on('click', function(){
2408
                        }
2367
                $('#modal-item-group-set').modal('show');
2409
2368
            });
2410
                        $("#modal-item-group-set").modal("hide");
2411
                    },
2412
                });
2369
2413
2370
            $("#modal-item-group-set-form").validate({
2414
                // Remove item(s) from an item group
2371
                submitHandler: function(form) {
2415
                $(".itemselection_action_item_group_unset").on("click", function () {
2372
                    $('#modal-item-group-set-submit').attr('disabled', 'disabled');
2416
                    $("#modal-item-group-unset").modal("show");
2417
                });
2373
2418
2374
                    const item_group_id = $('#item-group-add-form-select').val();
2419
                $("#modal-item-group-unset-submit").on("click", function () {
2420
                    $("#modal-item-group-unset-submit").attr("disabled", "disabled");
2375
2421
2376
                    let itemnumbers = new Array();
2422
                    let itemnumbers = new Array();
2377
                    $("input[name='itemnumber'][type='checkbox']:checked").each(function() {
2423
                    $("input[name='itemnumber'][type='checkbox']:checked").each(function () {
2378
                        const itemnumber = $(this).val();
2424
                        const itemnumber = $(this).val();
2379
                        itemnumbers.push( itemnumber );
2425
                        itemnumbers.push(itemnumber);
2380
                    });
2426
                    });
2381
                    if (itemnumbers.length > 0) {
2427
                    if (itemnumbers.length > 0) {
2382
                        let url = '/cgi-bin/koha/catalogue/detail.pl?op=set_item_group';
2428
                        let url = "/cgi-bin/koha/catalogue/detail.pl?op=unset_item_group";
2383
                        url += '&itemnumber=' + itemnumbers.join('&itemnumber=');
2429
                        url += "&itemnumber=" + itemnumbers.join("&itemnumber=");
2384
                        url += '&biblionumber=' + biblionumber;
2430
                        url += "&biblionumber=" + biblionumber;
2385
                        url += `&item_group_id=${item_group_id}`;
2386
2431
2387
                        window.location.replace(url);
2432
                        window.location.replace(url);
2388
                    }
2433
                    }
2389
2434
2390
                    $('#modal-item-group-set').modal('hide');
2435
                    $("#modal-item-group-unset").modal("hide");
2391
                }
2392
            });
2393
2394
            // Remove item(s) from an item group
2395
            $('.itemselection_action_item_group_unset').on('click', function(){
2396
                $('#modal-item-group-unset').modal('show');
2397
            });
2398
2399
            $("#modal-item-group-unset-submit").on('click', function(){
2400
                $('#modal-item-group-unset-submit').attr('disabled', 'disabled');
2401
2402
                let itemnumbers = new Array();
2403
                $("input[name='itemnumber'][type='checkbox']:checked").each(function() {
2404
                    const itemnumber = $(this).val();
2405
                    itemnumbers.push( itemnumber );
2406
                });
2436
                });
2407
                if (itemnumbers.length > 0) {
2408
                    let url = '/cgi-bin/koha/catalogue/detail.pl?op=unset_item_group';
2409
                    url += '&itemnumber=' + itemnumbers.join('&itemnumber=');
2410
                    url += '&biblionumber=' + biblionumber;
2411
2412
                    window.location.replace(url);
2413
                }
2414
2415
                $('#modal-item-group-unset').modal('hide');
2416
            });
2437
            });
2417
2418
        });
2419
        </script>
2438
        </script>
2420
    [% END # /IF EnableItemGroups %]
2439
    [% END # /IF EnableItemGroups %]
2421
2422
    <script>
2440
    <script>
2423
        $(".delete-comment").on("click", function(){
2441
        $(".delete-comment").on("click", function () {
2424
            return confirm( _("Are you sure you want to delete this comment?") );
2442
            return confirm(_("Are you sure you want to delete this comment?"));
2425
        });
2443
        });
2426
2444
2427
        specific_dt_errors = _("Have a look at the 'Audit' button in the toolbar");
2445
        specific_dt_errors = _("Have a look at the 'Audit' button in the toolbar");
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/issuehistory.tt (-2 / +1 lines)
Lines 134-142 Link Here
134
            table_settings['columns'].splice(0,1);
134
            table_settings['columns'].splice(0,1);
135
        [% END %]
135
        [% END %]
136
    </script>
136
    </script>
137
138
    <script>
137
    <script>
139
        $(document).ready(function() {
138
        $(document).ready(function () {
140
            var table = $("#table_issues").kohaTable(
139
            var table = $("#table_issues").kohaTable(
141
                {
140
                {
142
                    dom: 'C<"top pager"ilpfB><"#filter_c">tr<"bottom pager"ip>',
141
                    dom: 'C<"top pager"ilpfB><"#filter_c">tr<"bottom pager"ip>',
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/itemsearch.tt (-270 / +330 lines)
Lines 439-452 Link Here
439
            return av;
439
            return av;
440
        } );
440
        } );
441
    </script>
441
    </script>
442
443
    <script>
442
    <script>
444
        function showItemSelections( number ){
443
        function showItemSelections(number) {
445
            let caret = ' <span class="caret">';
444
            let caret = ' <span class="caret">';
446
            if( number > 0 ){
445
            if (number > 0) {
447
                $("#table_search_selections").show().find("span").html(_("Items selected: ") + number );
446
                $("#table_search_selections")
447
                    .show()
448
                    .find("span")
449
                    .html(_("Items selected: ") + number);
448
                $("#batch_mod_menu").removeClass("disabled").prop("disabled", false);
450
                $("#batch_mod_menu").removeClass("disabled").prop("disabled", false);
449
                $("#export-button").html(_("Export selected results (%s) to").format  ( number ) + caret);
451
                $("#export-button").html(_("Export selected results (%s) to").format(number) + caret);
450
            } else {
452
            } else {
451
                $("#table_search_selections").hide();
453
                $("#table_search_selections").hide();
452
                $("#batch_mod_menu").prop("disabled", true).addClass("disabled");
454
                $("#batch_mod_menu").prop("disabled", true).addClass("disabled");
Lines 456-477 Link Here
456
        }
458
        }
457
459
458
        function loadAuthorisedValuesSelect(select) {
460
        function loadAuthorisedValuesSelect(select) {
459
            var selected = select.find('option:selected');
461
            var selected = select.find("option:selected");
460
            var category = selected.data('authorised-values-category');
462
            var category = selected.data("authorised-values-category");
461
            var form_field_value = select.siblings('.form-field-value');
463
            var form_field_value = select.siblings(".form-field-value");
462
            if (category && category in authorised_values) {
464
            if (category && category in authorised_values) {
463
                var values = authorised_values[category];
465
                var values = authorised_values[category];
464
                var html = '<select name="q" class="form-field-value">\n';
466
                var html = '<select name="q" class="form-field-value">\n';
465
                for (i in values) {
467
                for (i in values) {
466
                    var value = values[i];
468
                    var value = values[i];
467
                    html += '<option value="' + value.authorised_value + '">' + value.lib + '</option>\n';
469
                    html += '<option value="' + value.authorised_value + '">' + value.lib + "</option>\n";
468
                }
470
                }
469
                html += '</select>\n';
471
                html += "</select>\n";
470
                var new_form_field_value = $(html);
472
                var new_form_field_value = $(html);
471
                new_form_field_value.val(form_field_value.val());
473
                new_form_field_value.val(form_field_value.val());
472
                form_field_value.replaceWith(new_form_field_value);
474
                form_field_value.replaceWith(new_form_field_value);
473
            } else {
475
            } else {
474
                if (form_field_value.prop('tagName').toLowerCase() == 'select') {
476
                if (form_field_value.prop("tagName").toLowerCase() == "select") {
475
                    html = '<input name="q" type="text" class="form-field-value" />';
477
                    html = '<input name="q" type="text" class="form-field-value" />';
476
                    var new_form_field_value = $(html);
478
                    var new_form_field_value = $(html);
477
                    form_field_value.replaceWith(new_form_field_value);
479
                    form_field_value.replaceWith(new_form_field_value);
Lines 479-502 Link Here
479
            }
481
            }
480
        }
482
        }
481
483
482
        function addNewField( link ) {
484
        function addNewField(link) {
483
            var form_field = $('div.form-field-select-text').last();
485
            var form_field = $("div.form-field-select-text").last();
484
            var copy = form_field.clone(true);
486
            var copy = form_field.clone(true);
485
            copy.find('input,select').not('[type="hidden"]').each(function() {
487
            copy.find("input,select")
486
                $(this).val('');
488
                .not('[type="hidden"]')
487
            });
489
                .each(function () {
488
            copy.find('.form-field-conjunction').prop('disabled', false).val('and');
490
                    $(this).val("");
491
                });
492
            copy.find(".form-field-conjunction").prop("disabled", false).val("and");
489
            form_field.after(copy);
493
            form_field.after(copy);
490
            link.remove();
494
            link.remove();
491
            copy.find('select.form-field-column').change();
495
            copy.find("select.form-field-column").change();
492
        }
496
        }
493
497
494
        function exportItems(format) {
498
        function exportItems(format) {
495
            let item_search_selections = JSON.parse(localStorage.getItem("item_search_selections")) || [];
499
            let item_search_selections = JSON.parse(localStorage.getItem("item_search_selections")) || [];
496
            if (item_search_selections.length > 0) {
500
            if (item_search_selections.length > 0) {
497
                let inputs = item_search_selections.map(itemnumber =>
501
                let inputs = item_search_selections.map(itemnumber => `<input type="hidden" name="itemnumber" value="${itemnumber}">`).join("");
498
                    `<input type="hidden" name="itemnumber" value="${itemnumber}">`
499
                ).join('');
500
502
501
                const csrf_token = $('meta[name="csrf-token"]').attr("content");
503
                const csrf_token = $('meta[name="csrf-token"]').attr("content");
502
                let form = $(`
504
                let form = $(`
Lines 508-531 Link Here
508
                    </form>
510
                    </form>
509
                `);
511
                `);
510
512
511
                $('body').append(form);
513
                $("body").append(form);
512
                form.submit();
514
                form.submit();
513
                form.remove();
515
                form.remove();
514
            } else {
516
            } else {
515
                $('#format-' + format).prop('checked', true);
517
                $("#format-" + format).prop("checked", true);
516
                $('#itemsearchform').submit();
518
                $("#itemsearchform").submit();
517
                $('#format-html').prop('checked', true);
519
                $("#format-html").prop("checked", true);
518
            }
520
            }
519
        }
521
        }
520
522
521
        function prepSelections(){
523
        function prepSelections() {
522
            let item_search_selections = JSON.parse( localStorage.getItem("item_search_selections") ) || [];
524
            let item_search_selections = JSON.parse(localStorage.getItem("item_search_selections")) || [];
523
            if( item_search_selections.length > 0 ){
525
            if (item_search_selections.length > 0) {
524
                showItemSelections( item_search_selections.length );
526
                showItemSelections(item_search_selections.length);
525
                $("#item_search input[type='checkbox']").each(function(){
527
                $("#item_search input[type='checkbox']").each(function () {
526
                    var itemnumber = $(this).val();
528
                    var itemnumber = $(this).val();
527
                    if( item_search_selections.indexOf( itemnumber ) >= 0 ){
529
                    if (item_search_selections.indexOf(itemnumber) >= 0) {
528
                        $(this).prop("checked", true );
530
                        $(this).prop("checked", true);
529
                    }
531
                    }
530
                });
532
                });
531
            }
533
            }
Lines 533-664 Link Here
533
535
534
        function getParams($form) {
536
        function getParams($form) {
535
            var params = [];
537
            var params = [];
536
            $form.find('select:not(:disabled) option:selected,input[type="text"]:not(:disabled),input[type="hidden"]:not(:disabled),input[type="radio"]:checked').each(function() {
538
            $form.find('select:not(:disabled) option:selected,input[type="text"]:not(:disabled),input[type="hidden"]:not(:disabled),input[type="radio"]:checked').each(function () {
537
                if ( $(this).prop('tagName').toLowerCase() == 'option' ) {
539
                if ($(this).prop("tagName").toLowerCase() == "option") {
538
                    var name = $(this).parents('select').first().attr('name');
540
                    var name = $(this).parents("select").first().attr("name");
539
                    var value = $(this).val();
541
                    var value = $(this).val();
540
                    params.push({ 'name': name, 'value': value });
542
                    params.push({ name: name, value: value });
541
                } else {
543
                } else {
542
                    params.push({ 'name': $(this).attr('name'), 'value': $(this).val() });
544
                    params.push({ name: $(this).attr("name"), value: $(this).val() });
543
                }
545
                }
544
            });
546
            });
545
            return params;
547
            return params;
546
        }
548
        }
547
549
548
        function submitForm($form) {
550
        function submitForm($form) {
549
            var tr = ''
551
            var tr =
550
                + '    <tr>'
552
                "" +
551
                + '      <th id="items_checkbox" data-colname="itemsearch_checkbox"></th>'
553
                "    <tr>" +
552
                + '      <th id="items_title" data-colname="title">' + _("Title") + '</th>'
554
                '      <th id="items_checkbox" data-colname="itemsearch_checkbox"></th>' +
553
                + '      <th id="items_pubdate" data-colname="publication_date">' + _("Publication date") + '</th>'
555
                '      <th id="items_title" data-colname="title">' +
554
                + '      <th id="items_publisher" data-colname="publisher">' + _("Publisher") + '</th>'
556
                _("Title") +
555
                + '      <th id="items_collection" data-colname="collection">' + _("Collection") + '</th>'
557
                "</th>" +
556
                + '      <th id="items_barcode" data-colname="barcode">' + _("Barcode") + '</th>'
558
                '      <th id="items_pubdate" data-colname="publication_date">' +
557
                + '      <th id="items_itemnumber" data-colname="item_number">' + _("Item number") + '</th>'
559
                _("Publication date") +
558
                + '      <th id="items_enumchron" data-colname="serial_enumeration">' + _("Serial enumeration") + '</th>'
560
                "</th>" +
559
                + '      <th id="items_callno" data-colname="call_number">' + _("Call number") + '</th>'
561
                '      <th id="items_publisher" data-colname="publisher">' +
560
                + '      <th id="items_homebranch" data-colname="home_library">' + _("Home library") + '</th>'
562
                _("Publisher") +
561
                + '      <th id="items_holdingbranch" data-colname="current_library">' + _("Current library") + '</th>'
563
                "</th>" +
562
                + '      <th id="items_location" data-colname="shelving_location">' + _("Shelving location") + '</th>'
564
                '      <th id="items_collection" data-colname="collection">' +
563
                + '      <th id="items_itype" data-colname="item_type">' + _("Itemtype") + '</th>'
565
                _("Collection") +
564
                + '      <th id="item_inventoryno" data-colname="inventory_number">' + _("Inventory number") + '</th>'
566
                "</th>" +
565
                + '      <th id="items_status" data-colname="notforloan_status">' + _("Not for loan status") + '</th>'
567
                '      <th id="items_barcode" data-colname="barcode">' +
566
                + '      <th id="items_itemlost" data-colname="lost_status">' + _("Lost status") + '</th>'
568
                _("Barcode") +
567
                + '      <th id="items_widthdrawn" data-colname="withdrawn_status">' + _("Withdrawn status") + '</th>'
569
                "</th>" +
568
                + '      <th id="items_damaged" data-colname="damaged_status">' + _("Damaged status") + '</th>'
570
                '      <th id="items_itemnumber" data-colname="item_number">' +
569
                + '      <th id="items_dateaccessioned" data-colname="dateaccessioned">' + _("Date accessioned") + '</th>'
571
                _("Item number") +
570
                + '      <th id="items_checkouts" data-colname="checkouts">' + _("Checkouts") + '</th>'
572
                "</th>" +
571
                + '      <th id="items_datelastborrowed" data-colname="last_checkout_date">' + _("Last checkout date") + '</th>'
573
                '      <th id="items_enumchron" data-colname="serial_enumeration">' +
572
                + '      <th id="items_date_due" data-colname="due_date">' + _("Due date") + '</th>'
574
                _("Serial enumeration") +
573
                + '      <th id="items_actions" data-colname="actions">' + _("Actions") + '</th>'
575
                "</th>" +
574
                + '    </tr>';
576
                '      <th id="items_callno" data-colname="call_number">' +
575
577
                _("Call number") +
576
            var table = ''
578
                "</th>" +
577
                + '<div class="page-section">'
579
                '      <th id="items_homebranch" data-colname="home_library">' +
578
                + '    <div id="searchheader" class="searchheader">'
580
                _("Home library") +
579
                + '        <a href="#" id="select_all" class="btn btn-link"><i class="fa fa-check"></i> '
581
                "</th>" +
580
                +              _("Select visible rows")
582
                '      <th id="items_holdingbranch" data-colname="current_library">' +
581
                + '        </a> | '
583
                _("Current library") +
582
                + '        <a href="#" id="clear_all" class="btn btn-link"><i class="fa fa-times"></i> '
584
                "</th>" +
583
                +              _("Clear selection")
585
                '      <th id="items_location" data-colname="shelving_location">' +
584
                + '        </a>'
586
                _("Shelving location") +
585
                + '        <div class="btn-group"><button class="btn btn-default btn-sm dropdown-toggle" id="export-button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">' + _("Export all results to") + '</button>'
587
                "</th>" +
586
                + '            <ul class="dropdown-menu">'
588
                '      <th id="items_itype" data-colname="item_type">' +
587
                + '                <li><a class="dropdown-item" href="#" id="csvExportLink">' + _("CSV") + '</a></li>'
589
                _("Itemtype") +
588
                + '                <li><a class="dropdown-item" href="#" id="barcodesExportLink">' + _("Barcode file") + '</a></li>'
590
                "</th>" +
589
                + '            </ul>'
591
                '      <th id="item_inventoryno" data-colname="inventory_number">' +
590
                + '        </div>';
592
                _("Inventory number") +
591
            if ( permissions.CAN_user_tools_items_batchmod || permissions.CAN_user_tools_items_batchdel ){
593
                "</th>" +
592
                table += ''
594
                '      <th id="items_status" data-colname="notforloan_status">' +
593
                    + '        <div class="btn-group"><button class="btn btn-default btn-sm dropdown-toggle disabled" disabled="disabled" type="button" id="batch_mod_menu"data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="true"> ' + _("Batch operations") + ' </button>'
595
                _("Not for loan status") +
594
                    + '            <ul class="dropdown-menu" aria-labelledby="batch_mod_menu">';
596
                "</th>" +
595
                if ( permissions.CAN_user_tools_items_batchmod ){
597
                '      <th id="items_itemlost" data-colname="lost_status">' +
596
                    table += ''
598
                _("Lost status") +
597
                        + '                <li> <a class="dropdown-item batch_op send_to_item_mod" href="#" data-submit="batch_item_modification" data-bs-toggle="tooltip" data-bs-placement="right" title="' + _("Send selected items to batch item modification") + '">' + _("Batch item modification") + '</a> </li>';
599
                "</th>" +
600
                '      <th id="items_widthdrawn" data-colname="withdrawn_status">' +
601
                _("Withdrawn status") +
602
                "</th>" +
603
                '      <th id="items_damaged" data-colname="damaged_status">' +
604
                _("Damaged status") +
605
                "</th>" +
606
                '      <th id="items_dateaccessioned" data-colname="dateaccessioned">' +
607
                _("Date accessioned") +
608
                "</th>" +
609
                '      <th id="items_checkouts" data-colname="checkouts">' +
610
                _("Checkouts") +
611
                "</th>" +
612
                '      <th id="items_datelastborrowed" data-colname="last_checkout_date">' +
613
                _("Last checkout date") +
614
                "</th>" +
615
                '      <th id="items_date_due" data-colname="due_date">' +
616
                _("Due date") +
617
                "</th>" +
618
                '      <th id="items_actions" data-colname="actions">' +
619
                _("Actions") +
620
                "</th>" +
621
                "    </tr>";
622
623
            var table =
624
                "" +
625
                '<div class="page-section">' +
626
                '    <div id="searchheader" class="searchheader">' +
627
                '        <a href="#" id="select_all" class="btn btn-link"><i class="fa fa-check"></i> ' +
628
                _("Select visible rows") +
629
                "        </a> | " +
630
                '        <a href="#" id="clear_all" class="btn btn-link"><i class="fa fa-times"></i> ' +
631
                _("Clear selection") +
632
                "        </a>" +
633
                '        <div class="btn-group"><button class="btn btn-default btn-sm dropdown-toggle" id="export-button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">' +
634
                _("Export all results to") +
635
                "</button>" +
636
                '            <ul class="dropdown-menu">' +
637
                '                <li><a class="dropdown-item" href="#" id="csvExportLink">' +
638
                _("CSV") +
639
                "</a></li>" +
640
                '                <li><a class="dropdown-item" href="#" id="barcodesExportLink">' +
641
                _("Barcode file") +
642
                "</a></li>" +
643
                "            </ul>" +
644
                "        </div>";
645
            if (permissions.CAN_user_tools_items_batchmod || permissions.CAN_user_tools_items_batchdel) {
646
                table +=
647
                    "" +
648
                    '        <div class="btn-group"><button class="btn btn-default btn-sm dropdown-toggle disabled" disabled="disabled" type="button" id="batch_mod_menu"data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="true"> ' +
649
                    _("Batch operations") +
650
                    " </button>" +
651
                    '            <ul class="dropdown-menu" aria-labelledby="batch_mod_menu">';
652
                if (permissions.CAN_user_tools_items_batchmod) {
653
                    table +=
654
                        "" +
655
                        '                <li> <a class="dropdown-item batch_op send_to_item_mod" href="#" data-submit="batch_item_modification" data-bs-toggle="tooltip" data-bs-placement="right" title="' +
656
                        _("Send selected items to batch item modification") +
657
                        '">' +
658
                        _("Batch item modification") +
659
                        "</a> </li>";
598
                }
660
                }
599
                if ( permissions.CAN_user_tools_items_batchdel ){
661
                if (permissions.CAN_user_tools_items_batchdel) {
600
                    table += ''
662
                    table +=
601
                        + '                <li> <a class="dropdown-item batch_op send_to_item_del"" href="#" data-submit="batch_item_deletion" data-bs-toggle="tooltip" data-bs-placement="right" title="' + _("Send selected items to batch item deletion") + '">' + _("Batch item deletion") + '</a> </li>';
663
                        "" +
664
                        '                <li> <a class="dropdown-item batch_op send_to_item_del"" href="#" data-submit="batch_item_deletion" data-bs-toggle="tooltip" data-bs-placement="right" title="' +
665
                        _("Send selected items to batch item deletion") +
666
                        '">' +
667
                        _("Batch item deletion") +
668
                        "</a> </li>";
602
                }
669
                }
603
                table += ''
670
                table += "" + "            </ul>" + "        </div>";
604
                    + '            </ul>'
605
                    + '        </div>';
606
            }
671
            }
607
            table += ''
672
            table +=
608
                + '        <div id="table_search_selections" class="btn-group" style="display:none;">'
673
                "" +
609
                + '            <span></span>'
674
                '        <div id="table_search_selections" class="btn-group" style="display:none;">' +
610
                + '            <a href="#" id="clear-row-selection"><i class="fa fa-times"></i> ' + _("Clear") + '</a>'
675
                "            <span></span>" +
611
                + '        </div>'
676
                '            <a href="#" id="clear-row-selection"><i class="fa fa-times"></i> ' +
612
                + '    </div>'
677
                _("Clear") +
613
                + '    <table id="item_search">'
678
                "</a>" +
614
                + '      <thead>' + tr + '</thead>'
679
                "        </div>" +
615
                + '      <tbody></tbody>'
680
                "    </div>" +
616
                + '    </table>'
681
                '    <table id="item_search">' +
617
                + '</div>';
682
                "      <thead>" +
618
683
                tr +
619
            var advSearchLink = $('<a>')
684
                "</thead>" +
620
                .attr('href', '/cgi-bin/koha/catalogue/search.pl')
685
                "      <tbody></tbody>" +
621
                .html(_("Go to advanced search"));
686
                "    </table>" +
622
687
                "</div>";
623
            var editSearchLink = $('<a>')
688
624
                .attr('href', '#')
689
            var advSearchLink = $("<a>").attr("href", "/cgi-bin/koha/catalogue/search.pl").html(_("Go to advanced search"));
625
                .html("<i class='fa fa-pencil'></i> " + _("Edit search") )
690
626
                .addClass('btn btn-default')
691
            var editSearchLink = $("<a>")
627
                .on('click', function(e) {
692
                .attr("href", "#")
693
                .html("<i class='fa fa-pencil'></i> " + _("Edit search"))
694
                .addClass("btn btn-default")
695
                .on("click", function (e) {
628
                    e.preventDefault();
696
                    e.preventDefault();
629
                    $('#item-search-block').show();
697
                    $("#item-search-block").show();
630
                });
698
                });
631
699
632
            var getShareableLink = $('<a>')
700
            var getShareableLink = $("<a>")
633
                .attr('href', '#')
701
                .attr("href", "#")
634
                .html("<i class='fa fa-copy'></i> " + _("Copy shareable link") )
702
                .html("<i class='fa fa-copy'></i> " + _("Copy shareable link"))
635
                .addClass('btn btn-default')
703
                .addClass("btn btn-default")
636
                .on('click', function(e) {
704
                .on("click", function (e) {
637
                    e.preventDefault();
705
                    e.preventDefault();
638
                    var params = getParams( $('#itemsearchform') );
706
                    var params = getParams($("#itemsearchform"));
639
                    params = params.map(p => {
707
                    params = params.map(p => {
640
                        if(p.name === 'format') {
708
                        if (p.name === "format") {
641
                            return { ...p, value: 'shareable' };
709
                            return { ...p, value: "shareable" };
642
                        }
710
                        }
643
                        return p;
711
                        return p;
644
                    })
712
                    });
645
                    var url = window.location.origin + window.location.pathname + '?' + $.param(params);
713
                    var url = window.location.origin + window.location.pathname + "?" + $.param(params);
646
                    navigator.clipboard.writeText(url);
714
                    navigator.clipboard.writeText(url);
647
                    $(this).tooltip({trigger: 'manual', title: _("Copied!")}).tooltip('show');
715
                    $(this)
716
                        .tooltip({ trigger: "manual", title: _("Copied!") })
717
                        .tooltip("show");
648
                });
718
                });
649
719
650
            var results_heading = $('<div>').addClass('results-heading')
720
            var results_heading = $("<div>")
721
                .addClass("results-heading")
651
                .append("<h1>" + _("Item search results") + "</h1>")
722
                .append("<h1>" + _("Item search results") + "</h1>")
652
                .append($('<p>').append(advSearchLink))
723
                .append($("<p>").append(advSearchLink))
653
                .append($('<div>')
724
                .append($("<div>").addClass("btn-toolbar").attr("id", "toolbar").append(editSearchLink).append(getShareableLink));
654
                    .addClass("btn-toolbar")
725
            $("#results-wrapper").empty().append(results_heading).append(table);
655
                    .attr("id","toolbar")
656
                    .append(editSearchLink)
657
                    .append(getShareableLink)
658
                );
659
            $('#results-wrapper').empty()
660
                .append(results_heading)
661
                .append(table);
662
726
663
            var params = getParams($form);
727
            var params = getParams($form);
664
728
Lines 673-734 Link Here
673
                av_damaged: all_damageds,
737
                av_damaged: all_damageds,
674
            };
738
            };
675
739
676
            $('#item_search').kohaTable( {
740
            $("#item_search").kohaTable(
677
                bKohaColumnsUseNames: true,
741
                {
678
                destroy: true,
742
                    bKohaColumnsUseNames: true,
679
                serverSide: true,
743
                    destroy: true,
680
                processing: true,
744
                    serverSide: true,
681
                ajax: {
745
                    processing: true,
682
                    url: '/cgi-bin/koha/catalogue/itemsearch.pl',
746
                    ajax: {
683
                    data: function ( d ) {
747
                        url: "/cgi-bin/koha/catalogue/itemsearch.pl",
684
                        for (i in params) {
748
                        data: function (d) {
685
                            if(d[params[i].name]){
749
                            for (i in params) {
686
                                d[params[i].name] = [].concat(d[params[i].name], params[i].value);
750
                                if (d[params[i].name]) {
687
                            }else{
751
                                    d[params[i].name] = [].concat(d[params[i].name], params[i].value);
688
                                d[params[i].name] = params[i].value;
752
                                } else {
753
                                    d[params[i].name] = params[i].value;
754
                                }
689
                            }
755
                            }
690
                        }
756
                            d.format = "json";
691
                        d.format = 'json';
757
                            d.columns = JSON.stringify(d.columns);
692
                        d.columns = JSON.stringify( d.columns );
758
                            return d;
693
                        return d;
759
                        },
694
                    }
760
                    },
695
                },
761
                    bKohaAjaxSVC: true,
696
                bKohaAjaxSVC: true,
762
                    dom: 'C<"top pager"ilpB>tr<"bottom pager"ip>',
697
                dom: 'C<"top pager"ilpB>tr<"bottom pager"ip>',
763
                    order: [[1, "asc"]],
698
                order: [[1, 'asc']],
764
                    columns: [
699
                columns: [
765
                        { name: "checkbox", orderable: false, searchable: false },
700
                    { 'name': 'checkbox', 'orderable': false, searchable: false, },
766
                        { name: "title" },
701
                    { 'name': 'title' },
767
                        { name: "publicationyear" },
702
                    { 'name': 'publicationyear' },
768
                        { name: "publishercode" },
703
                    { 'name': 'publishercode' },
769
                        { name: "ccode", dataFilter: "collection_codes" },
704
                    { 'name': 'ccode', dataFilter: 'collection_codes' },
770
                        { name: "barcode" },
705
                    { 'name': 'barcode' },
771
                        { name: "itemnumber" },
706
                    { 'name': 'itemnumber' },
772
                        { name: "enumchron" },
707
                    { 'name': 'enumchron' },
773
                        { name: "itemcallnumber" },
708
                    { 'name': 'itemcallnumber' },
774
                        { name: "homebranch", dataFilter: "libraries" },
709
                    { 'name': 'homebranch', dataFilter: 'libraries' },
775
                        { name: "holdingbranch", dataFilter: "libraries" },
710
                    { 'name': 'holdingbranch', dataFilter: 'libraries' },
776
                        { name: "location", dataFilter: "locations" },
711
                    { 'name': 'location', dataFilter: 'locations' },
777
                        { name: "itype", dataFilter: "item_types" },
712
                    { 'name': 'itype', dataFilter: 'item_types' },
778
                        { name: "stocknumber" },
713
                    { 'name': 'stocknumber' },
779
                        { name: "notforloan", dataFilter: "av_notforloan" },
714
                    { 'name': 'notforloan', dataFilter: 'av_notforloan' },
780
                        { name: "itemlost", dataFilter: "av_lost" },
715
                    { 'name': 'itemlost', dataFilter: 'av_lost' },
781
                        { name: "withdrawn", dataFilter: "av_widthdrawn" },
716
                    { 'name': 'withdrawn', dataFilter: 'av_widthdrawn' },
782
                        { name: "damaged", dataFilter: "av_damaged" },
717
                    { 'name': 'damaged', dataFilter: 'av_damaged' },
783
                        { name: "dateaccessioned" },
718
                    { 'name': 'dateaccessioned' },
784
                        { name: "issues" },
719
                    { 'name': 'issues' },
785
                        { name: "datelastborrowed" },
720
                    { 'name': 'datelastborrowed' },
786
                        { name: "date_due" },
721
                    { 'name': 'date_due' },
787
                        { name: "actions", orderable: false, searchable: false },
722
                    { 'name': 'actions', 'orderable': false, searchable: false, }
788
                    ],
723
                ],
789
                    pagingType: "full_numbers",
724
                pagingType: "full_numbers",
790
                    drawCallback: function (settings) {
725
                drawCallback: function( settings ) {
791
                        prepSelections();
726
                    prepSelections();
792
                    },
793
                    fixedHeader: false, // There is a bug on this view
727
                },
794
                },
728
                fixedHeader: false // There is a bug on this view
795
                table_settings,
729
            }, table_settings, true, null, filters_options );
796
                true,
797
                null,
798
                filters_options
799
            );
730
800
731
            $('#item_search').on('draw.dt', function (e, settings) {
801
            $("#item_search").on("draw.dt", function (e, settings) {
732
                prepSelections();
802
                prepSelections();
733
                $('[data-bs-toggle="tooltip"]').tooltip();
803
                $('[data-bs-toggle="tooltip"]').tooltip();
734
            });
804
            });
Lines 736-870 Link Here
736
806
737
        $(document).ready(function () {
807
        $(document).ready(function () {
738
            // Add the "New field" link.
808
            // Add the "New field" link.
739
            var form_field = $('div.form-field-select-text').last()
809
            var form_field = $("div.form-field-select-text").last();
740
            var NEW_FIELD = _("New field");
810
            var NEW_FIELD = _("New field");
741
            var button_field_new = $('<a href="#" class="button-field-new" title="Add a new field"><i class="fa fa-plus"></i> ' + NEW_FIELD + '</a>');
811
            var button_field_new = $('<a href="#" class="button-field-new" title="Add a new field"><i class="fa fa-plus"></i> ' + NEW_FIELD + "</a>");
742
            button_field_new.click(function(e) {
812
            button_field_new.click(function (e) {
743
                e.preventDefault();
813
                e.preventDefault();
744
                addNewField( $(this) );
814
                addNewField($(this));
745
            });
815
            });
746
            form_field.append(button_field_new);
816
            form_field.append(button_field_new);
747
817
748
            // If a field is linked to an authorised values list, display the list.
818
            // If a field is linked to an authorised values list, display the list.
749
            $('div.form-field-select-text select[name="f"]').change(function() {
819
            $('div.form-field-select-text select[name="f"]')
750
                loadAuthorisedValuesSelect($(this));
820
                .change(function () {
751
            }).change();
821
                    loadAuthorisedValuesSelect($(this));
822
                })
823
                .change();
752
824
753
            // Prevent user to select the 'All ...' option with other options.
825
            // Prevent user to select the 'All ...' option with other options.
754
            $('div.form-field-select').each(function() {
826
            $("div.form-field-select").each(function () {
755
                $(this).find('select').filter(':last').change(function() {
827
                $(this)
756
                    values = $(this).val();
828
                    .find("select")
757
                    if (values.length > 1) {
829
                    .filter(":last")
758
                        var idx = $.inArray('', values);
830
                    .change(function () {
759
                        if (idx != -1) {
831
                        values = $(this).val();
760
                            values.splice(idx, 1);
832
                        if (values.length > 1) {
761
                            $(this).val(values);
833
                            var idx = $.inArray("", values);
834
                            if (idx != -1) {
835
                                values.splice(idx, 1);
836
                                $(this).val(values);
837
                            }
762
                        }
838
                        }
763
                    }
839
                    });
764
                });
765
            });
840
            });
766
841
767
            $('#itemsearchform').submit(function() {
842
            $("#itemsearchform").submit(function () {
768
                var searchform = $(this);
843
                var searchform = $(this);
769
                if( $("#forget_item_selections").is(':checked') ){
844
                if ($("#forget_item_selections").is(":checked")) {
770
                  localStorage.removeItem("item_search_selections");
845
                    localStorage.removeItem("item_search_selections");
771
                }
846
                }
772
                var format = searchform.find('input[name="format"]:checked').val();
847
                var format = searchform.find('input[name="format"]:checked').val();
773
                if (format == 'html') {
848
                if (format == "html") {
774
                    submitForm(searchform);
849
                    submitForm(searchform);
775
                    $("#item-search-block").hide();
850
                    $("#item-search-block").hide();
776
                    return false;
851
                    return false;
777
                }
852
                }
778
            });
853
            });
779
854
780
            $("body").on("click", "#select_all", function(e) {
855
            $("body").on("click", "#select_all", function (e) {
781
                e.preventDefault();
856
                e.preventDefault();
782
                $("#item_search input[type='checkbox']").each(function(){
857
                $("#item_search input[type='checkbox']").each(function () {
783
                    if( $(this).prop("checked") == false ){
858
                    if ($(this).prop("checked") == false) {
784
                        $(this).prop( "checked", true ).change();
859
                        $(this).prop("checked", true).change();
785
                    }
860
                    }
786
                });
861
                });
787
            });
862
            });
788
863
789
            $("body").on("click", "#clear_all", function(e) {
864
            $("body").on("click", "#clear_all", function (e) {
790
                e.preventDefault();
865
                e.preventDefault();
791
                $("#item_search input[type='checkbox']").each(function(){
866
                $("#item_search input[type='checkbox']").each(function () {
792
                    if( $(this).prop("checked") == true ){
867
                    if ($(this).prop("checked") == true) {
793
                        $(this).prop( "checked", false ).change();
868
                        $(this).prop("checked", false).change();
794
                    }
869
                    }
795
                });
870
                });
796
            });
871
            });
797
872
798
            $("body").on("click", "#clear-row-selection", function(e){
873
            $("body").on("click", "#clear-row-selection", function (e) {
799
                e.preventDefault();
874
                e.preventDefault();
800
                $("#item_search input[type='checkbox']").prop("checked" ,false ).change();
875
                $("#item_search input[type='checkbox']").prop("checked", false).change();
801
                localStorage.removeItem("item_search_selections");
876
                localStorage.removeItem("item_search_selections");
802
                showItemSelections( 0 );
877
                showItemSelections(0);
803
            });
878
            });
804
879
805
            $("body").on('change', '#item_search input[type="checkbox"]', function() {
880
            $("body").on("change", '#item_search input[type="checkbox"]', function () {
806
                let item_search_selections = JSON.parse( localStorage.getItem("item_search_selections") ) || [];
881
                let item_search_selections = JSON.parse(localStorage.getItem("item_search_selections")) || [];
807
                var itemnumber = $(this).val();
882
                var itemnumber = $(this).val();
808
                if( $(this).prop("checked") ){
883
                if ($(this).prop("checked")) {
809
                    item_search_selections.push( $(this).val() );
884
                    item_search_selections.push($(this).val());
810
                    localStorage.setItem('item_search_selections', JSON.stringify( item_search_selections ));
885
                    localStorage.setItem("item_search_selections", JSON.stringify(item_search_selections));
811
                    showItemSelections( item_search_selections.length );
886
                    showItemSelections(item_search_selections.length);
812
                } else {
887
                } else {
813
                    var filtered = item_search_selections.filter(function( value ){
888
                    var filtered = item_search_selections.filter(function (value) {
814
                        return value !== itemnumber;
889
                        return value !== itemnumber;
815
                    });
890
                    });
816
                    if( filtered.length > 0 ){
891
                    if (filtered.length > 0) {
817
                        localStorage.setItem('item_search_selections', JSON.stringify( filtered ));
892
                        localStorage.setItem("item_search_selections", JSON.stringify(filtered));
818
                        item_search_selections = filtered;
893
                        item_search_selections = filtered;
819
                        showItemSelections( filtered.length );
894
                        showItemSelections(filtered.length);
820
                    } else {
895
                    } else {
821
                        item_search_selections = [];
896
                        item_search_selections = [];
822
                        localStorage.removeItem('item_search_selections');
897
                        localStorage.removeItem("item_search_selections");
823
                        showItemSelections( 0 );
898
                        showItemSelections(0);
824
                    }
899
                    }
825
                }
900
                }
826
            });
901
            });
827
902
828
            $("body").on("click", "#csvExportLink", function(e){
903
            $("body").on("click", "#csvExportLink", function (e) {
829
                e.preventDefault();
904
                e.preventDefault();
830
                exportItems('csv');
905
                exportItems("csv");
831
            });
906
            });
832
907
833
            $("body").on("click", "#barcodesExportLink", function(e){
908
            $("body").on("click", "#barcodesExportLink", function (e) {
834
                e.preventDefault();
909
                e.preventDefault();
835
                exportItems('barcodes');
910
                exportItems("barcodes");
836
            });
911
            });
837
912
838
            $("body").on("click", ".batch_op", function(e){
913
            $("body").on("click", ".batch_op", function (e) {
839
                e.preventDefault();
914
                e.preventDefault();
840
                let batch_mod_form = $("#batch_item_operations");
915
                let batch_mod_form = $("#batch_item_operations");
841
                batch_mod_form.empty();
916
                batch_mod_form.empty();
842
                batch_mod_form.append(
917
                batch_mod_form.append($("<input>").attr("type", "hidden").attr("name", "op").val("cud-show"));
843
                    $("<input>").attr("type","hidden")
918
                batch_mod_form.append($("<input>").attr("type", "hidden").attr("name", "csrf_token").val($('meta[name="csrf-token"]').attr("content")));
844
                    .attr("name", "op")
919
                batch_mod_form.append($("<input>").attr("type", "hidden").attr("name", "del").attr("id", "batch_mod_del"));
845
                    .val("cud-show")
920
                let item_search_selections = JSON.parse(localStorage.getItem("item_search_selections")) || [];
846
                );
847
                batch_mod_form.append(
848
                    $("<input>").attr("type","hidden")
849
                    .attr("name", "csrf_token")
850
                    .val($('meta[name="csrf-token"]').attr('content'))
851
                );
852
                batch_mod_form.append(
853
                    $("<input>").attr("type","hidden")
854
                    .attr("name", "del")
855
                    .attr("id", "batch_mod_del")
856
                );
857
                let item_search_selections = JSON.parse( localStorage.getItem("item_search_selections") ) || [];
858
                // Populate batch forms with itemnumbers in local storage
921
                // Populate batch forms with itemnumbers in local storage
859
                for (let item of item_search_selections){
922
                for (let item of item_search_selections) {
860
                    var field = $("<input>").attr("type","hidden")
923
                    var field = $("<input>").attr("type", "hidden").attr("name", "itemnumber").val(item);
861
                        .attr("name","itemnumber")
924
                    batch_mod_form.append(field);
862
                        .val( item );
863
                    batch_mod_form.append( field );
864
                }
925
                }
865
                if( $(this).hasClass("send_to_item_mod") ){
926
                if ($(this).hasClass("send_to_item_mod")) {
866
                    $("#batch_mod_del").val(0);
927
                    $("#batch_mod_del").val(0);
867
                } else if ( $(this).hasClass("send_to_item_del") ){
928
                } else if ($(this).hasClass("send_to_item_del")) {
868
                    $("#batch_mod_del").val(1);
929
                    $("#batch_mod_del").val(1);
869
                } else {
930
                } else {
870
                    return false;
931
                    return false;
Lines 872-895 Link Here
872
                batch_mod_form.submit();
933
                batch_mod_form.submit();
873
            });
934
            });
874
935
875
            $("body").on('click','#item_search tbody td',function(e){
936
            $("body").on("click", "#item_search tbody td", function (e) {
876
                var checkbox = $(this).find("input[type=checkbox]");
937
                var checkbox = $(this).find("input[type=checkbox]");
877
                if (e.target.type != "checkbox") {
938
                if (e.target.type != "checkbox") {
878
                    checkbox.prop('checked', !checkbox.prop("checked"));
939
                    checkbox.prop("checked", !checkbox.prop("checked"));
879
                    checkbox.change();
940
                    checkbox.change();
880
                }
941
                }
881
            });
942
            });
882
943
883
            // Apply select2 to all select fields having a "multiple" attribute
944
            // Apply select2 to all select fields having a "multiple" attribute
884
            let selectFields = document.querySelectorAll('select[multiple]');
945
            let selectFields = document.querySelectorAll("select[multiple]");
885
            selectFields.forEach((selectField) => {
946
            selectFields.forEach(selectField => {
886
                selectField.style.minWidth = '320px';
947
                selectField.style.minWidth = "320px";
887
                $(selectField).select2();
948
                $(selectField).select2();
888
            });
949
            });
889
950
890
            let urlParams = new URLSearchParams(window.location.search)
951
            let urlParams = new URLSearchParams(window.location.search);
891
            if (urlParams.get('format') === 'shareable') {
952
            if (urlParams.get("format") === "shareable") {
892
                submitForm($('#itemsearchform'));
953
                submitForm($("#itemsearchform"));
893
                $("#item-search-block").hide();
954
                $("#item-search-block").hide();
894
            }
955
            }
895
        });
956
        });
896
- 

Return to bug 41566