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: "me.holding_library_id",
445
                    data: "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: "me.home_library_id",
456
                    data: "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.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.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 1281-1440 Link Here
1281
            var table_settings = [% TablesSettings.GetTableSettings( 'catalogue', 'concerns', 'table_concerns', 'json' ) | $raw %];
1281
            var table_settings = [% TablesSettings.GetTableSettings( 'catalogue', 'concerns', 'table_concerns', 'json' ) | $raw %];
1282
            const biblio_id = "[% biblionumber | html %]";
1282
            const biblio_id = "[% biblionumber | html %]";
1283
        </script>
1283
        </script>
1284
1285
        <script>
1284
        <script>
1286
            $(document).ready(function() {
1285
            $(document).ready(function () {
1287
                $("#bibliodetails a:first").tab("show");
1286
                $("#bibliodetails a:first").tab("show");
1288
1287
1289
                let additional_filters = {
1288
                let additional_filters = {
1290
                    resolved_date: function(){
1289
                    resolved_date: function () {
1291
                        if ( $("#hide_resolved_concerns").is(":checked") ) {
1290
                        if ($("#hide_resolved_concerns").is(":checked")) {
1292
                            return { "=": null };
1291
                            return { "=": null };
1293
                        } else {
1292
                        } else {
1294
                            return;
1293
                            return;
1295
                        }
1294
                        }
1296
                    },
1295
                    },
1297
                    source: 'catalog',
1296
                    source: "catalog",
1298
                    biblio_id,
1297
                    biblio_id,
1299
                };
1298
                };
1300
                let external_filter_nodes = {
1299
                let external_filter_nodes = {
1301
                    hide_resolved_concerns: "#hide_resolved_concerns",
1300
                    hide_resolved_concerns: "#hide_resolved_concerns",
1302
                };
1301
                };
1303
1302
1304
                var tickets_url = '/api/v1/tickets';
1303
                var tickets_url = "/api/v1/tickets";
1305
                var tickets = $("#table_concerns").kohaTable({
1304
                var tickets = $("#table_concerns").kohaTable(
1306
                    ajax: {
1305
                    {
1307
                        "url": tickets_url
1306
                        ajax: {
1308
                    },
1307
                            url: tickets_url,
1309
                    embed: [
1310
                        "assignee",
1311
                        "reporter",
1312
                        "resolver",
1313
                        "biblio",
1314
                        "updates+count",
1315
                        "+strings"
1316
                    ],
1317
                    emptyTable: '<div class="alert alert-info">' + _("Congratulations, there are no catalog concerns.") + '</div>',
1318
                    columnDefs: [ {
1319
                        targets: [0,1,2,3],
1320
                        render: function (data, type, row, meta) {
1321
                            if ( type == 'display' ) {
1322
                                if ( data != null ) {
1323
                                    return data.escapeHtml();
1324
                                }
1325
                                else {
1326
                                    return "";
1327
                                }
1328
                            }
1329
                            return data;
1330
                        }
1331
                    } ],
1332
                    columns: [
1333
                        {
1334
                            data: "reported_date:reporter.firstname",
1335
                            render: function(data, type, row, meta) {
1336
                                let reported = '<div class="d-flex justify-content-between align-items-start">';
1337
                                reported += '<span class="reporter">' + $patron_to_html(row.reporter, {
1338
                                    display_cardnumber: false,
1339
                                    url: true
1340
                                }) + '</span>';
1341
                                reported += '<span class="date text-muted">' + $datetime(row.reported_date) + '</span>';
1342
                                reported += '</div>';
1343
                                return reported;
1344
                            },
1345
                            searchable: true,
1346
                            orderable: true
1347
                        },
1308
                        },
1348
                        {
1309
                        embed: ["assignee", "reporter", "resolver", "biblio", "updates+count", "+strings"],
1349
                            data: "title:body",
1310
                        emptyTable: '<div class="alert alert-info">' + _("Congratulations, there are no catalog concerns.") + "</div>",
1350
                            render: function(data, type, row, meta) {
1311
                        columnDefs: [
1351
                                let result = '<div class="d-flex justify-content-between align-items-start">';
1312
                            {
1313
                                targets: [0, 1, 2, 3],
1314
                                render: function (data, type, row, meta) {
1315
                                    if (type == "display") {
1316
                                        if (data != null) {
1317
                                            return data.escapeHtml();
1318
                                        } else {
1319
                                            return "";
1320
                                        }
1321
                                    }
1322
                                    return data;
1323
                                },
1324
                            },
1325
                        ],
1326
                        columns: [
1327
                            {
1328
                                data: "reported_date:reporter.firstname",
1329
                                render: function (data, type, row, meta) {
1330
                                    let reported = '<div class="d-flex justify-content-between align-items-start">';
1331
                                    reported +=
1332
                                        '<span class="reporter">' +
1333
                                        $patron_to_html(row.reporter, {
1334
                                            display_cardnumber: false,
1335
                                            url: true,
1336
                                        }) +
1337
                                        "</span>";
1338
                                    reported += '<span class="date text-muted">' + $datetime(row.reported_date) + "</span>";
1339
                                    reported += "</div>";
1340
                                    return reported;
1341
                                },
1342
                                searchable: true,
1343
                                orderable: true,
1344
                            },
1345
                            {
1346
                                data: "title:body",
1347
                                render: function (data, type, row, meta) {
1348
                                    let result = '<div class="d-flex justify-content-between align-items-start">';
1352
1349
1353
                                // Title link on the left
1350
                                    // Title link on the left
1354
                                result += '<a id="title_' + row.ticket_id + '" role="button" href="#" class="detail-trigger">' + row.title + '</a>';
1351
                                    result += '<a id="title_' + row.ticket_id + '" role="button" href="#" class="detail-trigger">' + row.title + "</a>";
1355
1352
1356
                                // Updates count on the right, if it exists
1353
                                    // Updates count on the right, if it exists
1357
                                if (row.updates_count) {
1354
                                    if (row.updates_count) {
1358
                                    result += '<span><a role="button" href="#" class="detail-trigger"><i class="fa fa-comment" aria-hidden="true"></i> ' + row.updates_count + '</a></span>';
1355
                                        result += '<span><a role="button" href="#" class="detail-trigger"><i class="fa fa-comment" aria-hidden="true"></i> ' + row.updates_count + "</a></span>";
1359
                                }
1356
                                    }
1360
1357
1361
                                // Hidden detail content
1358
                                    // Hidden detail content
1362
                                result += '</div>';
1359
                                    result += "</div>";
1363
                                result += '<div id="detail_' + row.ticket_id + '" style="display:none">' + row.body + '</div>';
1360
                                    result += '<div id="detail_' + row.ticket_id + '" style="display:none">' + row.body + "</div>";
1364
1361
1365
                                return result;
1362
                                    return result;
1363
                                },
1364
                                searchable: true,
1365
                                orderable: true,
1366
                            },
1366
                            },
1367
                            searchable: true,
1367
                            {
1368
                            orderable: true
1368
                                data: "biblio.title",
1369
                        },
1369
                                render: function (data, type, row, meta) {
1370
                        {
1370
                                    return $biblio_to_html(row.biblio, {
1371
                            data: "biblio.title",
1371
                                        link: 1,
1372
                            render: function(data, type, row, meta) {
1372
                                    });
1373
                                return $biblio_to_html(row.biblio, {
1373
                                },
1374
                                    link: 1
1374
                                searchable: true,
1375
                                });
1375
                                orderable: true,
1376
                            },
1376
                            },
1377
                            searchable: true,
1377
                            {
1378
                            orderable: true
1378
                                data: "assignee.firstname:assignee.surname:resolver.firstname:resolver.surname:resolved_date:status",
1379
                        },
1379
                                render: function (data, type, row, meta) {
1380
                        {
1380
                                    let result = "";
1381
                            data: "assignee.firstname:assignee.surname:resolver.firstname:resolver.surname:resolved_date:status",
1381
                                    if (row.resolved_date) {
1382
                            render: function(data, type, row, meta) {
1382
                                        result += "<div>";
1383
                                let result = '';
1383
                                        result +=
1384
                                if (row.resolved_date) {
1384
                                            _("Resolved by") +
1385
                                    result += "<div>";
1385
                                            " <span>" +
1386
                                    result += _("Resolved by") + ' <span>' + $patron_to_html(row.resolver, {
1386
                                            $patron_to_html(row.resolver, {
1387
                                        display_cardnumber: false,
1387
                                                display_cardnumber: false,
1388
                                        url: true
1388
                                                url: true,
1389
                                    }) + '</span>';
1389
                                            }) +
1390
                                    result += "</div>";
1390
                                            "</span>";
1391
                                    if (row.status) {
1391
                                        result += "</div>";
1392
                                        result += '<div>';
1392
                                        if (row.status) {
1393
                                        result += ' ' + _("as") + ' ';
1393
                                            result += "<div>";
1394
                                        result += row._strings.status ? escape_str(row._strings.status.str) : "";
1394
                                            result += " " + _("as") + " ";
1395
                                        result += '</div>';
1395
                                            result += row._strings.status ? escape_str(row._strings.status.str) : "";
1396
                                    }
1396
                                            result += "</div>";
1397
                                    result += '<div>' + $datetime(row.resolved_date) + '</div>';
1397
                                        }
1398
                                } else {
1398
                                        result += "<div>" + $datetime(row.resolved_date) + "</div>";
1399
                                    result += '<div>';
1400
                                    if (row.status) {
1401
                                        result += row._strings.status ? escape_str(row._strings.status.str) : "";
1402
                                    } else {
1399
                                    } else {
1403
                                        result += _("Open");
1400
                                        result += "<div>";
1404
                                    }
1401
                                        if (row.status) {
1405
                                    result += '</div>';
1402
                                            result += row._strings.status ? escape_str(row._strings.status.str) : "";
1406
                                    if (row.assignee) {
1403
                                        } else {
1407
                                        result += '<div>';
1404
                                            result += _("Open");
1408
                                        result += _("Assigned to: ") + ' <span>' + $patron_to_html(row.assignee, {
1405
                                        }
1409
                                            display_cardnumber: false,
1406
                                        result += "</div>";
1410
                                            url: true
1407
                                        if (row.assignee) {
1411
                                        }) + '</span>';
1408
                                            result += "<div>";
1412
                                        result += '</div>';
1409
                                            result +=
1410
                                                _("Assigned to: ") +
1411
                                                " <span>" +
1412
                                                $patron_to_html(row.assignee, {
1413
                                                    display_cardnumber: false,
1414
                                                    url: true,
1415
                                                }) +
1416
                                                "</span>";
1417
                                            result += "</div>";
1418
                                        }
1413
                                    }
1419
                                    }
1414
                                }
1420
                                    return result;
1415
                                return result;
1421
                                },
1422
                                searchable: true,
1423
                                orderable: true,
1416
                            },
1424
                            },
1417
                            searchable: true,
1425
                            {
1418
                            orderable: true
1426
                                data: function (row, type, val, meta) {
1419
                        },
1427
                                    let resolved = row.resolved_date ? true : false;
1420
                        {
1428
                                    let result =
1421
                            data: function(row, type, val, meta) {
1429
                                        '<a class="btn btn-default btn-xs main-trigger" role="button" href="#" data-bs-toggle="modal" data-bs-target="#ticketDetailsModal" data-concern="' +
1422
                                let resolved = ( row.resolved_date ) ? true : false;
1430
                                        encodeURIComponent(row.ticket_id) +
1423
                                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>';
1431
                                        '" data-resolved="' +
1424
                                return result;
1432
                                        resolved +
1433
                                        '" data-assignee="' +
1434
                                        $patron_to_html(row.assignee, { display_cardnumber: false, url: false }) +
1435
                                        '"><i class="fa-solid fa-eye" aria-hidden="true"></i> ' +
1436
                                        _("Details") +
1437
                                        "</a>";
1438
                                    return result;
1439
                                },
1440
                                searchable: false,
1441
                                orderable: false,
1425
                            },
1442
                            },
1426
                            searchable: false,
1443
                        ],
1427
                            orderable: false
1444
                    },
1428
                        },
1445
                    table_settings,
1429
                    ]
1446
                    0,
1430
                }, table_settings, 0, additional_filters, undefined, external_filter_nodes);
1447
                    additional_filters,
1448
                    undefined,
1449
                    external_filter_nodes
1450
                );
1431
1451
1432
                $('#hideResolved').on("click", function() {
1452
                $("#hideResolved").on("click", function () {
1433
                    $("#hide_resolved_concerns").prop("checked", true);
1453
                    $("#hide_resolved_concerns").prop("checked", true);
1434
                    tickets.DataTable().draw();
1454
                    tickets.DataTable().draw();
1435
                });
1455
                });
1436
1456
1437
                $('#showAll').on("click", function() {
1457
                $("#showAll").on("click", function () {
1438
                    $("#hide_resolved_concerns").prop("checked", false);
1458
                    $("#hide_resolved_concerns").prop("checked", false);
1439
                    tickets.DataTable().draw();
1459
                    tickets.DataTable().draw();
1440
                });
1460
                });
Lines 1728-1734 Link Here
1728
    [% IF Koha.Preference('EnableBooking') %]
1748
    [% IF Koha.Preference('EnableBooking') %]
1729
        [% Asset.js("js/modals/place_booking.js") | $raw %]
1749
        [% Asset.js("js/modals/place_booking.js") | $raw %]
1730
    [% END %]
1750
    [% END %]
1731
1732
    <script>
1751
    <script>
1733
        var browser;
1752
        var browser;
1734
        browser = KOHA.browser("[% searchid | html %]", parseInt(biblionumber, 10));
1753
        browser = KOHA.browser("[% searchid | html %]", parseInt(biblionumber, 10));
Lines 1748-1912 Link Here
1748
            CAN_user_editcatalogue_manage_item_groups: [% CAN_user_editcatalogue_manage_item_groups ? 1 : 0 | html %],
1767
            CAN_user_editcatalogue_manage_item_groups: [% CAN_user_editcatalogue_manage_item_groups ? 1 : 0 | html %],
1749
        });
1768
        });
1750
    </script>
1769
    </script>
1751
1752
    <script>
1770
    <script>
1753
        let items_tab_ids = [ 'holdings', 'otherholdings' ];
1771
        let items_tab_ids = ["holdings", "otherholdings"];
1754
        items_tab_ids.forEach( function( tab_id, index ) {
1772
        items_tab_ids.forEach(function (tab_id, index) {
1755
1756
            // Early return if the tab is not shown (ie. no table)
1773
            // Early return if the tab is not shown (ie. no table)
1757
            if (!$("#%s_table".format(tab_id)).length) return;
1774
            if (!$("#%s_table".format(tab_id)).length) return;
1758
            if (prefs.AlwaysShowHoldingsTableFilters){
1775
            if (prefs.AlwaysShowHoldingsTableFilters) {
1759
                build_items_table(tab_id, true, {}, build_items_table_drawncallback);
1776
                build_items_table(tab_id, true, {}, build_items_table_drawncallback);
1760
            } else {
1777
            } else {
1761
                build_items_table(tab_id, false, {}, build_items_table_drawncallback);
1778
                build_items_table(tab_id, false, {}, build_items_table_drawncallback);
1762
            }
1779
            }
1763
1780
1764
            if (prefs.bundlesEnabled){
1781
            if (prefs.bundlesEnabled) {
1765
                // Add event listener for opening and closing bundle details
1782
                // Add event listener for opening and closing bundle details
1766
                $('#' + tab_id + '_table tbody').on('click', 'button.details-control', function () {
1783
                $("#" + tab_id + "_table tbody").on("click", "button.details-control", function () {
1767
                    var button = $(this);
1784
                    var button = $(this);
1768
                    var tr = button.closest('tr');
1785
                    var tr = button.closest("tr");
1769
                    var dTable = button.closest('table').DataTable({ 'retrieve': true });
1786
                    var dTable = button.closest("table").DataTable({ retrieve: true });
1770
1787
1771
                    let row = dTable.row( tr );
1788
                    let row = dTable.row(tr);
1772
                    let data = row.data();
1789
                    let data = row.data();
1773
                    let itemnumber = data.item_id;
1790
                    let itemnumber = data.item_id;
1774
                    let duedate = (data.checkout&&data.checkout.due_date) || null;
1791
                    let duedate = (data.checkout && data.checkout.due_date) || null;
1775
1792
1776
                    if ( row.child.isShown() ) {
1793
                    if (row.child.isShown()) {
1777
                        // This row is already open - close it
1794
                        // This row is already open - close it
1778
                        row.child.hide();
1795
                        row.child.hide();
1779
                        tr.removeClass('shown');
1796
                        tr.removeClass("shown");
1780
                        button.removeClass('active');
1797
                        button.removeClass("active");
1781
                    } else {
1798
                    } else {
1782
                        // Open this row
1799
                        // Open this row
1783
                        createChild(row, itemnumber, duedate);
1800
                        createChild(row, itemnumber, duedate);
1784
                        tr.addClass('shown');
1801
                        tr.addClass("shown");
1785
                        button.addClass('active');
1802
                        button.addClass("active");
1786
                    }
1803
                    }
1787
                });
1804
                });
1788
            }
1805
            }
1789
        });
1806
        });
1790
1807
1791
        if (bundlesEnabled){ // Bundle handling
1808
        if (bundlesEnabled) {
1792
            function createChild ( row, itemnumber, duedate ) {
1809
            // Bundle handling
1810
            function createChild(row, itemnumber, duedate) {
1793
                // Toolbar
1811
                // Toolbar
1794
                var bundle_toolbar = $('<div id="toolbar" class="btn-toolbar"></div>');
1812
                var bundle_toolbar = $('<div id="toolbar" class="btn-toolbar"></div>');
1795
                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>');
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>");
1796
                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>');
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>");
1797
1815
1798
            // Toolbar
1816
                // Toolbar
1799
            var bundle_toolbar = $('<div id="toolbar" class="btn-toolbar"></div>');
1817
                var bundle_toolbar = $('<div id="toolbar" class="btn-toolbar"></div>');
1800
            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>');
1818
                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>");
1801
            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>');
1819
                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>");
1802
1820
1803
                // This is the table we'll convert into a DataTable
1821
                // This is the table we'll convert into a DataTable
1804
                var bundles_table = $('<table class="display tbundle" data-itemnumber="'+itemnumber+'" id="bundle_table_'+itemnumber+'" width="100%"/>');
1822
                var bundles_table = $('<table class="display tbundle" data-itemnumber="' + itemnumber + '" id="bundle_table_' + itemnumber + '" width="100%"/>');
1805
1823
1806
                // Display it the child row
1824
                // Display it the child row
1807
                row.child( bundle_toolbar.add(bundles_table), 'bundle' ).show();
1825
                row.child(bundle_toolbar.add(bundles_table), "bundle").show();
1808
1826
1809
                // Initialise as a DataTable
1827
                // Initialise as a DataTable
1810
                var bundle_table_url = "/api/v1/items/" + itemnumber + "/bundled_items?";
1828
                var bundle_table_url = "/api/v1/items/" + itemnumber + "/bundled_items?";
1811
                var bundle_table = bundles_table.kohaTable({
1829
                var bundle_table = bundles_table.kohaTable(
1812
                    "ajax": {
1830
                    {
1813
                        "url": bundle_table_url
1831
                        ajax: {
1814
                    },
1832
                            url: bundle_table_url,
1815
                    "embed": [
1816
                        "biblio",
1817
                        "return_claim.patron"
1818
                    ],
1819
                    "order": [[ 1, "asc" ]],
1820
                    "columnDefs": [ {
1821
                        "targets": [0,1,2,3],
1822
                        "render": function (data, type, row, meta) {
1823
                            if ( data && type == 'display' ) {
1824
                                return data.escapeHtml();
1825
                            }
1826
                            return data;
1827
                        }
1828
                    } ],
1829
                    "columns": [
1830
                        {
1831
                            "data": "biblio.title:biblio.subtitle:biblio.medium",
1832
                            "title": _("Title"),
1833
                            "searchable": true,
1834
                            "orderable": true,
1835
                            "render": function(data, type, row, meta) {
1836
                                return $biblio_to_html(row.biblio, { link: 1 });
1837
                            }
1838
                        },
1839
                        {
1840
                            "data": "biblio.author",
1841
                            "title": _("Author"),
1842
                            "searchable": true,
1843
                            "orderable": true,
1844
                        },
1845
                        {
1846
                            "data": "copy_number",
1847
                            "title": _("Copy number"),
1848
                            "searchable": true,
1849
                            "orderable": true,
1850
                        },
1851
                        {
1852
                            "data": "callnumber",
1853
                            "title": _("Callnumber"),
1854
                            "searchable": true,
1855
                            "orderable": true,
1856
                        },
1857
                        {
1858
                            "data": "external_id",
1859
                            "title": _("Barcode"),
1860
                            "searchable": true,
1861
                            "orderable": true,
1862
                        },
1833
                        },
1863
                        {
1834
                        embed: ["biblio", "return_claim.patron"],
1864
                            "data": "lost_status:last_seen_date:return_claim.patron",
1835
                        order: [[1, "asc"]],
1865
                            "title": _("Status"),
1836
                        columnDefs: [
1866
                            "searchable": false,
1837
                            {
1867
                            "orderable": false,
1838
                                targets: [0, 1, 2, 3],
1868
                            "render": function(data, type, row, meta) {
1839
                                render: function (data, type, row, meta) {
1869
                                if ( row.lost_status == prefs.BundleLostValue ) {
1840
                                    if (data && type == "display") {
1870
                                    let out = '<span class="lost">' + _("Last seen") + ': ' + $date(row.last_seen_date) + '</span>';
1841
                                        return data.escapeHtml();
1871
                                    if ( row.return_claim ) {
1872
                                        out = out + '<span class="claims_return">' + _("Claims returned by") + ': ' + $patron_to_html( row.return_claim.patron, { display_cardnumber: false, url: true } ) + '</span>';
1873
                                    }
1842
                                    }
1874
                                    return out;
1843
                                    return data;
1875
                                }
1844
                                },
1876
                                else if ( row.lost_status !== 0 ) {
1877
                                    return '<span class="lost">' + _("Lost") + ': ' + row.lost_status + '</span>';
1878
                                }
1879
                                return '<span class="available">' + _("Present") + '</span>';
1880
                            }
1881
                        },
1882
                        {
1883
                            "data": function( row, type, val, meta ) {
1884
                                var result;
1885
                                if (duedate) {
1886
                                    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"));
1887
                                } else {
1888
                                    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';
1889
                                }
1890
                                return result;
1891
                            },
1845
                            },
1892
                            "title": _("Actions"),
1846
                        ],
1893
                            "searchable": false,
1847
                        columns: [
1894
                            "orderable": false,
1848
                            {
1895
                            "class": "no-export"
1849
                                data: "biblio.title:biblio.subtitle:biblio.medium",
1896
                        }
1850
                                title: _("Title"),
1897
                    ]
1851
                                searchable: true,
1898
                }, bundle_settings, 1);
1852
                                orderable: true,
1899
                $(".tbundle").on("click", ".remove:not(.disabled)", function(){
1853
                                render: function (data, type, row, meta) {
1900
                    var bundle_table = $(this).closest('table');
1854
                                    return $biblio_to_html(row.biblio, { link: 1 });
1901
                    var host_itemnumber = bundle_table.data('itemnumber');
1855
                                },
1902
                    var component_itemnumber = $(this).data('itemnumber');
1856
                            },
1857
                            {
1858
                                data: "biblio.author",
1859
                                title: _("Author"),
1860
                                searchable: true,
1861
                                orderable: true,
1862
                            },
1863
                            {
1864
                                data: "copy_number",
1865
                                title: _("Copy number"),
1866
                                searchable: true,
1867
                                orderable: true,
1868
                            },
1869
                            {
1870
                                data: "callnumber",
1871
                                title: _("Callnumber"),
1872
                                searchable: true,
1873
                                orderable: true,
1874
                            },
1875
                            {
1876
                                data: "external_id",
1877
                                title: _("Barcode"),
1878
                                searchable: true,
1879
                                orderable: true,
1880
                            },
1881
                            {
1882
                                data: "lost_status:last_seen_date:return_claim.patron",
1883
                                title: _("Status"),
1884
                                searchable: false,
1885
                                orderable: false,
1886
                                render: function (data, type, row, meta) {
1887
                                    if (row.lost_status == prefs.BundleLostValue) {
1888
                                        let out = '<span class="lost">' + _("Last seen") + ": " + $date(row.last_seen_date) + "</span>";
1889
                                        if (row.return_claim) {
1890
                                            out = out + '<span class="claims_return">' + _("Claims returned by") + ": " + $patron_to_html(row.return_claim.patron, { display_cardnumber: false, url: true }) + "</span>";
1891
                                        }
1892
                                        return out;
1893
                                    } else if (row.lost_status !== 0) {
1894
                                        return '<span class="lost">' + _("Lost") + ": " + row.lost_status + "</span>";
1895
                                    }
1896
                                    return '<span class="available">' + _("Present") + "</span>";
1897
                                },
1898
                            },
1899
                            {
1900
                                data: function (row, type, val, meta) {
1901
                                    var result;
1902
                                    if (duedate) {
1903
                                        result =
1904
                                            '<button class="btn btn-default btn-xs remove disabled" role="button" data-itemnumber="' +
1905
                                            row.item_id +
1906
                                            '" 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"));
1907
                                    } else {
1908
                                        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";
1909
                                    }
1910
                                    return result;
1911
                                },
1912
                                title: _("Actions"),
1913
                                searchable: false,
1914
                                orderable: false,
1915
                                class: "no-export",
1916
                            },
1917
                        ],
1918
                    },
1919
                    bundle_settings,
1920
                    1
1921
                );
1922
                $(".tbundle").on("click", ".remove:not(.disabled)", function () {
1923
                    var bundle_table = $(this).closest("table");
1924
                    var host_itemnumber = bundle_table.data("itemnumber");
1925
                    var component_itemnumber = $(this).data("itemnumber");
1903
                    var unlink_item_url = "/api/v1/items/" + host_itemnumber + "/bundled_items/" + component_itemnumber;
1926
                    var unlink_item_url = "/api/v1/items/" + host_itemnumber + "/bundled_items/" + component_itemnumber;
1904
                    $.ajax({
1927
                    $.ajax({
1905
                        type: "DELETE",
1928
                        type: "DELETE",
1906
                        url: unlink_item_url,
1929
                        url: unlink_item_url,
1907
                        success: function(){
1930
                        success: function () {
1908
                            bundle_table.DataTable({ 'retrieve': true }).draw(false);
1931
                            bundle_table.DataTable({ retrieve: true }).draw(false);
1909
                        }
1932
                        },
1910
                    });
1933
                    });
1911
                });
1934
                });
1912
1935
Lines 1915-2004 Link Here
1915
1938
1916
            var bundle_changed;
1939
            var bundle_changed;
1917
            var bundle_form_active;
1940
            var bundle_form_active;
1918
            $("#addToBundleModal").on("shown.bs.modal", function(e){
1941
            $("#addToBundleModal").on("shown.bs.modal", function (e) {
1919
                var button = $(e.relatedTarget);
1942
                var button = $(e.relatedTarget);
1920
                var item_id = button.data('item');
1943
                var item_id = button.data("item");
1921
                $("#addResult").replaceWith('<div id="addResult"></div>');
1944
                $("#addResult").replaceWith('<div id="addResult"></div>');
1922
                $("#addToBundleForm").attr('action', '/api/v1/items/' + item_id + '/bundled_items');
1945
                $("#addToBundleForm").attr("action", "/api/v1/items/" + item_id + "/bundled_items");
1923
                $("#external_id").focus();
1946
                $("#external_id").focus();
1924
                bundle_changed = 0;
1947
                bundle_changed = 0;
1925
                bundle_form_active = item_id;
1948
                bundle_form_active = item_id;
1926
            });
1949
            });
1927
1950
1928
            function addToBundle (url, data) {
1951
            function addToBundle(url, data) {
1929
                /* Send the data using post with external_id */
1952
                /* Send the data using post with external_id */
1930
                var posting = $.post({
1953
                var posting = $.post({
1931
                    url: url,
1954
                    url: url,
1932
                    data: JSON.stringify(data),
1955
                    data: JSON.stringify(data),
1933
                    contentType: "application/json; charset=utf-8",
1956
                    contentType: "application/json; charset=utf-8",
1934
                    dataType: "json"
1957
                    dataType: "json",
1935
                });
1958
                });
1936
1959
1937
                const barcode = data.external_id;
1960
                const barcode = data.external_id;
1938
                const marc_link = data.marc_link;
1961
                const marc_link = data.marc_link;
1939
1962
1940
                /* Report the results */
1963
                /* Report the results */
1941
                posting.done(function(data) {
1964
                posting.done(function (data) {
1942
                    $('#addResult').replaceWith('<div id="addResult" class="alert alert-success">'+_("Success: Added '%s'").format(barcode)+'</div>');
1965
                    $("#addResult").replaceWith('<div id="addResult" class="alert alert-success">' + _("Success: Added '%s'").format(barcode) + "</div>");
1943
                    $('#external_id').val('').focus();
1966
                    $("#external_id").val("").focus();
1944
                    bundle_changed = 1;
1967
                    bundle_changed = 1;
1945
                });
1968
                });
1946
                posting.fail(function(data) {
1969
                posting.fail(function (data) {
1947
                    if ( data.status === 409 ) {
1970
                    if (data.status === 409) {
1948
                        var response = data.responseJSON;
1971
                        var response = data.responseJSON;
1949
                        if ( response.error_code === 'already_bundled' ) {
1972
                        if (response.error_code === "already_bundled") {
1950
                            $('#addResult').replaceWith('<div id="addResult" class="alert alert-warning">'+_("Warning: Item '%s' already attached").format(barcode)+'</div>');
1973
                            $("#addResult").replaceWith('<div id="addResult" class="alert alert-warning">' + _("Warning: Item '%s' already attached").format(barcode) + "</div>");
1951
                        } else if (response.error_code === 'bundle_checkout_out') {
1974
                        } else if (response.error_code === "bundle_checkout_out") {
1952
                            $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Bundle is currently checked out")+'</div>');
1975
                            $("#addResult").replaceWith('<div id="addResult" class="alert alert-danger">' + _("Failure: Bundle is currently checked out") + "</div>");
1953
                        } else if (response.error_code === 'checked_out') {
1976
                        } else if (response.error_code === "checked_out") {
1954
                            const button = $('<button type="button">')
1977
                            const button = $('<button type="button">')
1955
                                .addClass('btn btn-xs')
1978
                                .addClass("btn btn-xs")
1956
                                .text(_("Check in and add to bundle"))
1979
                                .text(_("Check in and add to bundle"))
1957
                                .on('click', function () {
1980
                                .on("click", function () {
1958
                                    addToBundle(url, { external_id: barcode, force_checkin: true, marc_link: marc_link });
1981
                                    addToBundle(url, { external_id: barcode, force_checkin: true, marc_link: marc_link });
1959
                                });
1982
                                });
1960
                            $('#addResult')
1983
                            $("#addResult").empty().attr("class", "alert alert-warning").append(__x("Warning: Item {barcode} is checked out", { barcode })).append(" ", button);
1961
                                .empty()
1984
                        } else if (response.error_code === "failed_checkin") {
1962
                                .attr('class', 'alert alert-warning')
1985
                            $("#addResult").empty().attr("class", "alert alert-danger").append(__x("Failure: Item {barcode} cannot be checked in", { barcode }));
1963
                                .append(__x('Warning: Item {barcode} is checked out', { barcode }))
1986
                        } else if (response.error_code === "reserved") {
1964
                                .append(' ', button);
1965
                        } else if (response.error_code === 'failed_checkin') {
1966
                            $('#addResult')
1967
                                .empty()
1968
                                .attr('class', 'alert alert-danger')
1969
                                .append(__x('Failure: Item {barcode} cannot be checked in', { barcode }))
1970
                        } else if (response.error_code === 'reserved') {
1971
                            const button = $('<button type="button">')
1987
                            const button = $('<button type="button">')
1972
                                .addClass('btn btn-xs')
1988
                                .addClass("btn btn-xs")
1973
                                .text(_("Ignore holds and add to bundle"))
1989
                                .text(_("Ignore holds and add to bundle"))
1974
                                .on('click', function () {
1990
                                .on("click", function () {
1975
                                    addToBundle(url, { external_id: barcode, ignore_holds: true, marc_link: marc_link });
1991
                                    addToBundle(url, { external_id: barcode, ignore_holds: true, marc_link: marc_link });
1976
                                });
1992
                                });
1977
                            $('#addResult')
1993
                            $("#addResult").empty().attr("class", "alert alert-warning").append(__x("Warning: Item {barcode} is on hold", { barcode })).append(" ", button);
1978
                                .empty()
1979
                                .attr('class', 'alert alert-warning')
1980
                                .append(__x('Warning: Item {barcode} is on hold', { barcode }))
1981
                                .append(' ', button);
1982
                        } else {
1994
                        } else {
1983
                            $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Item '%s' belongs to another bundle").format(barcode)+'</div>');
1995
                            $("#addResult").replaceWith('<div id="addResult" class="alert alert-danger">' + _("Failure: Item '%s' belongs to another bundle").format(barcode) + "</div>");
1984
                        }
1996
                        }
1985
                    } else if ( data.status === 404 ) {
1997
                    } else if (data.status === 404) {
1986
                        $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Item '%s' not found").format(barcode)+'</div>');
1998
                        $("#addResult").replaceWith('<div id="addResult" class="alert alert-danger">' + _("Failure: Item '%s' not found").format(barcode) + "</div>");
1987
                    } else if ( data.status === 400 ) {
1999
                    } else if (data.status === 400) {
1988
                        var response = data.responseJSON;
2000
                        var response = data.responseJSON;
1989
                        if ( response.error_code === "failed_nesting" ) {
2001
                        if (response.error_code === "failed_nesting") {
1990
                            $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Item '%s' is a bundle and bundles cannot be nested").format(barcode)+'</div>');
2002
                            $("#addResult").replaceWith('<div id="addResult" class="alert alert-danger">' + _("Failure: Item '%s' is a bundle and bundles cannot be nested").format(barcode) + "</div>");
1991
                        } else {
2003
                        } else {
1992
                            $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Check the logs for details.")+'</div>');
2004
                            $("#addResult").replaceWith('<div id="addResult" class="alert alert-danger">' + _("Failure: Check the logs for details.") + "</div>");
1993
                        }
2005
                        }
1994
                    } else {
2006
                    } else {
1995
                        $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Check the logs for details.")+'</div>');
2007
                        $("#addResult").replaceWith('<div id="addResult" class="alert alert-danger">' + _("Failure: Check the logs for details.") + "</div>");
1996
                    }
2008
                    }
1997
                    $('#external_id').val('').focus();
2009
                    $("#external_id").val("").focus();
1998
                });
2010
                });
1999
            }
2011
            }
2000
2012
2001
            $("#addToBundleForm").submit(function(event) {
2013
            $("#addToBundleForm").submit(function (event) {
2002
                /* stop form from submitting normally */
2014
                /* stop form from submitting normally */
2003
                event.preventDefault();
2015
                event.preventDefault();
2004
2016
Lines 2008-2096 Link Here
2008
                addToBundle(url, data);
2020
                addToBundle(url, data);
2009
            });
2021
            });
2010
2022
2011
            $("#addToBundleModal").on("hidden.bs.modal", function(e){
2023
            $("#addToBundleModal").on("hidden.bs.modal", function (e) {
2012
                if ( bundle_changed ) {
2024
                if (bundle_changed) {
2013
                    $('#bundle_table_'+bundle_form_active).DataTable({ 'retrieve': true }).ajax.reload();
2025
                    $("#bundle_table_" + bundle_form_active)
2026
                        .DataTable({ retrieve: true })
2027
                        .ajax.reload();
2014
                }
2028
                }
2015
                bundle_form_active = 0;
2029
                bundle_form_active = 0;
2016
                bundle_changed = 0;
2030
                bundle_changed = 0;
2017
            });
2031
            });
2018
2032
2019
            $("#removeFromBundleModal").on("shown.bs.modal", function(e){
2033
            $("#removeFromBundleModal").on("shown.bs.modal", function (e) {
2020
                var button = $(e.relatedTarget);
2034
                var button = $(e.relatedTarget);
2021
                var item_id = button.data('item');
2035
                var item_id = button.data("item");
2022
                $("#removeResult").replaceWith('<div id="removeResult"></div>');
2036
                $("#removeResult").replaceWith('<div id="removeResult"></div>');
2023
                $("#removeFromBundleForm").attr('action', '/api/v1/items/' + item_id + '/bundled_items/');
2037
                $("#removeFromBundleForm").attr("action", "/api/v1/items/" + item_id + "/bundled_items/");
2024
                $("#rm_external_id").focus();
2038
                $("#rm_external_id").focus();
2025
                bundle_changed = 0;
2039
                bundle_changed = 0;
2026
                bundle_form_active = item_id;
2040
                bundle_form_active = item_id;
2027
            });
2041
            });
2028
2042
2029
            $("#removeFromBundleForm").submit(function(event) {
2043
            $("#removeFromBundleForm").submit(function (event) {
2030
2031
                /* stop form from submitting normally */
2044
                /* stop form from submitting normally */
2032
                event.preventDefault();
2045
                event.preventDefault();
2033
2046
2034
                /* get the action attribute from the <form action=""> element */
2047
                /* get the action attribute from the <form action=""> element */
2035
                var $form = $(this),
2048
                var $form = $(this),
2036
                url = $form.attr('action');
2049
                    url = $form.attr("action");
2037
2050
2038
                var barcode = $('#rm_external_id').val();
2051
                var barcode = $("#rm_external_id").val();
2039
2052
2040
                /* Fetch itemnumber using rm_external_id */
2053
                /* Fetch itemnumber using rm_external_id */
2041
                var itemReq = $.get('/api/v1/items', { q: JSON.stringify({
2054
                var itemReq = $.get(
2042
                    external_id: barcode
2055
                    "/api/v1/items",
2043
                }) }, null, "json");
2056
                    {
2057
                        q: JSON.stringify({
2058
                            external_id: barcode,
2059
                        }),
2060
                    },
2061
                    null,
2062
                    "json"
2063
                );
2044
2064
2045
                var itemnumber;
2065
                var itemnumber;
2046
                itemReq.done(function(data) {
2066
                itemReq.done(function (data) {
2047
                    if (data.length === 1) {
2067
                    if (data.length === 1) {
2048
                        itemnumber = data[0].item_id;
2068
                        itemnumber = data[0].item_id;
2049
2069
2050
                        /* Remove link using fetch itemnumber */
2070
                        /* Remove link using fetch itemnumber */
2051
                        var deleteReq = $.ajax( url + itemnumber, {
2071
                        var deleteReq = $.ajax(url + itemnumber, {
2052
                            type : 'DELETE'
2072
                            type: "DELETE",
2053
                        });
2073
                        });
2054
2074
2055
                        /* Report the results */
2075
                        /* Report the results */
2056
                        deleteReq.done(function(data) {
2076
                        deleteReq.done(function (data) {
2057
                            var barcode = $('#rm_external_id').val();
2077
                            var barcode = $("#rm_external_id").val();
2058
                            $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-success">'+_("Success: Removed '%s'").format(barcode)+'</div>');
2078
                            $("#removeResult").replaceWith('<div id="removeResult" class="alert alert-success">' + _("Success: Removed '%s'").format(barcode) + "</div>");
2059
                            $('#rm_external_id').val('').focus();
2079
                            $("#rm_external_id").val("").focus();
2060
                            bundle_changed = 1;
2080
                            bundle_changed = 1;
2061
                        });
2081
                        });
2062
                        deleteReq.fail(function(data) {
2082
                        deleteReq.fail(function (data) {
2063
                            var barcode = $('#rm_external_id').val();
2083
                            var barcode = $("#rm_external_id").val();
2064
                            if ( data.status === 409 ) {
2084
                            if (data.status === 409) {
2065
                                var response = data.responseJSON;
2085
                                var response = data.responseJSON;
2066
                                if (response.error_code === 'bundle_checkout_out') {
2086
                                if (response.error_code === "bundle_checkout_out") {
2067
                                    $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failure: Bundle is currently checked out")+'</div>');
2087
                                    $("#removeResult").replaceWith('<div id="removeResult" class="alert alert-danger">' + _("Failure: Bundle is currently checked out") + "</div>");
2068
                                } else if ( response.key === "PRIMARY" ) {
2088
                                } else if (response.key === "PRIMARY") {
2069
                                    $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-warning">'+_("Warning: Item '%s' already attached").format(barcode)+'</div>');
2089
                                    $("#removeResult").replaceWith('<div id="removeResult" class="alert alert-warning">' + _("Warning: Item '%s' already attached").format(barcode) + "</div>");
2070
                                } else {
2090
                                } else {
2071
                                    $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failure: Item '%s' belongs to another bundle").format(barcode)+'</div>');
2091
                                    $("#removeResult").replaceWith('<div id="removeResult" class="alert alert-danger">' + _("Failure: Item '%s' belongs to another bundle").format(barcode) + "</div>");
2072
                                }
2092
                                }
2073
                            } else if ( data.status === 404 ) {
2093
                            } else if (data.status === 404) {
2074
                                $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Item '%s' not found").format(barcode)+'</div>');
2094
                                $("#addResult").replaceWith('<div id="addResult" class="alert alert-danger">' + _("Failure: Item '%s' not found").format(barcode) + "</div>");
2075
                            } else {
2095
                            } else {
2076
                                $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failure: Check the logs for details")+'</div>');
2096
                                $("#removeResult").replaceWith('<div id="removeResult" class="alert alert-danger">' + _("Failure: Check the logs for details") + "</div>");
2077
                            }
2097
                            }
2078
                            $('#rm_external_id').val('').focus();
2098
                            $("#rm_external_id").val("").focus();
2079
                        });
2099
                        });
2080
                    } else {
2100
                    } else {
2081
                        $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failed: Barcode matched more than one item '%s'").format(barcode)+'</div>');
2101
                        $("#removeResult").replaceWith('<div id="removeResult" class="alert alert-danger">' + _("Failed: Barcode matched more than one item '%s'").format(barcode) + "</div>");
2082
                    }
2102
                    }
2083
                });
2103
                });
2084
                itemReq.fail(function(data) {
2104
                itemReq.fail(function (data) {
2085
                    $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failed: Item not found '%s'").format(barcode)+'</div>');
2105
                    $("#removeResult").replaceWith('<div id="removeResult" class="alert alert-danger">' + _("Failed: Item not found '%s'").format(barcode) + "</div>");
2086
                    $('#rm_external_id').val('').focus();
2106
                    $("#rm_external_id").val("").focus();
2087
2088
                });
2107
                });
2089
            });
2108
            });
2090
2109
2091
            $("#removeFromBundleModal").on("hidden.bs.modal", function(e){
2110
            $("#removeFromBundleModal").on("hidden.bs.modal", function (e) {
2092
                if ( bundle_changed ) {
2111
                if (bundle_changed) {
2093
                    $('#bundle_table_'+bundle_form_active).DataTable({ 'retrieve': true }).ajax.reload();
2112
                    $("#bundle_table_" + bundle_form_active)
2113
                        .DataTable({ retrieve: true })
2114
                        .ajax.reload();
2094
                }
2115
                }
2095
                bundle_form_active = 0;
2116
                bundle_form_active = 0;
2096
                bundle_changed = 0;
2117
                bundle_changed = 0;
Lines 2098-2111 Link Here
2098
            // End bundle handling
2119
            // End bundle handling
2099
        }
2120
        }
2100
    </script>
2121
    </script>
2101
2102
    [% IF Koha.Preference('AcquisitionDetails') %]
2122
    [% IF Koha.Preference('AcquisitionDetails') %]
2103
        <script>
2123
        <script>
2104
            var table_settings = [% TablesSettings.GetTableSettings('catalogue', 'detail', 'acquisitiondetails-table', 'json') | $raw %];
2124
            var table_settings = [% TablesSettings.GetTableSettings('catalogue', 'detail', 'acquisitiondetails-table', 'json') | $raw %];
2105
        </script>
2125
        </script>
2106
2107
        <script>
2126
        <script>
2108
            $(document).ready(function() {
2127
            $(document).ready(function () {
2109
                var acquisitiondetails_table = $("#orders").kohaTable(
2128
                var acquisitiondetails_table = $("#orders").kohaTable(
2110
                    {
2129
                    {
2111
                        dom: 'C<"top pager"ilpfB><"#filter_c">tr<"bottom pager"ip>',
2130
                        dom: 'C<"top pager"ilpfB><"#filter_c">tr<"bottom pager"ip>',
Lines 2121-2127 Link Here
2121
2140
2122
    [% IF suggestions.count %]
2141
    [% IF suggestions.count %]
2123
        <script>
2142
        <script>
2124
            $(document).ready(function() {
2143
            $(document).ready(function () {
2125
                $("#suggestions").kohaTable({
2144
                $("#suggestions").kohaTable({
2126
                    pagingType: "full",
2145
                    pagingType: "full",
2127
                });
2146
                });
Lines 2133-2142 Link Here
2133
        <script>
2152
        <script>
2134
            var comment_table_settings = [% TablesSettings.GetTableSettings('catalogue', 'detail', 'comments-table', 'json') | $raw %];
2153
            var comment_table_settings = [% TablesSettings.GetTableSettings('catalogue', 'detail', 'comments-table', 'json') | $raw %];
2135
        </script>
2154
        </script>
2136
2137
        <script>
2155
        <script>
2138
            $(document).ready(function() {
2156
            $(document).ready(function () {
2139
2140
                var comments_table = $("#comments_table").kohaTable(
2157
                var comments_table = $("#comments_table").kohaTable(
2141
                    {
2158
                    {
2142
                        paging: false,
2159
                        paging: false,
Lines 2151-2414 Link Here
2151
2168
2152
    [% IF found1 && Koha.Preference('RetainCatalogSearchTerms') %]
2169
    [% IF found1 && Koha.Preference('RetainCatalogSearchTerms') %]
2153
        <script>
2170
        <script>
2154
            $(document).ready(function() {
2171
            $(document).ready(function () {
2155
                var search_index = localStorage.getItem("cat_search_pulldown_selection");
2172
                var search_index = localStorage.getItem("cat_search_pulldown_selection");
2156
                var search_value = localStorage.getItem("searchbox_value");
2173
                var search_value = localStorage.getItem("searchbox_value");
2157
                if ( search_index ){ $('#cat-search-block select.advsearch').val(search_index)};
2174
                if (search_index) {
2158
                if ( search_value ){ $('#cat-search-block #search-form').val(search_value)};
2175
                    $("#cat-search-block select.advsearch").val(search_index);
2176
                }
2177
                if (search_value) {
2178
                    $("#cat-search-block #search-form").val(search_value);
2179
                }
2159
            });
2180
            });
2160
        </script>
2181
        </script>
2161
    [% END %]
2182
    [% END %]
2162
2183
2163
    [% IF Koha.Preference('EnableItemGroups') %]
2184
    [% IF Koha.Preference('EnableItemGroups') %]
2164
        <script>
2185
        <script>
2165
            $(document).ready(function() {
2186
            $(document).ready(function () {
2166
2187
                // Load item groups table
2167
            // Load item groups table
2188
                var itemGroupsTable = $("#items-group-table").kohaTable({
2168
            var itemGroupsTable = $("#items-group-table").kohaTable({
2189
                    autoWidth: false,
2169
                autoWidth: false,
2190
                    dom: '<"top pager"ilp>t<"bottom pager"ip>r',
2170
                dom: '<"top pager"ilp>t<"bottom pager"ip>r',
2191
                    columns: [
2171
                columns: [
2192
                        {
2172
                    {
2193
                            data: "display_order",
2173
                        data: "display_order",
2194
                            title: _("Display order"),
2174
                        title: _("Display order"),
2195
                            searchable: true,
2175
                        searchable: true,
2196
                            orderable: true,
2176
                        orderable: true,
2197
                        },
2177
                    },
2198
                        {
2178
                    {
2199
                            data: "description",
2179
                        data: "description",
2200
                            title: _("Description"),
2180
                        title: _("Description"),
2201
                            searchable: true,
2181
                        searchable: true,
2202
                            orderable: true,
2182
                        orderable: true,
2203
                        },
2183
                    },
2204
                        {
2184
                    {
2205
                            data: function (oObj) {
2185
                        data: function( oObj ) {
2206
                                if (permissions.CAN_user_editcatalogue_manage_item_groups) {
2186
                            if (permissions.CAN_user_editcatalogue_manage_item_groups){
2207
                                    return (
2187
                                return `<button class='item-group-edit btn btn-default btn-xs' data-item-group-id='${oObj.item_group_id}'>
2208
                                        `<button class='item-group-edit btn btn-default btn-xs' data-item-group-id='${oObj.item_group_id}'>
2188
                                    <i class="fa-solid fa-pencil" aria-hidden="true"></i> ${_("Edit")}
2209
                                    <i class="fa-solid fa-pencil" aria-hidden="true"></i> ${_("Edit")}
2210
                                </button>` +
2211
                                        "&nbsp" +
2212
                                        `<button class='item-group-delete btn btn-default btn-xs' data-item-group-id='${oObj.item_group_id}'>
2213
                                    <i class='fa fa-trash-can'></i> ${"Delete"}
2189
                                </button>`
2214
                                </button>`
2190
                                + '&nbsp'
2215
                                    );
2191
                                + `<button class='item-group-delete btn btn-default btn-xs' data-item-group-id='${oObj.item_group_id}'>
2216
                                } else {
2192
                                    <i class='fa fa-trash-can'></i> ${('Delete')}
2217
                                    return "";
2193
                                </button>`;
2218
                                }
2194
                            } else {
2219
                            },
2195
                                return "";
2220
                            searchable: false,
2196
                            }
2221
                            orderable: false,
2197
                        },
2222
                        },
2198
                        searchable: false,
2223
                    ],
2199
                        orderable: false,
2224
                    paging: false,
2225
                    ajax: { url: `/api/v1/biblios/${biblionumber}/item_groups?_per_page=-1` },
2226
                });
2227
2228
                // Create new item groups
2229
                $(".item-group-create").on("click", function () {
2230
                    $("#modal-item-group-create-form-description").val("");
2231
                    $("#modal-item-group-create-submit").removeAttr("disabled");
2232
                    $("#modal-item-group-create").modal("show");
2233
                });
2234
2235
                $("#modal-item-group-create-form").validate({
2236
                    submitHandler: function (form) {
2237
                        $.ajax({
2238
                            url: `/api/v1/biblios/${biblionumber}/item_groups`,
2239
                            headers: { "x-koha-embed": "items" },
2240
                            success: function (item_groups) {
2241
                                $("#modal-item-group-create-submit").attr("disabled", "disabled");
2242
2243
                                var settings = {
2244
                                    url: `/api/v1/biblios/${biblionumber}/item_groups`,
2245
                                    method: "POST",
2246
                                    headers: {
2247
                                        "Content-Type": "application/json",
2248
                                    },
2249
                                    data: JSON.stringify({
2250
                                        description: $("#modal-item-group-create-form-description").val(),
2251
                                        display_order: $("#modal-item-group-create-form-display_order").val(),
2252
                                    }),
2253
                                };
2254
2255
                                $.ajax(settings)
2256
                                    .done(function (response) {
2257
                                        $("#item-group-add-form-select").append(
2258
                                            $("<option>", {
2259
                                                value: response.item_group_id,
2260
                                                text: response.description,
2261
                                            })
2262
                                        );
2263
2264
                                        $("#modal-item-group-create").modal("hide");
2265
                                        if (item_groups.length == 0) {
2266
                                            // This bib has no previous item groups, reload the page
2267
                                            window.location.replace(`/cgi-bin/koha/catalogue/detail.pl?biblionumber=${biblionumber}`);
2268
                                        } else {
2269
                                            // Has other item groups, just reload the table
2270
                                            itemGroupsTable.api().ajax.reload();
2271
                                        }
2272
                                    })
2273
                                    .fail(function (err) {
2274
                                        var message = err.responseJSON.error;
2275
                                        alert(message);
2276
                                    });
2277
                            },
2278
                        });
2200
                    },
2279
                    },
2201
                ],
2280
                });
2202
                paging: false,
2203
                ajax: { url: `/api/v1/biblios/${biblionumber}/item_groups?_per_page=-1` },
2204
            });
2205
2281
2206
            // Create new item groups
2282
                $("#modal-item-group-create").on("shown.bs.modal", function () {
2207
            $('.item-group-create').on('click', function(){
2283
                    $("#modal-item-group-create-form-description").focus();
2208
                $('#modal-item-group-create-form-description').val("");
2284
                });
2209
                $('#modal-item-group-create-submit').removeAttr('disabled');
2210
                $('#modal-item-group-create').modal('show');
2211
            });
2212
2285
2213
            $("#modal-item-group-create-form").validate({
2286
                // Edit existing item groups
2214
                submitHandler: function(form) {
2287
                $("body").on("click", ".item-group-edit", function () {
2215
                    $.ajax({
2288
                    const item_group_id = $(this).data("item-group-id");
2216
                        url: `/api/v1/biblios/${biblionumber}/item_groups`,
2289
                    const url = `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`;
2217
                        headers: { "x-koha-embed": "items" },
2290
                    $.get(url, function (data) {
2218
                        success: function(item_groups){
2291
                        $("#modal-item-group-edit-form-description").val(data.description);
2219
                            $('#modal-item-group-create-submit').attr('disabled', 'disabled');
2292
                        $("#modal-item-group-edit-form-display_order").val(data.display_order);
2220
2293
                        $("#modal-item-group-edit-submit").data("item-group-id", item_group_id);
2221
                            var settings = {
2294
                        $("#modal-item-group-edit-submit").removeAttr("disabled");
2222
                              "url": `/api/v1/biblios/${biblionumber}/item_groups`,
2295
                        $("#modal-item-group-edit").modal("show");
2223
                              "method": "POST",
2296
                    });
2224
                              "headers": {
2297
                });
2225
                                "Content-Type": "application/json"
2298
2226
                              },
2299
                $("#modal-item-group-edit-form").validate({
2227
                              "data": JSON.stringify(
2300
                    submitHandler: function (form) {
2228
                                  {
2301
                        $("#modal-item-group-edit-submit").attr("disabled", "disabled");
2229
                                      "description": $("#modal-item-group-create-form-description").val(),
2302
2230
                                      "display_order": $("#modal-item-group-create-form-display_order").val(),
2303
                        const item_group_id = $("#modal-item-group-edit-submit").data("item-group-id");
2231
                                  }
2304
                        const url = `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`;
2232
                              ),
2305
2233
                            };
2306
                        var settings = {
2234
2307
                            url: url,
2235
                            $.ajax(settings)
2308
                            method: "PUT",
2309
                            headers: {
2310
                                "Content-Type": "application/json",
2311
                            },
2312
                            data: JSON.stringify({
2313
                                description: $("#modal-item-group-edit-form-description").val(),
2314
                                display_order: $("#modal-item-group-edit-form-display_order").val(),
2315
                            }),
2316
                        };
2317
2318
                        $.ajax(settings)
2236
                            .done(function (response) {
2319
                            .done(function (response) {
2237
                                $('#item-group-add-form-select').append($('<option>', {
2320
                                $("#modal-item-group-edit").modal("hide");
2238
                                    value: response.item_group_id,
2321
                                itemGroupsTable.api().ajax.reload();
2239
                                    text: response.description
2240
                                }));
2241
2242
                                $('#modal-item-group-create').modal('hide');
2243
                                if ( item_groups.length == 0 ) {
2244
                                    // This bib has no previous item groups, reload the page
2245
                                    window.location.replace(`/cgi-bin/koha/catalogue/detail.pl?biblionumber=${biblionumber}`);
2246
                                } else {
2247
                                    // Has other item groups, just reload the table
2248
                                    itemGroupsTable.api().ajax.reload();
2249
                                }
2250
                            })
2322
                            })
2251
                            .fail(function(err) {
2323
                            .fail(function (err) {
2252
                                var message = err.responseJSON.error;
2324
                                var message = err.responseJSON.error;
2253
                                alert(message);
2325
                                alert(message);
2254
                            });
2326
                            });
2255
                        }
2327
                    },
2256
                    });
2328
                });
2257
                }
2258
            });
2259
2329
2260
            $('#modal-item-group-create').on('shown.bs.modal', function () {
2330
                $("#modal-item-group-edit").on("shown.bs.modal", function () {
2261
                $('#modal-item-group-create-form-description').focus();
2331
                    $("#modal-item-group-edit-form-description").focus();
2262
            });
2332
                });
2263
2333
2264
            // Edit existing item groups
2334
                // Delete existing item groups
2265
            $('body').on( 'click', '.item-group-edit', function(){
2335
                $("body").on("click", ".item-group-delete", function () {
2266
                const item_group_id = $(this).data('item-group-id');
2336
                    const item_group_id = $(this).data("item-group-id");
2267
                const url = `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`;
2337
                    $("#modal-item-group-delete-submit").data("item-group-id", item_group_id);
2268
                $.get( url, function( data ) {
2338
                    $("#modal-item-group-delete-submit").removeAttr("disabled");
2269
                    $('#modal-item-group-edit-form-description').val( data.description );
2339
                    $("#modal-item-group-delete").modal("show");
2270
                    $('#modal-item-group-edit-form-display_order').val( data.display_order );
2271
                    $('#modal-item-group-edit-submit').data('item-group-id', item_group_id );
2272
                    $('#modal-item-group-edit-submit').removeAttr('disabled');
2273
                    $('#modal-item-group-edit').modal('show');
2274
                });
2340
                });
2275
            });
2341
                $("#modal-item-group-delete-submit").on("click", function () {
2342
                    $("#modal-item-group-delete-submit").attr("disabled", "disabled");
2343
                    const item_group_id = $("#modal-item-group-delete-submit").data("item-group-id");
2276
2344
2277
            $("#modal-item-group-edit-form").validate({
2345
                    $.ajax({
2278
                submitHandler: function(form) {
2346
                        url: `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`,
2279
                    $('#modal-item-group-edit-submit').attr('disabled', 'disabled');
2347
                        headers: { "x-koha-embed": "items" },
2348
                        success: function (item_group_data) {
2349
                            $.ajax({
2350
                                url: `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`,
2351
                                method: "DELETE",
2352
                            })
2353
                                .done(function (response) {
2354
                                    $("#modal-item-group-delete").modal("hide");
2355
                                    $(`#item-group-add-form-select option[value='${item_group_id}']`).remove();
2356
                                    if (item_group_data.items === null) {
2357
                                        // No items for this item group, we can just refresh the table
2358
                                        itemGroupsTable.api().ajax.reload();
2359
                                    } else {
2360
                                        // This item group had items attached to it, we need to reload the page
2361
                                        window.location.replace(`/cgi-bin/koha/catalogue/detail.pl?biblionumber=${biblionumber}`);
2362
                                    }
2363
                                })
2364
                                .fail(function (err) {
2365
                                    var message = err.responseJSON.error;
2366
                                    alert(message);
2367
                                });
2368
                        },
2369
                    });
2370
                });
2280
2371
2281
                    const item_group_id = $('#modal-item-group-edit-submit').data('item-group-id');
2372
                // Add item(s) to a item group
2282
                    const url = `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`;
2373
                $(".itemselection_action_item_group_set").on("click", function () {
2374
                    $("#modal-item-group-set").modal("show");
2375
                });
2283
2376
2284
                    var settings = {
2377
                $("#modal-item-group-set-form").validate({
2285
                      "url": url,
2378
                    submitHandler: function (form) {
2286
                      "method": "PUT",
2379
                        $("#modal-item-group-set-submit").attr("disabled", "disabled");
2287
                      "headers": {
2288
                        "Content-Type": "application/json"
2289
                      },
2290
                      "data": JSON.stringify(
2291
                          {
2292
                              "description": $("#modal-item-group-edit-form-description").val(),
2293
                              "display_order": $("#modal-item-group-edit-form-display_order").val(),
2294
                          }
2295
                      ),
2296
                    };
2297
2298
                    $.ajax(settings)
2299
                    .done(function (response) {
2300
                        $('#modal-item-group-edit').modal('hide');
2301
                        itemGroupsTable.api().ajax.reload();
2302
                    })
2303
                    .fail(function(err) {
2304
                        var message = err.responseJSON.error;
2305
                        alert(message);
2306
                    });
2307
                }
2308
            });
2309
2380
2310
            $('#modal-item-group-edit').on('shown.bs.modal', function () {
2381
                        const item_group_id = $("#item-group-add-form-select").val();
2311
                $('#modal-item-group-edit-form-description').focus();
2312
            })
2313
2382
2314
            // Delete existing item groups
2383
                        let itemnumbers = new Array();
2315
            $('body').on( 'click', '.item-group-delete', function(){
2384
                        $("input[name='itemnumber'][type='checkbox']:checked").each(function () {
2316
                const item_group_id = $(this).data('item-group-id');
2385
                            const itemnumber = $(this).val();
2317
                $('#modal-item-group-delete-submit').data('item-group-id', item_group_id );
2386
                            itemnumbers.push(itemnumber);
2318
                $('#modal-item-group-delete-submit').removeAttr('disabled');
2319
                $('#modal-item-group-delete').modal('show');
2320
            });
2321
            $("#modal-item-group-delete-submit").on('click', function(){
2322
                $('#modal-item-group-delete-submit').attr('disabled', 'disabled');
2323
                const item_group_id = $("#modal-item-group-delete-submit").data('item-group-id');
2324
2325
                $.ajax({
2326
                    url: `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`,
2327
                    headers: { "x-koha-embed": "items" },
2328
                    success: function(item_group_data){
2329
                        $.ajax({
2330
                          "url": `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`,
2331
                          "method": "DELETE",
2332
                        })
2333
                        .done(function (response) {
2334
                            $('#modal-item-group-delete').modal('hide');
2335
                            $(`#item-group-add-form-select option[value='${item_group_id}']`).remove();
2336
                            if ( item_group_data.items === null ) {
2337
                                // No items for this item group, we can just refresh the table
2338
                                itemGroupsTable.api().ajax.reload();
2339
                            } else {
2340
                                // This item group had items attached to it, we need to reload the page
2341
                                window.location.replace(`/cgi-bin/koha/catalogue/detail.pl?biblionumber=${biblionumber}`);
2342
                            }
2343
                        })
2344
                        .fail(function(err) {
2345
                            var message = err.responseJSON.error;
2346
                            alert(message);
2347
                        });
2387
                        });
2348
                    }
2388
                        if (itemnumbers.length > 0) {
2349
                });
2389
                            let url = "/cgi-bin/koha/catalogue/detail.pl?op=set_item_group";
2350
            });
2390
                            url += "&itemnumber=" + itemnumbers.join("&itemnumber=");
2391
                            url += "&biblionumber=" + biblionumber;
2392
                            url += `&item_group_id=${item_group_id}`;
2351
2393
2352
            // Add item(s) to a item group
2394
                            window.location.replace(url);
2353
            $('.itemselection_action_item_group_set').on('click', function(){
2395
                        }
2354
                $('#modal-item-group-set').modal('show');
2396
2355
            });
2397
                        $("#modal-item-group-set").modal("hide");
2398
                    },
2399
                });
2356
2400
2357
            $("#modal-item-group-set-form").validate({
2401
                // Remove item(s) from an item group
2358
                submitHandler: function(form) {
2402
                $(".itemselection_action_item_group_unset").on("click", function () {
2359
                    $('#modal-item-group-set-submit').attr('disabled', 'disabled');
2403
                    $("#modal-item-group-unset").modal("show");
2404
                });
2360
2405
2361
                    const item_group_id = $('#item-group-add-form-select').val();
2406
                $("#modal-item-group-unset-submit").on("click", function () {
2407
                    $("#modal-item-group-unset-submit").attr("disabled", "disabled");
2362
2408
2363
                    let itemnumbers = new Array();
2409
                    let itemnumbers = new Array();
2364
                    $("input[name='itemnumber'][type='checkbox']:checked").each(function() {
2410
                    $("input[name='itemnumber'][type='checkbox']:checked").each(function () {
2365
                        const itemnumber = $(this).val();
2411
                        const itemnumber = $(this).val();
2366
                        itemnumbers.push( itemnumber );
2412
                        itemnumbers.push(itemnumber);
2367
                    });
2413
                    });
2368
                    if (itemnumbers.length > 0) {
2414
                    if (itemnumbers.length > 0) {
2369
                        let url = '/cgi-bin/koha/catalogue/detail.pl?op=set_item_group';
2415
                        let url = "/cgi-bin/koha/catalogue/detail.pl?op=unset_item_group";
2370
                        url += '&itemnumber=' + itemnumbers.join('&itemnumber=');
2416
                        url += "&itemnumber=" + itemnumbers.join("&itemnumber=");
2371
                        url += '&biblionumber=' + biblionumber;
2417
                        url += "&biblionumber=" + biblionumber;
2372
                        url += `&item_group_id=${item_group_id}`;
2373
2418
2374
                        window.location.replace(url);
2419
                        window.location.replace(url);
2375
                    }
2420
                    }
2376
2421
2377
                    $('#modal-item-group-set').modal('hide');
2422
                    $("#modal-item-group-unset").modal("hide");
2378
                }
2379
            });
2380
2381
            // Remove item(s) from an item group
2382
            $('.itemselection_action_item_group_unset').on('click', function(){
2383
                $('#modal-item-group-unset').modal('show');
2384
            });
2385
2386
            $("#modal-item-group-unset-submit").on('click', function(){
2387
                $('#modal-item-group-unset-submit').attr('disabled', 'disabled');
2388
2389
                let itemnumbers = new Array();
2390
                $("input[name='itemnumber'][type='checkbox']:checked").each(function() {
2391
                    const itemnumber = $(this).val();
2392
                    itemnumbers.push( itemnumber );
2393
                });
2423
                });
2394
                if (itemnumbers.length > 0) {
2395
                    let url = '/cgi-bin/koha/catalogue/detail.pl?op=unset_item_group';
2396
                    url += '&itemnumber=' + itemnumbers.join('&itemnumber=');
2397
                    url += '&biblionumber=' + biblionumber;
2398
2399
                    window.location.replace(url);
2400
                }
2401
2402
                $('#modal-item-group-unset').modal('hide');
2403
            });
2424
            });
2404
2405
        });
2406
        </script>
2425
        </script>
2407
    [% END # /IF EnableItemGroups %]
2426
    [% END # /IF EnableItemGroups %]
2408
2409
    <script>
2427
    <script>
2410
        $(".delete-comment").on("click", function(){
2428
        $(".delete-comment").on("click", function () {
2411
            return confirm( _("Are you sure you want to delete this comment?") );
2429
            return confirm(_("Are you sure you want to delete this comment?"));
2412
        });
2430
        });
2413
    </script>
2431
    </script>
2414
    [% CoverImagePlugins | $raw %]
2432
    [% CoverImagePlugins | $raw %]
(-)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