Bugzilla – Attachment 191106 Details for
Bug 41566
Tidy kohaTable block - catalogue
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 41566: catalogue - auto tidy
5933c95.patch (text/plain), 183.09 KB, created by
Jonathan Druart
on 2026-01-09 14:46:09 UTC
(
hide
)
Description:
Bug 41566: catalogue - auto tidy
Filename:
MIME Type:
Creator:
Jonathan Druart
Created:
2026-01-09 14:46:09 UTC
Size:
183.09 KB
patch
obsolete
>From 5933c959184364206aaad74bccaa21473ab5656a Mon Sep 17 00:00:00 2001 >From: Jonathan Druart <jonathan.druart@bugs.koha-community.org> >Date: Fri, 9 Jan 2026 13:11:20 +0100 >Subject: [PATCH] Bug 41566: catalogue - auto tidy > >--- > .../tables/items/catalogue_detail.inc | 778 ++++++------ > .../prog/en/modules/catalogue/detail.tt | 1112 +++++++++-------- > .../prog/en/modules/catalogue/issuehistory.tt | 3 +- > .../prog/en/modules/catalogue/itemsearch.tt | 599 +++++---- > 4 files changed, 1313 insertions(+), 1179 deletions(-) > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers/tables/items/catalogue_detail.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers/tables/items/catalogue_detail.inc >index 5be8f2af20a..375ef0f37f1 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers/tables/items/catalogue_detail.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers/tables/items/catalogue_detail.inc >@@ -162,57 +162,54 @@ > holdings: "[% PROCESS 'build_table' tab="holdings" | collapse | $tojson %]", > otherholdings: "[% PROCESS 'build_table' tab="otherholdings" | collapse | $tojson %]", > }; >- > </script> >- > <script> > let items_selection = {}; > > function _itemSelectionBuildLink(tab_id, link_class) { >- > let itemnumbers = items_selection[tab_id]; >- let tab = $("#" + tab_id + "_panel" ); >+ let tab = $("#" + tab_id + "_panel"); > let form = tab.find(link_class); > $(form).find("input[name='itemnumber']").remove(); > >- $(itemnumbers).each(function() { >+ $(itemnumbers).each(function () { > $(form).append("<input name='itemnumber' type='hidden' value='%s'/>".format(this)); > }); >- return !!itemnumbers.length >+ return !!itemnumbers.length; > } > function itemSelectionBuildDeleteLink(tab_id) { >- return _itemSelectionBuildLink(tab_id, '.itemselection_action_delete_form'); >+ return _itemSelectionBuildLink(tab_id, ".itemselection_action_delete_form"); > } > function itemSelectionBuildModifyLink(tab_id) { >- return _itemSelectionBuildLink(tab_id, '.itemselection_action_modify_form'); >+ return _itemSelectionBuildLink(tab_id, ".itemselection_action_modify_form"); > } > > function itemSelectionBuildActionLinks(tab_id) { > var delete_link_ok = itemSelectionBuildDeleteLink(tab_id); > var modify_link_ok = itemSelectionBuildModifyLink(tab_id); >- var tab = $("#" + tab_id + "_panel" ); >+ var tab = $("#" + tab_id + "_panel"); > if (modify_link_ok || delete_link_ok) { >- $('.itemselection_actions', tab).show(); >+ $(".itemselection_actions", tab).show(); > } else { >- $('.itemselection_actions', tab).hide(); >+ $(".itemselection_actions", tab).hide(); > } > } > >- function update_columns_visibility(table_dt, table_settings, user_colvis){ >+ function update_columns_visibility(table_dt, table_settings, user_colvis) { > table_dt.columns().visible(true, false); > let hidden_ids = _dt_visibility(table_settings, table_dt); > table_dt.columns(hidden_ids).visible(false, false); >- table_dt.columns().every(function(){ >+ table_dt.columns().every(function () { > let i = this.index(); > let is_empty = true; > let nodes = this.nodes(); > nodes.each((td, ii) => { >- if ( $(td).html() !== '' ) { >+ if ($(td).html() !== "") { > is_empty = false; > return; > } > }); >- if ( is_empty ) { >+ if (is_empty) { > table_dt.columns(i).visible(false, false); > } > }); >@@ -221,66 +218,78 @@ > } > } > >- >- $(document).ready(function() { >- >- $(".SelectAll").on("click",function(e){ >+ $(document).ready(function () { >+ $(".SelectAll").on("click", function (e) { > e.preventDefault(); > let tab_id = $(this).data("tab"); >- let tab = $("#" + tab_id + "_panel" ); >+ let tab = $("#" + tab_id + "_panel"); > items_selection[tab_id] = []; >- tab.find("input[name='itemnumber'][type='checkbox']").each( (i, input) => { >+ tab.find("input[name='itemnumber'][type='checkbox']").each((i, input) => { > let itemnumber = parseInt($(input).val()); > items_selection[tab_id].push(itemnumber); >- $(input).prop('checked', true); >+ $(input).prop("checked", true); > }); > itemSelectionBuildActionLinks(tab_id); > }); > >- $(".ClearAll").on("click",function(e){ >+ $(".ClearAll").on("click", function (e) { > e.preventDefault(); > let tab_id = $(this).data("tab"); >- let tab = $("#" + tab_id + "_panel" ); >+ let tab = $("#" + tab_id + "_panel"); > items_selection[tab_id] = []; >- $("input[name='itemnumber'][type='checkbox']", tab).prop('checked', false); >+ $("input[name='itemnumber'][type='checkbox']", tab).prop("checked", false); > itemSelectionBuildActionLinks(tab_id); > }); >- > }); > > let filters_shown = false; >- $(document).ready(function() { >- $(".show_filters").on("click",function(e){ >+ $(document).ready(function () { >+ $(".show_filters").on("click", function (e) { > e.preventDefault(); > let tab_id = $(this).data("tab"); >- let tab = $("#" + tab_id + "_panel" ); >+ let tab = $("#" + tab_id + "_panel"); > tab.find(".show_filters").hide(); > tab.find(".hide_filters").show(); > filters_show = true; >- $("#"+tab_id+"_table thead tr:eq(1)").remove(); >- build_items_table(tab_id, true, { destroy: true }, build_items_table_drawncallback ); >+ $("#" + tab_id + "_table thead tr:eq(1)").remove(); >+ build_items_table(tab_id, true, { destroy: true }, build_items_table_drawncallback); > itemSelectionBuildActionLinks(tab_id); > }); > >- $(".hide_filters").on("click",function(e){ >+ $(".hide_filters").on("click", function (e) { > e.preventDefault(); > let tab_id = $(this).data("tab"); >- let tab = $("#" + tab_id + "_panel" ); >+ let tab = $("#" + tab_id + "_panel"); > tab.find(".hide_filters").hide(); > tab.find(".show_filters").show(); > filters_show = false; >- $("#"+tab_id+"_table thead tr:eq(1)").remove(); >- build_items_table(tab_id, false, { destroy: true }, build_items_table_drawncallback ); >+ $("#" + tab_id + "_table thead tr:eq(1)").remove(); >+ build_items_table(tab_id, false, { destroy: true }, build_items_table_drawncallback); > itemSelectionBuildActionLinks(tab_id); > }); > }); > >- 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")}; >- const all_statuses = Object.keys(statuses).map(k => {return {_id: k, _str: statuses[k]}}); >+ 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"), >+ }; >+ const all_statuses = Object.keys(statuses).map(k => { >+ return { _id: k, _str: statuses[k] }; >+ }); > > var coded_values = { >- library: new Map(all_libraries.map( l => [l.branchname, l.branchcode] )), >- item_type: new Map(all_item_types.map( i => [i.translated_description, i.itemtype] )), >+ library: new Map(all_libraries.map(l => [l.branchname, l.branchcode])), >+ item_type: new Map(all_item_types.map(i => [i.translated_description, i.itemtype])), > collection_code: av_ccode, > location: av_loc, > }; >@@ -297,133 +306,141 @@ > // Do we need separate/new endpoints or do we hack the somewhere client-side? > let item_table_url = `/api/v1/biblios/${biblionumber}/items?`; > 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"]; >- if (prefs.LocalCoverImages){ >- embed.push('cover_image_ids'); >+ if (prefs.LocalCoverImages) { >+ embed.push("cover_image_ids"); > } >- if (prefs.EnableItemGroups){ >- embed.push('item_group_item.item_group.description'); >+ if (prefs.EnableItemGroups) { >+ embed.push("item_group_item.item_group.description"); > } >- if (is_serial){ >- embed.push('serial_item.serial'); >+ if (is_serial) { >+ embed.push("serial_item.serial"); > } >- if (prefs.UseRecalls){ >- embed.push('recall', 'recall+strings', 'recall.patron') >+ if (prefs.UseRecalls) { >+ embed.push("recall", "recall+strings", "recall.patron"); > } >- embed.push('in_bundle', 'bundle_host', 'bundle_host.biblio', 'bundle_items_lost+count', 'bundle_items_not_lost+count'); >- if (prefs.UseCourseReserves){ >- embed.push('course_item.course_reserves.course'); >+ embed.push("in_bundle", "bundle_host", "bundle_host.biblio", "bundle_items_lost+count", "bundle_items_not_lost+count"); >+ if (prefs.UseCourseReserves) { >+ embed.push("course_item.course_reserves.course"); > } >- if (prefs.ClaimReturnedLostValue){ >- embed.push('return_claims'); >+ if (prefs.ClaimReturnedLostValue) { >+ embed.push("return_claims"); > } > >- if (prefs.EasyAnalyticalRecords){ >+ if (prefs.EasyAnalyticalRecords) { > // For host records >- embed.push('biblio.title'); >+ embed.push("biblio.title"); > } > >- if (analyze){ >- embed.push('analytics_count'); >+ if (analyze) { >+ embed.push("analytics_count"); > } > >- let user_colvis = {holdings: {}, otherholdings: {}}; >- function build_items_table (tab_id, add_filters, dt_options, drawcallback) { >- >+ let user_colvis = { holdings: {}, otherholdings: {} }; >+ function build_items_table(tab_id, add_filters, dt_options, drawcallback) { > let table_dt; >- if ( dt_options && dt_options.hasOwnProperty('destroy') ) { >+ if (dt_options && dt_options.hasOwnProperty("destroy")) { > // Keep a copy of the user settings, the destroy is going to trigger the column-visibility.dt event for all columns >- let user_colvis_bak= Object.assign({}, user_colvis[tab_id]); >- let table_id = "#"+tab_id+"_table"; >- if( $.fn.dataTable.isDataTable(table_id) ) { >+ let user_colvis_bak = Object.assign({}, user_colvis[tab_id]); >+ let table_id = "#" + tab_id + "_table"; >+ if ($.fn.dataTable.isDataTable(table_id)) { > $(table_id).DataTable().destroy(); > } > $(table_id).replaceWith(table_nodes[tab_id]); >- dt_options['destroy'] = null; >+ dt_options["destroy"] = null; > user_colvis[tab_id] = user_colvis_bak; > } > let default_filters = {}; >- if (prefs.SeparateHoldings){ >- let branch = prefs.SeparateHoldingsBranch == 'homebranch' ? 'me.home_library_id' : 'me.holding_library_id'; >- if ( tab_id == 'holdings' ) { >+ if (prefs.SeparateHoldings) { >+ let branch = prefs.SeparateHoldingsBranch == "homebranch" ? "me.home_library_id" : "me.holding_library_id"; >+ if (tab_id == "holdings") { > default_filters[branch] = logged_in_branchcode; > } else { >- default_filters[branch] = { '!=': logged_in_branchcode }; >+ default_filters[branch] = { "!=": logged_in_branchcode }; > } > } > >- if (hidden_count){ >+ if (hidden_count) { > default_filters.lost_status = "0"; > } >- if ( !items_selection.hasOwnProperty(tab_id) ){ >+ if (!items_selection.hasOwnProperty(tab_id)) { > items_selection[tab_id] = []; > } > >- default_filters._status = function(){ >+ default_filters._status = function () { > return $("#" + tab_id + "_status select").val(); > }; > >-var columns = [ >+ var columns = [ > { > data: "me.item_id", > searchable: false, > orderable: false, > render: function (data, type, row, meta) { >- if ( can_edit_items_from.includes(row.home_library_id) || !can_edit_items_from.length ){ >- if ( items_selection[tab_id].includes(row.item_id) ) { >+ if (can_edit_items_from.includes(row.home_library_id) || !can_edit_items_from.length) { >+ if (items_selection[tab_id].includes(row.item_id)) { > return '<input type="checkbox" value="%s" name="itemnumber" checked />'.format(row.item_id); > } else { > return '<input type="checkbox" value="%s" name="itemnumber" />'.format(row.item_id); > } > } else { >- return '' >+ return ""; > } >- } >+ }, > }, >- ...(prefs.LocalCoverImages ? >- [{ >- data: "", >- className: "cover", >- searchable: false, >- orderable: false, >- render: function (data, type, row, meta) { >- if ( !row.cover_image_ids.length > 0 ) { >- return ''; >- } >- let node = '<div class="bookcoverimg">'; >- node += '<div class="cover-slider">'; >- row.cover_image_ids.forEach(id => { >- node += '<div class="cover-image local-coverimg">'; >- node += '<a href="/cgi-bin/koha/catalogue/image.pl?imagenumber=%s" title="%s">'.format(id, _("Local cover image")); >- 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")); >- node += '</a>'; >- node += '</div>'; >- }); >- node += '</div>'; >- node += '</div>'; >- return node; >- } >- }] : []), >- ...(prefs.item_level_itypes ? >- [{ >- data: "me.item_type_id", // FIXME Cannot filter by biblioitem.itemtype >- datatype: "coded_value:item_type", >- dataFilter: "item_types", >- className: "itype", >- searchable: true, >- orderable: true, >- render: function (data, type, row, meta) { >- let node = ''; >- let item_type_description = row._strings.item_type_id ? row._strings.item_type_id.str : row.item_type_id; >- if (prefs.noItemTypeImages){ >- let image_location = item_type_image_locations[row.item_type_id]; >- 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)) >- : ''; >- } >- node += '<span class="itypedesc itypetext">%s</span>'.format(escape_str(item_type_description)); >- return node; >- } >- }] : []), >+ ...(prefs.LocalCoverImages >+ ? [ >+ { >+ data: "", >+ className: "cover", >+ searchable: false, >+ orderable: false, >+ render: function (data, type, row, meta) { >+ if (!row.cover_image_ids.length > 0) { >+ return ""; >+ } >+ let node = '<div class="bookcoverimg">'; >+ node += '<div class="cover-slider">'; >+ row.cover_image_ids.forEach(id => { >+ node += '<div class="cover-image local-coverimg">'; >+ node += '<a href="/cgi-bin/koha/catalogue/image.pl?imagenumber=%s" title="%s">'.format(id, _("Local cover image")); >+ 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") >+ ); >+ node += "</a>"; >+ node += "</div>"; >+ }); >+ node += "</div>"; >+ node += "</div>"; >+ return node; >+ }, >+ }, >+ ] >+ : []), >+ ...(prefs.item_level_itypes >+ ? [ >+ { >+ data: "me.item_type_id", // FIXME Cannot filter by biblioitem.itemtype >+ datatype: "coded_value:item_type", >+ dataFilter: "item_types", >+ className: "itype", >+ searchable: true, >+ orderable: true, >+ render: function (data, type, row, meta) { >+ let node = ""; >+ let item_type_description = row._strings.item_type_id ? row._strings.item_type_id.str : row.item_type_id; >+ if (prefs.noItemTypeImages) { >+ let image_location = item_type_image_locations[row.item_type_id]; >+ 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)) : ""; >+ } >+ node += '<span class="itypedesc itypetext">%s</span>'.format(escape_str(item_type_description)); >+ return node; >+ }, >+ }, >+ ] >+ : []), > { > data: "me.holding_library_id", > datatype: "coded_value:library", >@@ -433,7 +450,7 @@ var columns = [ > orderable: true, > render: function (data, type, row, meta) { > return escape_str(row._strings.holding_library_id ? row._strings.holding_library_id.str : row.holding_library_id); >- } >+ }, > }, > { > data: "me.home_library_id", >@@ -444,7 +461,7 @@ var columns = [ > orderable: true, > render: function (data, type, row, meta) { > return escape_str(row._strings.home_library_id ? row._strings.home_library_id.str : row.home_library_id); >- } >+ }, > }, > { > data: "me.location", >@@ -457,15 +474,15 @@ var columns = [ > // display current location in parentheses. If not, display current location. > // Note that permanent location is a code, and location may be an authval. > let loc_str = row._strings.location ? row._strings.location.str : row.location; >- if ( row.permanent_location && row.permanent_location != row.location ) { >+ if (row.permanent_location && row.permanent_location != row.location) { > let permanent_loc_str = av_loc.get(row.permanent_location); >- nodes += '%s (%s)'.format(escape_str(permanent_loc_str), escape_str(loc_str)); >+ nodes += "%s (%s)".format(escape_str(permanent_loc_str), escape_str(loc_str)); > } else { > nodes += escape_str(loc_str); > } >- nodes += '</span>'; >+ nodes += "</span>"; > return nodes; >- } >+ }, > }, > { > data: "me.collection_code", >@@ -474,22 +491,25 @@ var columns = [ > orderable: true, > render: function (data, type, row, meta) { > return escape_str(row._strings.collection_code ? row._strings.collection_code.str : row.collection_code); >- } >+ }, > }, >- ...(prefs.EnableItemGroups ? >- [{ >- data: "item_group_item.item_group.description", >- className: "item_group", >- searchable: true, >- orderable: true, >- render: function (data, type, row, meta) { >- if ( row.item_group_item ) { >- return escape_str(row.item_group_item.item_group.description); >- } else { >- return ""; >- } >- } >- }] : []), >+ ...(prefs.EnableItemGroups >+ ? [ >+ { >+ data: "item_group_item.item_group.description", >+ className: "item_group", >+ searchable: true, >+ orderable: true, >+ render: function (data, type, row, meta) { >+ if (row.item_group_item) { >+ return escape_str(row.item_group_item.item_group.description); >+ } else { >+ return ""; >+ } >+ }, >+ }, >+ ] >+ : []), > { > data: "me.callnumber", > className: "itemcallnumber", >@@ -497,8 +517,7 @@ var columns = [ > orderable: true, > render: function (data, type, row, meta) { > return escape_str(row.callnumber); >- } >- >+ }, > }, > { > data: "me.serial_issue_number", >@@ -509,24 +528,24 @@ var columns = [ > let nodes = ""; > // 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? > let serial = row.serial_item ? row.serial_item.serial : null; >- if ( row.serial_issue_number && serial && serial.serialseq ) { >+ if (row.serial_issue_number && serial && serial.serialseq) { > nodes += '<span class="enum">%s</span>'.format(escape_str(row.serial_issue_number)); >- if ( serial.serialseq && row.serial_issue_number != serial.serialseq ) { >- nodes += ' <span class="sep"> -- </span>' >+ if (serial.serialseq && row.serial_issue_number != serial.serialseq) { >+ nodes += ' <span class="sep"> -- </span>'; > nodes += ' <span class="serialseq">%s</span>'.format(escape_str(serial.serialseq)); > } >- } else if ( row.serial_issue_number ) { >+ } else if (row.serial_issue_number) { > nodes += ' <span class="enum">%s</span>'.format(escape_str(row.serial_issue_number)); >- } else if ( serial && serial.serialseq ) { >+ } else if (serial && serial.serialseq) { > nodes += '<span class="serialseq">%s</span>'.format(escape_str(serial.serialseq)); > } >- if (prefs.DisplayPublishedDate){ >- if ( serial && serial.publisheddate ) { >+ if (prefs.DisplayPublishedDate) { >+ if (serial && serial.publisheddate) { > nodes += ' <span class="pubdate">(%s)</span>'.format($date(serial.publisheddate)); > } > } > return nodes; >- } >+ }, > }, > { > data: "", >@@ -536,67 +555,72 @@ var columns = [ > orderable: false, > render: function (data, type, row, meta) { > let nodes = ""; >- row._status.forEach( status => { >- if ( status == 'checked_out' || status == 'local_use') { >- nodes += '<span>'; >+ row._status.forEach(status => { >+ if (status == "checked_out" || status == "local_use") { >+ nodes += "<span>"; > > // Hacky for patron_to_html in case we simply want to display the patron's library name > row.checkout.patron.library = { name: libraries_names.get(row.checkout.patron.library_id) }; > let patron_to_html = $patron_to_html(row.checkout.patron, { url: true, display_cardnumber: true, hide_patron_name }); > >- if ( status == 'local_use' ) { >+ if (status == "local_use") { > nodes += _("Currently in local use by %s").format(patron_to_html); > } else { > nodes += '<span class="datedue">'; > nodes += _("Checked out to %s").format(patron_to_html); > } >- nodes += ': '; >+ nodes += ": "; > nodes += _("due %s").format($date(row.checkout.due_date, { as_due_date: true })); >- nodes += "</span>" >- >+ nodes += "</span>"; > } >- if ( status == 'in_transit' ) { >- if ( row.transfer.datesent ) { >- 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))); >+ if (status == "in_transit") { >+ if (row.transfer.datesent) { >+ 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)) >+ ); > } else { >- 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))); >+ 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)) >+ ); > } > } > >- if ( status == 'lost' ) { >+ if (status == "lost") { > let lost_lib = av_lost.get(row.lost_status.toString()) || _("Unavailable (lost or missing"); > nodes += '<span class="lost">%s</span>'.format(escape_str(lost_lib)); > >- const hasReturnClaims = row.return_claims && row.return_claims.filter(rc => !rc.resolution).length > 0 ? true : false >- if(hasReturnClaims) { >- nodes += '<span class="holding_status claimed_returned">' + _("(Claimed returned)") + '</span>'; >+ const hasReturnClaims = row.return_claims && row.return_claims.filter(rc => !rc.resolution).length > 0 ? true : false; >+ if (hasReturnClaims) { >+ nodes += '<span class="holding_status claimed_returned">' + _("(Claimed returned)") + "</span>"; > } > } > >- if ( status == 'withdrawn' ) { >+ if (status == "withdrawn") { > let withdrawn_lib = av_withdrawn.get(row.withdrawn.toString()) || _("Withdrawn"); > nodes += '<span class="wdn">%s</span>'.format(escape_str(withdrawn_lib)); > } > >- if ( status == 'damaged' ) { >+ if (status == "damaged") { > let damaged_lib = av_damaged.get(row.damaged_status.toString()) || _("Damaged"); > nodes += '<span class="dmg">%s</span>'.format(escape_str(damaged_lib)); > } > >- if ( status == 'not_for_loan' ) { >+ if (status == "not_for_loan") { > let not_for_loan_lib = av_not_for_loan.get(row.not_for_loan_status.toString()); >- 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>'; >+ 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>"; > } > >- if ( status == 'on_hold') { >- if ( row.first_hold.waiting_date ) { >- if ( row.first_hold.desk ) { >- 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)))); >+ if (status == "on_hold") { >+ if (row.first_hold.waiting_date) { >+ if (row.first_hold.desk) { >+ 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))) >+ ); > } else { > 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)))); > } >- if (prefs.canreservefromotherbranches){ >- if ( row.first_hold.waiting_date || row.first_hold.priority == 1 ) { >+ if (prefs.canreservefromotherbranches) { >+ if (row.first_hold.waiting_date || row.first_hold.priority == 1) { > // Hacky for patron_to_html in case we simply want to display the patron's library name > row.first_hold.patron.library = { name: libraries_names.get(row.first_hold.patron.library_id) }; > >@@ -609,32 +633,34 @@ var columns = [ > } > } > >- if (prefs.UseRecalls){ >- if ( row.recall && ( row.item_id === row.recall.item_id ) ) { >- if ( row.recall.waiting_date ) { >- 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))); >- } else { >- // Hacky for patron_to_html in case we simply want to display the patron's library name >- row.recall.patron.library = { name: libraries_names.get(row.recall.patron.library_id) }; >+ if (prefs.UseRecalls) { >+ if (row.recall && row.item_id === row.recall.item_id) { >+ if (row.recall.waiting_date) { >+ 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)) >+ ); >+ } else { >+ // Hacky for patron_to_html in case we simply want to display the patron's library name >+ row.recall.patron.library = { name: libraries_names.get(row.recall.patron.library_id) }; > >- let patron_to_html = $patron_to_html(row.recall.patron, {url: true, display_cardnumber: true, hide_patron_name }); >- nodes += '<span class="holding_status recalledby">%s</span>'.format(_("Recalled by %s on %s").format(patron_to_html, $date(row.recall.created_date))) >+ let patron_to_html = $patron_to_html(row.recall.patron, { url: true, display_cardnumber: true, hide_patron_name }); >+ nodes += '<span class="holding_status recalledby">%s</span>'.format(_("Recalled by %s on %s").format(patron_to_html, $date(row.recall.created_date))); >+ } > } > } >- } >- if ( status == 'available' ) { >- nodes += ' <span>%s</span>'.format(_("Available")) >+ if (status == "available") { >+ nodes += " <span>%s</span>".format(_("Available")); > } > >- if ( status == 'restricted') { >+ if (status == "restricted") { > nodes += '<span class="restricted">(%s)</span>'.format(escape_str(av_restricted.get(row.restricted_status.toString()))); > } >- if ( status == 'in_bundle') { >+ if (status == "in_bundle") { > nodes += '<span class="bundled">%s</span>'.format(_("In bundle: %s").format($biblio_to_html(row.bundle_host.biblio, { link: true }))); > } > }); > return nodes; >- } >+ }, > }, > { > data: "me.last_seen_date", >@@ -644,7 +670,7 @@ var columns = [ > orderable: true, > render: function (data, type, row, meta) { > return $datetime(row.last_seen_date); >- } >+ }, > }, > { > data: "me.checkouts_count", >@@ -653,7 +679,7 @@ var columns = [ > orderable: true, > render: function (data, type, row, meta) { > return row.checkouts_count || 0; >- } >+ }, > }, > { > data: "me.renewals_count", >@@ -662,7 +688,7 @@ var columns = [ > orderable: true, > render: function (data, type, row, meta) { > return row.renewals_count || 0; >- } >+ }, > }, > { > data: "me.localuse", >@@ -671,7 +697,7 @@ var columns = [ > orderable: true, > render: function (data, type, row, meta) { > return row.localuse || 0; >- } >+ }, > }, > { > data: "me.acquisition_date", >@@ -681,7 +707,7 @@ var columns = [ > orderable: true, > render: function (data, type, row, meta) { > return $date(row.acquisition_date); >- } >+ }, > }, > { > data: "me.last_checkout_date", >@@ -691,7 +717,7 @@ var columns = [ > orderable: true, > render: function (data, type, row, meta) { > return $date(row.last_checkout_date); >- } >+ }, > }, > { > data: "me.acquisition_source", >@@ -700,7 +726,7 @@ var columns = [ > orderable: true, > render: function (data, type, row, meta) { > return escape_str(row._strings.acquisition_source ? row._strings.acquisition_source.str : row.acquisition_source); >- } >+ }, > }, > { > data: "me.external_id", >@@ -708,11 +734,11 @@ var columns = [ > searchable: true, > orderable: true, > render: function (data, type, row, meta) { >- if ( row.external_id != null ) { >+ if (row.external_id != null) { > 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); > } >- return ''; >- } >+ return ""; >+ }, > }, > { > data: "me.uri", >@@ -720,20 +746,20 @@ var columns = [ > searchable: true, > orderable: true, > render: function (data, type, row, meta) { >- if ( !row.uri ) return ""; >+ if (!row.uri) return ""; > >- let nodes = ''; >- if ( row.uri.split(' \| ').length > 1 ) { >- row.uri.split(' \| ').forEach((uri, i) => { >- let node = safe_link(uri,uri); >+ let nodes = ""; >+ if (row.uri.split(" \| ").length > 1) { >+ row.uri.split(" \| ").forEach((uri, i) => { >+ let node = safe_link(uri, uri); > nodes += node.outerHTML + "<br>"; > }); > } else { >- let node = safe_link(row.uri,url_link_text); >+ let node = safe_link(row.uri, url_link_text); > nodes += node.outerHTML; > } > return nodes; >- } >+ }, > }, > { > data: "me.copy_number", >@@ -742,7 +768,7 @@ var columns = [ > orderable: true, > render: function (data, type, row, meta) { > return escape_str(row._strings.copy_number ? row._strings.copy_number.str : row.copy_number); >- } >+ }, > }, > { > data: "me.inventory_number", >@@ -751,7 +777,7 @@ var columns = [ > orderable: true, > render: function (data, type, row, meta) { > return escape_str(row.inventory_number); >- } >+ }, > }, > { > data: "me.materials_notes", >@@ -760,7 +786,7 @@ var columns = [ > orderable: true, > render: function (data, type, row, meta) { > return escape_str(row.materials_notes); >- } >+ }, > }, > { > data: "me.public_notes", >@@ -768,8 +794,8 @@ var columns = [ > searchable: true, > orderable: true, > render: function (data, type, row, meta) { >- return row.public_notes ? escape_str(row.public_notes).replaceAll('\n', '<br />') : ''; >- } >+ return row.public_notes ? escape_str(row.public_notes).replaceAll("\n", "<br />") : ""; >+ }, > }, > { > data: "me.internal_notes", >@@ -778,181 +804,211 @@ var columns = [ > orderable: true, > render: function (data, type, row, meta) { > return escape_str(row.internal_notes); >- } >- }, >- ...(prefs.EasyAnalyticalRecords? >- [{ >- data: "biblio.title", >- searchable: false, >- orderable: true, >- render: function (data, type, row, meta) { >- if ( row.biblio_id == biblionumber ) return ""; >- return '<a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=%s">%s</a>'.format(row.biblio_id, row.biblio.title); >- } >- }]:[]), >- ...(analyze ? >- [{ >- data: "analytics_count", >- searchable: false, >- orderable: false, >- render: function (data, type, row, meta) { >- if (row.analytics_count == 0) return "" >- return '<a href="/cgi-bin/koha/catalogue/search.pl?idx=hi&q=%s">%s</a>'.format(row.item_id, _("%s analytics").format(row.analytics_count)); >- } >+ }, > }, >+ ...(prefs.EasyAnalyticalRecords >+ ? [ >+ { >+ data: "biblio.title", >+ searchable: false, >+ orderable: true, >+ render: function (data, type, row, meta) { >+ if (row.biblio_id == biblionumber) return ""; >+ return '<a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=%s">%s</a>'.format(row.biblio_id, row.biblio.title); >+ }, >+ }, >+ ] >+ : []), >+ ...(analyze >+ ? [ >+ { >+ data: "analytics_count", >+ searchable: false, >+ orderable: false, >+ render: function (data, type, row, meta) { >+ if (row.analytics_count == 0) return ""; >+ return '<a href="/cgi-bin/koha/catalogue/search.pl?idx=hi&q=%s">%s</a>'.format(row.item_id, _("%s analytics").format(row.analytics_count)); >+ }, >+ }, >+ { >+ data: "analytics_count", // create analytics link >+ searchable: false, >+ orderable: false, >+ render: function (data, type, row, meta) { >+ return '<a href="/cgi-bin/koha/cataloguing/addbiblio.pl?hostbiblionumber=%s&hostitemnumber=%s">%s</a>'.format(row.biblio_id, row.item_id, _("Create analytics")); >+ }, >+ }, >+ ] >+ : []), >+ ...(prefs.UseCourseReserves >+ ? [ >+ { >+ data: "course_item.course_reserves.course.course_name", >+ searchable: true, >+ orderable: true, >+ render: function (data, type, row, meta) { >+ let nodes = ""; >+ if (!row.course_item) return nodes; >+ row.course_item.course_reserves.forEach((cr, i) => { >+ let c = cr.course; >+ if (c.enabled != "yes") return; >+ nodes += "<p>"; >+ nodes += '<a href="/cgi-bin/koha/course_reserves/course-details.pl?course_id=%s">'.format(c.course_id); >+ nodes += escape_str(c.course_name); >+ if (c.section) { >+ nodes += " " + escape_str(c.section); >+ } >+ if (c.term) { >+ nodes += " " + av_courses_term.get(c.term.toString()); >+ } >+ nodes += "</p>"; >+ }); >+ return nodes; >+ }, >+ }, >+ ] >+ : []), >+ ...(prefs.SpineLabelShowPrintOnBibDetails >+ ? [ >+ { >+ data: "", >+ searchable: false, >+ orderable: false, >+ render: function (data, type, row, meta) { >+ 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)); >+ }, >+ }, >+ ] >+ : []), >+ ...(permissions.CAN_user_editcatalogue_edit_items >+ ? [ >+ { >+ data: function (row, type, val, meta) { >+ let nodes = ""; >+ if (can_edit_items_from.includes(row.home_library_id) || !can_edit_items_from.length) { >+ if (prefs.LocalCoverImages || prefs.OPACLocalCoverImages) { >+ nodes += '<div class="btn-group dropup">'; >+ 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") >+ ); >+ nodes += ' <ul class="dropdown-menu">'; >+ nodes += ' <li><a class="dropdown-item" href="/cgi-bin/koha/tools/upload-cover-image.pl?itemnumber=%s&filetype=image"><i class="fa fa-upload"></i> %s</a></li>'.format( >+ row.item_id, >+ _("Upload image") >+ ); >+ nodes += " </ul>"; >+ nodes += "</div>"; >+ } else { >+ 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") >+ ); >+ } >+ } >+ if (bundlesEnabled) { >+ 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) >+ ); >+ } >+ >+ return nodes; >+ }, >+ className: "actions", >+ searchable: false, >+ orderable: false, >+ }, >+ ] >+ : []), >+ ]; >+ var items_table = $("#" + tab_id + "_table").kohaTable( > { >- data: "analytics_count", // create analytics link >- searchable: false, >- orderable: false, >- render: function (data, type, row, meta) { >- return '<a href="/cgi-bin/koha/cataloguing/addbiblio.pl?hostbiblionumber=%s&hostitemnumber=%s">%s</a>'.format(row.biblio_id, row.item_id, _("Create analytics")); >- } >- }]:[]), >- ...(prefs.UseCourseReserves? >- [{ >- data: "course_item.course_reserves.course.course_name", >- searchable: true, >- orderable: true, >- render: function (data, type, row, meta) { >- let nodes = ''; >- if (!row.course_item) return nodes; >- row.course_item.course_reserves.forEach((cr, i) => { >- let c = cr.course; >- if ( c.enabled != 'yes' ) return; >- nodes += '<p>'; >- nodes += '<a href="/cgi-bin/koha/course_reserves/course-details.pl?course_id=%s">'.format(c.course_id); >- nodes += escape_str(c.course_name); >- if ( c.section ) { >- nodes += ' ' + escape_str(c.section); >- } >- if ( c.term ) { >- nodes += ' ' + av_courses_term.get(c.term.toString()); >- } >- nodes += '</p>'; >+ ajax: { url: item_table_url }, >+ order: [], >+ embed, >+ autoWidth: false, >+ bKohaColumnsUseNames: true, >+ columns, >+ initComplete: function (settings, json) { >+ itemSelectionBuildActionLinks(tab_id); >+ }, >+ drawCallback: function (settings) { >+ let api = this.api(); >+ $.each($(this).find("tbody tr td:first-child"), function (index, e) { >+ let tr = $(this).parent(); >+ let row = api.row(tr).data(); >+ if (!row) return; // Happen if the table is empty >+ $(this) >+ .find("input[name='itemnumber'][type='checkbox']") >+ .on("change", function () { >+ let itemnumber = parseInt($(this).val()); >+ if ($(this).prop("checked")) { >+ items_selection[tab_id].push(itemnumber); >+ } else { >+ items_selection[tab_id] = items_selection[tab_id].filter(id => id != itemnumber); >+ } >+ itemSelectionBuildActionLinks(tab_id); >+ }); > }); >- return nodes; >- } >- }]:[]), >- ...(prefs.SpineLabelShowPrintOnBibDetails? >- [{ >- data: "", >- searchable: false, >- orderable: false, >- render: function (data, type, row, meta) { >- 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)); >- } >- }]:[]), >- ...(permissions.CAN_user_editcatalogue_edit_items ? >- [{ >- data: function( row, type, val, meta ) { >- let nodes = ''; >- if ( can_edit_items_from.includes(row.home_library_id) || !can_edit_items_from.length ){ >- if (prefs.LocalCoverImages || prefs.OPACLocalCoverImages){ >- nodes += '<div class="btn-group dropup">'; >- 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")); >- nodes += ' <ul class="dropdown-menu">'; >- nodes += ' <li><a class="dropdown-item" href="/cgi-bin/koha/tools/upload-cover-image.pl?itemnumber=%s&filetype=image"><i class="fa fa-upload"></i> %s</a></li>'.format(row.item_id, _("Upload image")); >- nodes += ' </ul>'; >- nodes += '</div>'; >- } else { >- 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")); >- } >- } >- if (bundlesEnabled){ >- 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)); >+ >+ if (!add_filters && settings._iRecordsDisplay == settings._iRecordsTotal && settings._iDisplayLength >= settings._iRecordsDisplay) { >+ let container = $(this).parent(); >+ container.find(".dt-info").remove(); >+ container.find(".table_entries").remove(); >+ container.find(".dataTables_filter").remove(); >+ container.find(".dt_button_clear_filter").remove(); >+ container.find(".bottom.pager").remove(); > } > >- return nodes; >- }, >- className: "actions", >- searchable: false, >- orderable: false >- }]:[]) >- ]; >- var items_table = $("#" + tab_id + '_table').kohaTable({ >- ajax: { url: item_table_url }, >- order: [], >- embed, >- autoWidth: false, >- bKohaColumnsUseNames: true, >- columns, >- initComplete: function( settings, json ){ >- itemSelectionBuildActionLinks(tab_id); >- }, >- drawCallback: function(settings){ >- let api = this.api(); >- $.each( >- $(this).find("tbody tr td:first-child"), >- function (index, e) { >- let tr = $(this).parent() >- let row = api.row(tr).data() >- if (!row) return // Happen if the table is empty >- $(this).find("input[name='itemnumber'][type='checkbox']").on("change", function(){ >- let itemnumber = parseInt($(this).val()); >- if( $(this).prop("checked") ){ >- items_selection[tab_id].push(itemnumber); >- } else { >- items_selection[tab_id] = items_selection[tab_id].filter( id => id != itemnumber ); >- } >- itemSelectionBuildActionLinks(tab_id); >+ if (prefs.SpineLabelShowPrintOnBibDetails) { >+ $(".print-label").on("click", function (e) { >+ e.preventDefault(); >+ link = $(this).attr("href"); >+ openWindow(link, "Print spine label", 400, 400); > }); > } >- ); >- >- if (!add_filters && settings._iRecordsDisplay == settings._iRecordsTotal && settings._iDisplayLength >= settings._iRecordsDisplay){ >- let container = $(this).parent(); >- container.find(".dt-info").remove(); >- container.find(".table_entries").remove(); >- container.find(".dataTables_filter").remove(); >- container.find(".dt_button_clear_filter").remove(); >- container.find(".bottom.pager").remove(); >- } > >- if (prefs.SpineLabelShowPrintOnBibDetails){ >- $(".print-label").on("click", function(e){ >- e.preventDefault(); >- link = $(this).attr("href"); >- openWindow(link,"Print spine label",400,400); >- }); >- } >- >- if ( api.data().length ) { >- update_columns_visibility(api, items_table_settings[tab_id], user_colvis[tab_id]); >- } >+ if (api.data().length) { >+ update_columns_visibility(api, items_table_settings[tab_id], user_colvis[tab_id]); >+ } > >- if ( drawcallback ) { drawcallback(this); } >+ if (drawcallback) { >+ drawcallback(this); >+ } >+ }, >+ ...dt_options, > }, >- ...dt_options, >- }, >- items_table_settings[tab_id], >- add_filters, >- default_filters, >- filters_options, >+ items_table_settings[tab_id], >+ add_filters, >+ default_filters, >+ filters_options > ); > > table_dt = items_table.DataTable(); >- table_dt.on("column-visibility.dt", function(e, settings, column, state, recalc ){ >+ table_dt.on("column-visibility.dt", function (e, settings, column, state, recalc) { > if (recalc === false) return; > >- if ( filters_shown ) { >+ if (filters_shown) { > _dt_add_filters(this, table_dt, filters_options); > } > > user_colvis[tab_id][column] = state; >- > }); > return items_table; > } >- function safe_link(uri,link_text) { >- let node = document.createElement('a'); >- let url_str = '#'; >+ function safe_link(uri, link_text) { >+ let node = document.createElement("a"); >+ let url_str = "#"; > try { > const safe_url = new URL(uri); > url_str = safe_url.href; > } catch (e) { > //console.error('Invalid URL:', e); > } >- node.setAttribute('href',url_str); >+ node.setAttribute("href", url_str); > node.textContent = link_text; > return node; > } >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt >index 7e67e92507a..8688a85a3ff 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt >@@ -1281,160 +1281,180 @@ > var table_settings = [% TablesSettings.GetTableSettings( 'catalogue', 'concerns', 'table_concerns', 'json' ) | $raw %]; > const biblio_id = "[% biblionumber | html %]"; > </script> >- > <script> >- $(document).ready(function() { >+ $(document).ready(function () { > $("#bibliodetails a:first").tab("show"); > > let additional_filters = { >- resolved_date: function(){ >- if ( $("#hide_resolved_concerns").is(":checked") ) { >+ resolved_date: function () { >+ if ($("#hide_resolved_concerns").is(":checked")) { > return { "=": null }; > } else { > return; > } > }, >- source: 'catalog', >+ source: "catalog", > biblio_id, > }; > let external_filter_nodes = { > hide_resolved_concerns: "#hide_resolved_concerns", > }; > >- var tickets_url = '/api/v1/tickets'; >- var tickets = $("#table_concerns").kohaTable({ >- ajax: { >- "url": tickets_url >- }, >- embed: [ >- "assignee", >- "reporter", >- "resolver", >- "biblio", >- "updates+count", >- "+strings" >- ], >- emptyTable: '<div class="alert alert-info">' + _("Congratulations, there are no catalog concerns.") + '</div>', >- columnDefs: [ { >- targets: [0,1,2,3], >- render: function (data, type, row, meta) { >- if ( type == 'display' ) { >- if ( data != null ) { >- return data.escapeHtml(); >- } >- else { >- return ""; >- } >- } >- return data; >- } >- } ], >- columns: [ >- { >- data: "reported_date:reporter.firstname", >- render: function(data, type, row, meta) { >- let reported = '<div class="d-flex justify-content-between align-items-start">'; >- reported += '<span class="reporter">' + $patron_to_html(row.reporter, { >- display_cardnumber: false, >- url: true >- }) + '</span>'; >- reported += '<span class="date text-muted">' + $datetime(row.reported_date) + '</span>'; >- reported += '</div>'; >- return reported; >- }, >- searchable: true, >- orderable: true >+ var tickets_url = "/api/v1/tickets"; >+ var tickets = $("#table_concerns").kohaTable( >+ { >+ ajax: { >+ url: tickets_url, > }, >- { >- data: "title:body", >- render: function(data, type, row, meta) { >- let result = '<div class="d-flex justify-content-between align-items-start">'; >+ embed: ["assignee", "reporter", "resolver", "biblio", "updates+count", "+strings"], >+ emptyTable: '<div class="alert alert-info">' + _("Congratulations, there are no catalog concerns.") + "</div>", >+ columnDefs: [ >+ { >+ targets: [0, 1, 2, 3], >+ render: function (data, type, row, meta) { >+ if (type == "display") { >+ if (data != null) { >+ return data.escapeHtml(); >+ } else { >+ return ""; >+ } >+ } >+ return data; >+ }, >+ }, >+ ], >+ columns: [ >+ { >+ data: "reported_date:reporter.firstname", >+ render: function (data, type, row, meta) { >+ let reported = '<div class="d-flex justify-content-between align-items-start">'; >+ reported += >+ '<span class="reporter">' + >+ $patron_to_html(row.reporter, { >+ display_cardnumber: false, >+ url: true, >+ }) + >+ "</span>"; >+ reported += '<span class="date text-muted">' + $datetime(row.reported_date) + "</span>"; >+ reported += "</div>"; >+ return reported; >+ }, >+ searchable: true, >+ orderable: true, >+ }, >+ { >+ data: "title:body", >+ render: function (data, type, row, meta) { >+ let result = '<div class="d-flex justify-content-between align-items-start">'; > >- // Title link on the left >- result += '<a id="title_' + row.ticket_id + '" role="button" href="#" class="detail-trigger">' + row.title + '</a>'; >+ // Title link on the left >+ result += '<a id="title_' + row.ticket_id + '" role="button" href="#" class="detail-trigger">' + row.title + "</a>"; > >- // Updates count on the right, if it exists >- if (row.updates_count) { >- result += '<span><a role="button" href="#" class="detail-trigger"><i class="fa fa-comment" aria-hidden="true"></i> ' + row.updates_count + '</a></span>'; >- } >+ // Updates count on the right, if it exists >+ if (row.updates_count) { >+ result += '<span><a role="button" href="#" class="detail-trigger"><i class="fa fa-comment" aria-hidden="true"></i> ' + row.updates_count + "</a></span>"; >+ } > >- // Hidden detail content >- result += '</div>'; >- result += '<div id="detail_' + row.ticket_id + '" style="display:none">' + row.body + '</div>'; >+ // Hidden detail content >+ result += "</div>"; >+ result += '<div id="detail_' + row.ticket_id + '" style="display:none">' + row.body + "</div>"; > >- return result; >+ return result; >+ }, >+ searchable: true, >+ orderable: true, > }, >- searchable: true, >- orderable: true >- }, >- { >- data: "biblio.title", >- render: function(data, type, row, meta) { >- return $biblio_to_html(row.biblio, { >- link: 1 >- }); >+ { >+ data: "biblio.title", >+ render: function (data, type, row, meta) { >+ return $biblio_to_html(row.biblio, { >+ link: 1, >+ }); >+ }, >+ searchable: true, >+ orderable: true, > }, >- searchable: true, >- orderable: true >- }, >- { >- data: "assignee.firstname:assignee.surname:resolver.firstname:resolver.surname:resolved_date:status", >- render: function(data, type, row, meta) { >- let result = ''; >- if (row.resolved_date) { >- result += "<div>"; >- result += _("Resolved by") + ' <span>' + $patron_to_html(row.resolver, { >- display_cardnumber: false, >- url: true >- }) + '</span>'; >- result += "</div>"; >- if (row.status) { >- result += '<div>'; >- result += ' ' + _("as") + ' '; >- result += row._strings.status ? escape_str(row._strings.status.str) : ""; >- result += '</div>'; >- } >- result += '<div>' + $datetime(row.resolved_date) + '</div>'; >- } else { >- result += '<div>'; >- if (row.status) { >- result += row._strings.status ? escape_str(row._strings.status.str) : ""; >+ { >+ data: "assignee.firstname:assignee.surname:resolver.firstname:resolver.surname:resolved_date:status", >+ render: function (data, type, row, meta) { >+ let result = ""; >+ if (row.resolved_date) { >+ result += "<div>"; >+ result += >+ _("Resolved by") + >+ " <span>" + >+ $patron_to_html(row.resolver, { >+ display_cardnumber: false, >+ url: true, >+ }) + >+ "</span>"; >+ result += "</div>"; >+ if (row.status) { >+ result += "<div>"; >+ result += " " + _("as") + " "; >+ result += row._strings.status ? escape_str(row._strings.status.str) : ""; >+ result += "</div>"; >+ } >+ result += "<div>" + $datetime(row.resolved_date) + "</div>"; > } else { >- result += _("Open"); >- } >- result += '</div>'; >- if (row.assignee) { >- result += '<div>'; >- result += _("Assigned to: ") + ' <span>' + $patron_to_html(row.assignee, { >- display_cardnumber: false, >- url: true >- }) + '</span>'; >- result += '</div>'; >+ result += "<div>"; >+ if (row.status) { >+ result += row._strings.status ? escape_str(row._strings.status.str) : ""; >+ } else { >+ result += _("Open"); >+ } >+ result += "</div>"; >+ if (row.assignee) { >+ result += "<div>"; >+ result += >+ _("Assigned to: ") + >+ " <span>" + >+ $patron_to_html(row.assignee, { >+ display_cardnumber: false, >+ url: true, >+ }) + >+ "</span>"; >+ result += "</div>"; >+ } > } >- } >- return result; >+ return result; >+ }, >+ searchable: true, >+ orderable: true, > }, >- searchable: true, >- orderable: true >- }, >- { >- data: function(row, type, val, meta) { >- let resolved = ( row.resolved_date ) ? true : false; >- 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>'; >- return result; >+ { >+ data: function (row, type, val, meta) { >+ let resolved = row.resolved_date ? true : false; >+ 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>"; >+ return result; >+ }, >+ searchable: false, >+ orderable: false, > }, >- searchable: false, >- orderable: false >- }, >- ] >- }, table_settings, 0, additional_filters, undefined, external_filter_nodes); >+ ], >+ }, >+ table_settings, >+ 0, >+ additional_filters, >+ undefined, >+ external_filter_nodes >+ ); > >- $('#hideResolved').on("click", function() { >+ $("#hideResolved").on("click", function () { > $("#hide_resolved_concerns").prop("checked", true); > tickets.DataTable().draw(); > }); > >- $('#showAll').on("click", function() { >+ $("#showAll").on("click", function () { > $("#hide_resolved_concerns").prop("checked", false); > tickets.DataTable().draw(); > }); >@@ -1728,7 +1748,6 @@ > [% IF Koha.Preference('EnableBooking') %] > [% Asset.js("js/modals/place_booking.js") | $raw %] > [% END %] >- > <script> > var browser; > browser = KOHA.browser("[% searchid | html %]", parseInt(biblionumber, 10)); >@@ -1748,165 +1767,169 @@ > CAN_user_editcatalogue_manage_item_groups: [% CAN_user_editcatalogue_manage_item_groups ? 1 : 0 | html %], > }); > </script> >- > <script> >- let items_tab_ids = [ 'holdings', 'otherholdings' ]; >- items_tab_ids.forEach( function( tab_id, index ) { >- >+ let items_tab_ids = ["holdings", "otherholdings"]; >+ items_tab_ids.forEach(function (tab_id, index) { > // Early return if the tab is not shown (ie. no table) > if (!$("#%s_table".format(tab_id)).length) return; >- if (prefs.AlwaysShowHoldingsTableFilters){ >+ if (prefs.AlwaysShowHoldingsTableFilters) { > build_items_table(tab_id, true, {}, build_items_table_drawncallback); > } else { > build_items_table(tab_id, false, {}, build_items_table_drawncallback); > } > >- if (prefs.bundlesEnabled){ >+ if (prefs.bundlesEnabled) { > // Add event listener for opening and closing bundle details >- $('#' + tab_id + '_table tbody').on('click', 'button.details-control', function () { >+ $("#" + tab_id + "_table tbody").on("click", "button.details-control", function () { > var button = $(this); >- var tr = button.closest('tr'); >- var dTable = button.closest('table').DataTable({ 'retrieve': true }); >+ var tr = button.closest("tr"); >+ var dTable = button.closest("table").DataTable({ retrieve: true }); > >- let row = dTable.row( tr ); >+ let row = dTable.row(tr); > let data = row.data(); > let itemnumber = data.item_id; >- let duedate = (data.checkout&&data.checkout.due_date) || null; >+ let duedate = (data.checkout && data.checkout.due_date) || null; > >- if ( row.child.isShown() ) { >+ if (row.child.isShown()) { > // This row is already open - close it > row.child.hide(); >- tr.removeClass('shown'); >- button.removeClass('active'); >+ tr.removeClass("shown"); >+ button.removeClass("active"); > } else { > // Open this row > createChild(row, itemnumber, duedate); >- tr.addClass('shown'); >- button.addClass('active'); >+ tr.addClass("shown"); >+ button.addClass("active"); > } > }); > } > }); > >- if (bundlesEnabled){ // Bundle handling >- function createChild ( row, itemnumber, duedate ) { >+ if (bundlesEnabled) { >+ // Bundle handling >+ function createChild(row, itemnumber, duedate) { > // Toolbar > var bundle_toolbar = $('<div id="toolbar" class="btn-toolbar"></div>'); >- 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>'); >- 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>'); >+ 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>"); >+ 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>"); > >- // Toolbar >- var bundle_toolbar = $('<div id="toolbar" class="btn-toolbar"></div>'); >- 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>'); >- 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>'); >+ // Toolbar >+ var bundle_toolbar = $('<div id="toolbar" class="btn-toolbar"></div>'); >+ 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>"); >+ 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>"); > > // This is the table we'll convert into a DataTable >- var bundles_table = $('<table class="display tbundle" data-itemnumber="'+itemnumber+'" id="bundle_table_'+itemnumber+'" width="100%"/>'); >+ var bundles_table = $('<table class="display tbundle" data-itemnumber="' + itemnumber + '" id="bundle_table_' + itemnumber + '" width="100%"/>'); > > // Display it the child row >- row.child( bundle_toolbar.add(bundles_table), 'bundle' ).show(); >+ row.child(bundle_toolbar.add(bundles_table), "bundle").show(); > > // Initialise as a DataTable > var bundle_table_url = "/api/v1/items/" + itemnumber + "/bundled_items?"; >- var bundle_table = bundles_table.kohaTable({ >- "ajax": { >- "url": bundle_table_url >- }, >- "embed": [ >- "biblio", >- "return_claim.patron" >- ], >- "order": [[ 1, "asc" ]], >- "columnDefs": [ { >- "targets": [0,1,2,3], >- "render": function (data, type, row, meta) { >- if ( data && type == 'display' ) { >- return data.escapeHtml(); >- } >- return data; >- } >- } ], >- "columns": [ >- { >- "data": "biblio.title:biblio.subtitle:biblio.medium", >- "title": _("Title"), >- "searchable": true, >- "orderable": true, >- "render": function(data, type, row, meta) { >- return $biblio_to_html(row.biblio, { link: 1 }); >- } >- }, >- { >- "data": "biblio.author", >- "title": _("Author"), >- "searchable": true, >- "orderable": true, >- }, >- { >- "data": "copy_number", >- "title": _("Copy number"), >- "searchable": true, >- "orderable": true, >- }, >- { >- "data": "callnumber", >- "title": _("Callnumber"), >- "searchable": true, >- "orderable": true, >- }, >- { >- "data": "external_id", >- "title": _("Barcode"), >- "searchable": true, >- "orderable": true, >+ var bundle_table = bundles_table.kohaTable( >+ { >+ ajax: { >+ url: bundle_table_url, > }, >- { >- "data": "lost_status:last_seen_date:return_claim.patron", >- "title": _("Status"), >- "searchable": false, >- "orderable": false, >- "render": function(data, type, row, meta) { >- if ( row.lost_status == prefs.BundleLostValue ) { >- let out = '<span class="lost">' + _("Last seen") + ': ' + $date(row.last_seen_date) + '</span>'; >- if ( row.return_claim ) { >- out = out + '<span class="claims_return">' + _("Claims returned by") + ': ' + $patron_to_html( row.return_claim.patron, { display_cardnumber: false, url: true } ) + '</span>'; >+ embed: ["biblio", "return_claim.patron"], >+ order: [[1, "asc"]], >+ columnDefs: [ >+ { >+ targets: [0, 1, 2, 3], >+ render: function (data, type, row, meta) { >+ if (data && type == "display") { >+ return data.escapeHtml(); > } >- return out; >- } >- else if ( row.lost_status !== 0 ) { >- return '<span class="lost">' + _("Lost") + ': ' + row.lost_status + '</span>'; >- } >- return '<span class="available">' + _("Present") + '</span>'; >- } >- }, >- { >- "data": function( row, type, val, meta ) { >- var result; >- if (duedate) { >- 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")); >- } else { >- 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'; >- } >- return result; >+ return data; >+ }, > }, >- "title": _("Actions"), >- "searchable": false, >- "orderable": false, >- "class": "no-export" >- } >- ] >- }, bundle_settings, 1); >- $(".tbundle").on("click", ".remove:not(.disabled)", function(){ >- var bundle_table = $(this).closest('table'); >- var host_itemnumber = bundle_table.data('itemnumber'); >- var component_itemnumber = $(this).data('itemnumber'); >+ ], >+ columns: [ >+ { >+ data: "biblio.title:biblio.subtitle:biblio.medium", >+ title: _("Title"), >+ searchable: true, >+ orderable: true, >+ render: function (data, type, row, meta) { >+ return $biblio_to_html(row.biblio, { link: 1 }); >+ }, >+ }, >+ { >+ data: "biblio.author", >+ title: _("Author"), >+ searchable: true, >+ orderable: true, >+ }, >+ { >+ data: "copy_number", >+ title: _("Copy number"), >+ searchable: true, >+ orderable: true, >+ }, >+ { >+ data: "callnumber", >+ title: _("Callnumber"), >+ searchable: true, >+ orderable: true, >+ }, >+ { >+ data: "external_id", >+ title: _("Barcode"), >+ searchable: true, >+ orderable: true, >+ }, >+ { >+ data: "lost_status:last_seen_date:return_claim.patron", >+ title: _("Status"), >+ searchable: false, >+ orderable: false, >+ render: function (data, type, row, meta) { >+ if (row.lost_status == prefs.BundleLostValue) { >+ let out = '<span class="lost">' + _("Last seen") + ": " + $date(row.last_seen_date) + "</span>"; >+ if (row.return_claim) { >+ out = out + '<span class="claims_return">' + _("Claims returned by") + ": " + $patron_to_html(row.return_claim.patron, { display_cardnumber: false, url: true }) + "</span>"; >+ } >+ return out; >+ } else if (row.lost_status !== 0) { >+ return '<span class="lost">' + _("Lost") + ": " + row.lost_status + "</span>"; >+ } >+ return '<span class="available">' + _("Present") + "</span>"; >+ }, >+ }, >+ { >+ data: function (row, type, val, meta) { >+ var result; >+ if (duedate) { >+ 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")); >+ } else { >+ 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"; >+ } >+ return result; >+ }, >+ title: _("Actions"), >+ searchable: false, >+ orderable: false, >+ class: "no-export", >+ }, >+ ], >+ }, >+ bundle_settings, >+ 1 >+ ); >+ $(".tbundle").on("click", ".remove:not(.disabled)", function () { >+ var bundle_table = $(this).closest("table"); >+ var host_itemnumber = bundle_table.data("itemnumber"); >+ var component_itemnumber = $(this).data("itemnumber"); > var unlink_item_url = "/api/v1/items/" + host_itemnumber + "/bundled_items/" + component_itemnumber; > $.ajax({ > type: "DELETE", > url: unlink_item_url, >- success: function(){ >- bundle_table.DataTable({ 'retrieve': true }).draw(false); >- } >+ success: function () { >+ bundle_table.DataTable({ retrieve: true }).draw(false); >+ }, > }); > }); > >@@ -1915,90 +1938,79 @@ > > var bundle_changed; > var bundle_form_active; >- $("#addToBundleModal").on("shown.bs.modal", function(e){ >+ $("#addToBundleModal").on("shown.bs.modal", function (e) { > var button = $(e.relatedTarget); >- var item_id = button.data('item'); >+ var item_id = button.data("item"); > $("#addResult").replaceWith('<div id="addResult"></div>'); >- $("#addToBundleForm").attr('action', '/api/v1/items/' + item_id + '/bundled_items'); >+ $("#addToBundleForm").attr("action", "/api/v1/items/" + item_id + "/bundled_items"); > $("#external_id").focus(); > bundle_changed = 0; > bundle_form_active = item_id; > }); > >- function addToBundle (url, data) { >+ function addToBundle(url, data) { > /* Send the data using post with external_id */ > var posting = $.post({ > url: url, > data: JSON.stringify(data), > contentType: "application/json; charset=utf-8", >- dataType: "json" >+ dataType: "json", > }); > > const barcode = data.external_id; > const marc_link = data.marc_link; > > /* Report the results */ >- posting.done(function(data) { >- $('#addResult').replaceWith('<div id="addResult" class="alert alert-success">'+_("Success: Added '%s'").format(barcode)+'</div>'); >- $('#external_id').val('').focus(); >+ posting.done(function (data) { >+ $("#addResult").replaceWith('<div id="addResult" class="alert alert-success">' + _("Success: Added '%s'").format(barcode) + "</div>"); >+ $("#external_id").val("").focus(); > bundle_changed = 1; > }); >- posting.fail(function(data) { >- if ( data.status === 409 ) { >+ posting.fail(function (data) { >+ if (data.status === 409) { > var response = data.responseJSON; >- if ( response.error_code === 'already_bundled' ) { >- $('#addResult').replaceWith('<div id="addResult" class="alert alert-warning">'+_("Warning: Item '%s' already attached").format(barcode)+'</div>'); >- } else if (response.error_code === 'bundle_checkout_out') { >- $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Bundle is currently checked out")+'</div>'); >- } else if (response.error_code === 'checked_out') { >+ if (response.error_code === "already_bundled") { >+ $("#addResult").replaceWith('<div id="addResult" class="alert alert-warning">' + _("Warning: Item '%s' already attached").format(barcode) + "</div>"); >+ } else if (response.error_code === "bundle_checkout_out") { >+ $("#addResult").replaceWith('<div id="addResult" class="alert alert-danger">' + _("Failure: Bundle is currently checked out") + "</div>"); >+ } else if (response.error_code === "checked_out") { > const button = $('<button type="button">') >- .addClass('btn btn-xs') >+ .addClass("btn btn-xs") > .text(_("Check in and add to bundle")) >- .on('click', function () { >+ .on("click", function () { > addToBundle(url, { external_id: barcode, force_checkin: true, marc_link: marc_link }); > }); >- $('#addResult') >- .empty() >- .attr('class', 'alert alert-warning') >- .append(__x('Warning: Item {barcode} is checked out', { barcode })) >- .append(' ', button); >- } else if (response.error_code === 'failed_checkin') { >- $('#addResult') >- .empty() >- .attr('class', 'alert alert-danger') >- .append(__x('Failure: Item {barcode} cannot be checked in', { barcode })) >- } else if (response.error_code === 'reserved') { >+ $("#addResult").empty().attr("class", "alert alert-warning").append(__x("Warning: Item {barcode} is checked out", { barcode })).append(" ", button); >+ } else if (response.error_code === "failed_checkin") { >+ $("#addResult").empty().attr("class", "alert alert-danger").append(__x("Failure: Item {barcode} cannot be checked in", { barcode })); >+ } else if (response.error_code === "reserved") { > const button = $('<button type="button">') >- .addClass('btn btn-xs') >+ .addClass("btn btn-xs") > .text(_("Ignore holds and add to bundle")) >- .on('click', function () { >+ .on("click", function () { > addToBundle(url, { external_id: barcode, ignore_holds: true, marc_link: marc_link }); > }); >- $('#addResult') >- .empty() >- .attr('class', 'alert alert-warning') >- .append(__x('Warning: Item {barcode} is on hold', { barcode })) >- .append(' ', button); >+ $("#addResult").empty().attr("class", "alert alert-warning").append(__x("Warning: Item {barcode} is on hold", { barcode })).append(" ", button); > } else { >- $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Item '%s' belongs to another bundle").format(barcode)+'</div>'); >+ $("#addResult").replaceWith('<div id="addResult" class="alert alert-danger">' + _("Failure: Item '%s' belongs to another bundle").format(barcode) + "</div>"); > } >- } else if ( data.status === 404 ) { >- $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Item '%s' not found").format(barcode)+'</div>'); >- } else if ( data.status === 400 ) { >+ } else if (data.status === 404) { >+ $("#addResult").replaceWith('<div id="addResult" class="alert alert-danger">' + _("Failure: Item '%s' not found").format(barcode) + "</div>"); >+ } else if (data.status === 400) { > var response = data.responseJSON; >- if ( response.error_code === "failed_nesting" ) { >- $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Item '%s' is a bundle and bundles cannot be nested").format(barcode)+'</div>'); >+ if (response.error_code === "failed_nesting") { >+ $("#addResult").replaceWith('<div id="addResult" class="alert alert-danger">' + _("Failure: Item '%s' is a bundle and bundles cannot be nested").format(barcode) + "</div>"); > } else { >- $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Check the logs for details.")+'</div>'); >+ $("#addResult").replaceWith('<div id="addResult" class="alert alert-danger">' + _("Failure: Check the logs for details.") + "</div>"); > } > } else { >- $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Check the logs for details.")+'</div>'); >+ $("#addResult").replaceWith('<div id="addResult" class="alert alert-danger">' + _("Failure: Check the logs for details.") + "</div>"); > } >- $('#external_id').val('').focus(); >+ $("#external_id").val("").focus(); > }); > } > >- $("#addToBundleForm").submit(function(event) { >+ $("#addToBundleForm").submit(function (event) { > /* stop form from submitting normally */ > event.preventDefault(); > >@@ -2008,89 +2020,98 @@ > addToBundle(url, data); > }); > >- $("#addToBundleModal").on("hidden.bs.modal", function(e){ >- if ( bundle_changed ) { >- $('#bundle_table_'+bundle_form_active).DataTable({ 'retrieve': true }).ajax.reload(); >+ $("#addToBundleModal").on("hidden.bs.modal", function (e) { >+ if (bundle_changed) { >+ $("#bundle_table_" + bundle_form_active) >+ .DataTable({ retrieve: true }) >+ .ajax.reload(); > } > bundle_form_active = 0; > bundle_changed = 0; > }); > >- $("#removeFromBundleModal").on("shown.bs.modal", function(e){ >+ $("#removeFromBundleModal").on("shown.bs.modal", function (e) { > var button = $(e.relatedTarget); >- var item_id = button.data('item'); >+ var item_id = button.data("item"); > $("#removeResult").replaceWith('<div id="removeResult"></div>'); >- $("#removeFromBundleForm").attr('action', '/api/v1/items/' + item_id + '/bundled_items/'); >+ $("#removeFromBundleForm").attr("action", "/api/v1/items/" + item_id + "/bundled_items/"); > $("#rm_external_id").focus(); > bundle_changed = 0; > bundle_form_active = item_id; > }); > >- $("#removeFromBundleForm").submit(function(event) { >- >+ $("#removeFromBundleForm").submit(function (event) { > /* stop form from submitting normally */ > event.preventDefault(); > > /* get the action attribute from the <form action=""> element */ > var $form = $(this), >- url = $form.attr('action'); >+ url = $form.attr("action"); > >- var barcode = $('#rm_external_id').val(); >+ var barcode = $("#rm_external_id").val(); > > /* Fetch itemnumber using rm_external_id */ >- var itemReq = $.get('/api/v1/items', { q: JSON.stringify({ >- external_id: barcode >- }) }, null, "json"); >+ var itemReq = $.get( >+ "/api/v1/items", >+ { >+ q: JSON.stringify({ >+ external_id: barcode, >+ }), >+ }, >+ null, >+ "json" >+ ); > > var itemnumber; >- itemReq.done(function(data) { >+ itemReq.done(function (data) { > if (data.length === 1) { > itemnumber = data[0].item_id; > > /* Remove link using fetch itemnumber */ >- var deleteReq = $.ajax( url + itemnumber, { >- type : 'DELETE' >+ var deleteReq = $.ajax(url + itemnumber, { >+ type: "DELETE", > }); > > /* Report the results */ >- deleteReq.done(function(data) { >- var barcode = $('#rm_external_id').val(); >- $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-success">'+_("Success: Removed '%s'").format(barcode)+'</div>'); >- $('#rm_external_id').val('').focus(); >+ deleteReq.done(function (data) { >+ var barcode = $("#rm_external_id").val(); >+ $("#removeResult").replaceWith('<div id="removeResult" class="alert alert-success">' + _("Success: Removed '%s'").format(barcode) + "</div>"); >+ $("#rm_external_id").val("").focus(); > bundle_changed = 1; > }); >- deleteReq.fail(function(data) { >- var barcode = $('#rm_external_id').val(); >- if ( data.status === 409 ) { >+ deleteReq.fail(function (data) { >+ var barcode = $("#rm_external_id").val(); >+ if (data.status === 409) { > var response = data.responseJSON; >- if (response.error_code === 'bundle_checkout_out') { >- $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failure: Bundle is currently checked out")+'</div>'); >- } else if ( response.key === "PRIMARY" ) { >- $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-warning">'+_("Warning: Item '%s' already attached").format(barcode)+'</div>'); >+ if (response.error_code === "bundle_checkout_out") { >+ $("#removeResult").replaceWith('<div id="removeResult" class="alert alert-danger">' + _("Failure: Bundle is currently checked out") + "</div>"); >+ } else if (response.key === "PRIMARY") { >+ $("#removeResult").replaceWith('<div id="removeResult" class="alert alert-warning">' + _("Warning: Item '%s' already attached").format(barcode) + "</div>"); > } else { >- $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failure: Item '%s' belongs to another bundle").format(barcode)+'</div>'); >+ $("#removeResult").replaceWith('<div id="removeResult" class="alert alert-danger">' + _("Failure: Item '%s' belongs to another bundle").format(barcode) + "</div>"); > } >- } else if ( data.status === 404 ) { >- $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Item '%s' not found").format(barcode)+'</div>'); >+ } else if (data.status === 404) { >+ $("#addResult").replaceWith('<div id="addResult" class="alert alert-danger">' + _("Failure: Item '%s' not found").format(barcode) + "</div>"); > } else { >- $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failure: Check the logs for details")+'</div>'); >+ $("#removeResult").replaceWith('<div id="removeResult" class="alert alert-danger">' + _("Failure: Check the logs for details") + "</div>"); > } >- $('#rm_external_id').val('').focus(); >+ $("#rm_external_id").val("").focus(); > }); > } else { >- $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failed: Barcode matched more than one item '%s'").format(barcode)+'</div>'); >+ $("#removeResult").replaceWith('<div id="removeResult" class="alert alert-danger">' + _("Failed: Barcode matched more than one item '%s'").format(barcode) + "</div>"); > } > }); >- itemReq.fail(function(data) { >- $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failed: Item not found '%s'").format(barcode)+'</div>'); >- $('#rm_external_id').val('').focus(); >- >+ itemReq.fail(function (data) { >+ $("#removeResult").replaceWith('<div id="removeResult" class="alert alert-danger">' + _("Failed: Item not found '%s'").format(barcode) + "</div>"); >+ $("#rm_external_id").val("").focus(); > }); > }); > >- $("#removeFromBundleModal").on("hidden.bs.modal", function(e){ >- if ( bundle_changed ) { >- $('#bundle_table_'+bundle_form_active).DataTable({ 'retrieve': true }).ajax.reload(); >+ $("#removeFromBundleModal").on("hidden.bs.modal", function (e) { >+ if (bundle_changed) { >+ $("#bundle_table_" + bundle_form_active) >+ .DataTable({ retrieve: true }) >+ .ajax.reload(); > } > bundle_form_active = 0; > bundle_changed = 0; >@@ -2098,14 +2119,12 @@ > // End bundle handling > } > </script> >- > [% IF Koha.Preference('AcquisitionDetails') %] > <script> > var table_settings = [% TablesSettings.GetTableSettings('catalogue', 'detail', 'acquisitiondetails-table', 'json') | $raw %]; > </script> >- > <script> >- $(document).ready(function() { >+ $(document).ready(function () { > var acquisitiondetails_table = $("#orders").kohaTable( > { > dom: 'C<"top pager"ilpfB><"#filter_c">tr<"bottom pager"ip>', >@@ -2121,7 +2140,7 @@ > > [% IF suggestions.count %] > <script> >- $(document).ready(function() { >+ $(document).ready(function () { > $("#suggestions").kohaTable({ > pagingType: "full", > }); >@@ -2133,10 +2152,8 @@ > <script> > var comment_table_settings = [% TablesSettings.GetTableSettings('catalogue', 'detail', 'comments-table', 'json') | $raw %]; > </script> >- > <script> >- $(document).ready(function() { >- >+ $(document).ready(function () { > var comments_table = $("#comments_table").kohaTable( > { > paging: false, >@@ -2151,264 +2168,265 @@ > > [% IF found1 && Koha.Preference('RetainCatalogSearchTerms') %] > <script> >- $(document).ready(function() { >+ $(document).ready(function () { > var search_index = localStorage.getItem("cat_search_pulldown_selection"); > var search_value = localStorage.getItem("searchbox_value"); >- if ( search_index ){ $('#cat-search-block select.advsearch').val(search_index)}; >- if ( search_value ){ $('#cat-search-block #search-form').val(search_value)}; >+ if (search_index) { >+ $("#cat-search-block select.advsearch").val(search_index); >+ } >+ if (search_value) { >+ $("#cat-search-block #search-form").val(search_value); >+ } > }); > </script> > [% END %] > > [% IF Koha.Preference('EnableItemGroups') %] > <script> >- $(document).ready(function() { >- >- // Load item groups table >- var itemGroupsTable = $("#items-group-table").kohaTable({ >- autoWidth: false, >- dom: '<"top pager"ilp>t<"bottom pager"ip>r', >- columns: [ >- { >- data: "display_order", >- title: _("Display order"), >- searchable: true, >- orderable: true, >- }, >- { >- data: "description", >- title: _("Description"), >- searchable: true, >- orderable: true, >- }, >- { >- data: function( oObj ) { >- if (permissions.CAN_user_editcatalogue_manage_item_groups){ >- return `<button class='item-group-edit btn btn-default btn-xs' data-item-group-id='${oObj.item_group_id}'> >+ $(document).ready(function () { >+ // Load item groups table >+ var itemGroupsTable = $("#items-group-table").kohaTable({ >+ autoWidth: false, >+ dom: '<"top pager"ilp>t<"bottom pager"ip>r', >+ columns: [ >+ { >+ data: "display_order", >+ title: _("Display order"), >+ searchable: true, >+ orderable: true, >+ }, >+ { >+ data: "description", >+ title: _("Description"), >+ searchable: true, >+ orderable: true, >+ }, >+ { >+ data: function (oObj) { >+ if (permissions.CAN_user_editcatalogue_manage_item_groups) { >+ return ( >+ `<button class='item-group-edit btn btn-default btn-xs' data-item-group-id='${oObj.item_group_id}'> > <i class="fa-solid fa-pencil" aria-hidden="true"></i> ${_("Edit")} >+ </button>` + >+ " " + >+ `<button class='item-group-delete btn btn-default btn-xs' data-item-group-id='${oObj.item_group_id}'> >+ <i class='fa fa-trash-can'></i> ${"Delete"} > </button>` >- + ' ' >- + `<button class='item-group-delete btn btn-default btn-xs' data-item-group-id='${oObj.item_group_id}'> >- <i class='fa fa-trash-can'></i> ${('Delete')} >- </button>`; >- } else { >- return ""; >- } >+ ); >+ } else { >+ return ""; >+ } >+ }, >+ searchable: false, >+ orderable: false, > }, >- searchable: false, >- orderable: false, >+ ], >+ paging: false, >+ ajax: { url: `/api/v1/biblios/${biblionumber}/item_groups?_per_page=-1` }, >+ }); >+ >+ // Create new item groups >+ $(".item-group-create").on("click", function () { >+ $("#modal-item-group-create-form-description").val(""); >+ $("#modal-item-group-create-submit").removeAttr("disabled"); >+ $("#modal-item-group-create").modal("show"); >+ }); >+ >+ $("#modal-item-group-create-form").validate({ >+ submitHandler: function (form) { >+ $.ajax({ >+ url: `/api/v1/biblios/${biblionumber}/item_groups`, >+ headers: { "x-koha-embed": "items" }, >+ success: function (item_groups) { >+ $("#modal-item-group-create-submit").attr("disabled", "disabled"); >+ >+ var settings = { >+ url: `/api/v1/biblios/${biblionumber}/item_groups`, >+ method: "POST", >+ headers: { >+ "Content-Type": "application/json", >+ }, >+ data: JSON.stringify({ >+ description: $("#modal-item-group-create-form-description").val(), >+ display_order: $("#modal-item-group-create-form-display_order").val(), >+ }), >+ }; >+ >+ $.ajax(settings) >+ .done(function (response) { >+ $("#item-group-add-form-select").append( >+ $("<option>", { >+ value: response.item_group_id, >+ text: response.description, >+ }) >+ ); >+ >+ $("#modal-item-group-create").modal("hide"); >+ if (item_groups.length == 0) { >+ // This bib has no previous item groups, reload the page >+ window.location.replace(`/cgi-bin/koha/catalogue/detail.pl?biblionumber=${biblionumber}`); >+ } else { >+ // Has other item groups, just reload the table >+ itemGroupsTable.api().ajax.reload(); >+ } >+ }) >+ .fail(function (err) { >+ var message = err.responseJSON.error; >+ alert(message); >+ }); >+ }, >+ }); > }, >- ], >- paging: false, >- ajax: { url: `/api/v1/biblios/${biblionumber}/item_groups?_per_page=-1` }, >- }); >+ }); > >- // Create new item groups >- $('.item-group-create').on('click', function(){ >- $('#modal-item-group-create-form-description').val(""); >- $('#modal-item-group-create-submit').removeAttr('disabled'); >- $('#modal-item-group-create').modal('show'); >- }); >+ $("#modal-item-group-create").on("shown.bs.modal", function () { >+ $("#modal-item-group-create-form-description").focus(); >+ }); > >- $("#modal-item-group-create-form").validate({ >- submitHandler: function(form) { >- $.ajax({ >- url: `/api/v1/biblios/${biblionumber}/item_groups`, >- headers: { "x-koha-embed": "items" }, >- success: function(item_groups){ >- $('#modal-item-group-create-submit').attr('disabled', 'disabled'); >- >- var settings = { >- "url": `/api/v1/biblios/${biblionumber}/item_groups`, >- "method": "POST", >- "headers": { >- "Content-Type": "application/json" >- }, >- "data": JSON.stringify( >- { >- "description": $("#modal-item-group-create-form-description").val(), >- "display_order": $("#modal-item-group-create-form-display_order").val(), >- } >- ), >- }; >- >- $.ajax(settings) >+ // Edit existing item groups >+ $("body").on("click", ".item-group-edit", function () { >+ const item_group_id = $(this).data("item-group-id"); >+ const url = `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`; >+ $.get(url, function (data) { >+ $("#modal-item-group-edit-form-description").val(data.description); >+ $("#modal-item-group-edit-form-display_order").val(data.display_order); >+ $("#modal-item-group-edit-submit").data("item-group-id", item_group_id); >+ $("#modal-item-group-edit-submit").removeAttr("disabled"); >+ $("#modal-item-group-edit").modal("show"); >+ }); >+ }); >+ >+ $("#modal-item-group-edit-form").validate({ >+ submitHandler: function (form) { >+ $("#modal-item-group-edit-submit").attr("disabled", "disabled"); >+ >+ const item_group_id = $("#modal-item-group-edit-submit").data("item-group-id"); >+ const url = `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`; >+ >+ var settings = { >+ url: url, >+ method: "PUT", >+ headers: { >+ "Content-Type": "application/json", >+ }, >+ data: JSON.stringify({ >+ description: $("#modal-item-group-edit-form-description").val(), >+ display_order: $("#modal-item-group-edit-form-display_order").val(), >+ }), >+ }; >+ >+ $.ajax(settings) > .done(function (response) { >- $('#item-group-add-form-select').append($('<option>', { >- value: response.item_group_id, >- text: response.description >- })); >- >- $('#modal-item-group-create').modal('hide'); >- if ( item_groups.length == 0 ) { >- // This bib has no previous item groups, reload the page >- window.location.replace(`/cgi-bin/koha/catalogue/detail.pl?biblionumber=${biblionumber}`); >- } else { >- // Has other item groups, just reload the table >- itemGroupsTable.api().ajax.reload(); >- } >+ $("#modal-item-group-edit").modal("hide"); >+ itemGroupsTable.api().ajax.reload(); > }) >- .fail(function(err) { >+ .fail(function (err) { > var message = err.responseJSON.error; > alert(message); > }); >- } >- }); >- } >- }); >+ }, >+ }); > >- $('#modal-item-group-create').on('shown.bs.modal', function () { >- $('#modal-item-group-create-form-description').focus(); >- }); >+ $("#modal-item-group-edit").on("shown.bs.modal", function () { >+ $("#modal-item-group-edit-form-description").focus(); >+ }); > >- // Edit existing item groups >- $('body').on( 'click', '.item-group-edit', function(){ >- const item_group_id = $(this).data('item-group-id'); >- const url = `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`; >- $.get( url, function( data ) { >- $('#modal-item-group-edit-form-description').val( data.description ); >- $('#modal-item-group-edit-form-display_order').val( data.display_order ); >- $('#modal-item-group-edit-submit').data('item-group-id', item_group_id ); >- $('#modal-item-group-edit-submit').removeAttr('disabled'); >- $('#modal-item-group-edit').modal('show'); >+ // Delete existing item groups >+ $("body").on("click", ".item-group-delete", function () { >+ const item_group_id = $(this).data("item-group-id"); >+ $("#modal-item-group-delete-submit").data("item-group-id", item_group_id); >+ $("#modal-item-group-delete-submit").removeAttr("disabled"); >+ $("#modal-item-group-delete").modal("show"); > }); >- }); >+ $("#modal-item-group-delete-submit").on("click", function () { >+ $("#modal-item-group-delete-submit").attr("disabled", "disabled"); >+ const item_group_id = $("#modal-item-group-delete-submit").data("item-group-id"); > >- $("#modal-item-group-edit-form").validate({ >- submitHandler: function(form) { >- $('#modal-item-group-edit-submit').attr('disabled', 'disabled'); >+ $.ajax({ >+ url: `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`, >+ headers: { "x-koha-embed": "items" }, >+ success: function (item_group_data) { >+ $.ajax({ >+ url: `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`, >+ method: "DELETE", >+ }) >+ .done(function (response) { >+ $("#modal-item-group-delete").modal("hide"); >+ $(`#item-group-add-form-select option[value='${item_group_id}']`).remove(); >+ if (item_group_data.items === null) { >+ // No items for this item group, we can just refresh the table >+ itemGroupsTable.api().ajax.reload(); >+ } else { >+ // This item group had items attached to it, we need to reload the page >+ window.location.replace(`/cgi-bin/koha/catalogue/detail.pl?biblionumber=${biblionumber}`); >+ } >+ }) >+ .fail(function (err) { >+ var message = err.responseJSON.error; >+ alert(message); >+ }); >+ }, >+ }); >+ }); > >- const item_group_id = $('#modal-item-group-edit-submit').data('item-group-id'); >- const url = `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`; >+ // Add item(s) to a item group >+ $(".itemselection_action_item_group_set").on("click", function () { >+ $("#modal-item-group-set").modal("show"); >+ }); > >- var settings = { >- "url": url, >- "method": "PUT", >- "headers": { >- "Content-Type": "application/json" >- }, >- "data": JSON.stringify( >- { >- "description": $("#modal-item-group-edit-form-description").val(), >- "display_order": $("#modal-item-group-edit-form-display_order").val(), >- } >- ), >- }; >- >- $.ajax(settings) >- .done(function (response) { >- $('#modal-item-group-edit').modal('hide'); >- itemGroupsTable.api().ajax.reload(); >- }) >- .fail(function(err) { >- var message = err.responseJSON.error; >- alert(message); >- }); >- } >- }); >+ $("#modal-item-group-set-form").validate({ >+ submitHandler: function (form) { >+ $("#modal-item-group-set-submit").attr("disabled", "disabled"); > >- $('#modal-item-group-edit').on('shown.bs.modal', function () { >- $('#modal-item-group-edit-form-description').focus(); >- }) >+ const item_group_id = $("#item-group-add-form-select").val(); > >- // Delete existing item groups >- $('body').on( 'click', '.item-group-delete', function(){ >- const item_group_id = $(this).data('item-group-id'); >- $('#modal-item-group-delete-submit').data('item-group-id', item_group_id ); >- $('#modal-item-group-delete-submit').removeAttr('disabled'); >- $('#modal-item-group-delete').modal('show'); >- }); >- $("#modal-item-group-delete-submit").on('click', function(){ >- $('#modal-item-group-delete-submit').attr('disabled', 'disabled'); >- const item_group_id = $("#modal-item-group-delete-submit").data('item-group-id'); >- >- $.ajax({ >- url: `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`, >- headers: { "x-koha-embed": "items" }, >- success: function(item_group_data){ >- $.ajax({ >- "url": `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`, >- "method": "DELETE", >- }) >- .done(function (response) { >- $('#modal-item-group-delete').modal('hide'); >- $(`#item-group-add-form-select option[value='${item_group_id}']`).remove(); >- if ( item_group_data.items === null ) { >- // No items for this item group, we can just refresh the table >- itemGroupsTable.api().ajax.reload(); >- } else { >- // This item group had items attached to it, we need to reload the page >- window.location.replace(`/cgi-bin/koha/catalogue/detail.pl?biblionumber=${biblionumber}`); >- } >- }) >- .fail(function(err) { >- var message = err.responseJSON.error; >- alert(message); >+ let itemnumbers = new Array(); >+ $("input[name='itemnumber'][type='checkbox']:checked").each(function () { >+ const itemnumber = $(this).val(); >+ itemnumbers.push(itemnumber); > }); >- } >- }); >- }); >+ if (itemnumbers.length > 0) { >+ let url = "/cgi-bin/koha/catalogue/detail.pl?op=set_item_group"; >+ url += "&itemnumber=" + itemnumbers.join("&itemnumber="); >+ url += "&biblionumber=" + biblionumber; >+ url += `&item_group_id=${item_group_id}`; > >- // Add item(s) to a item group >- $('.itemselection_action_item_group_set').on('click', function(){ >- $('#modal-item-group-set').modal('show'); >- }); >+ window.location.replace(url); >+ } >+ >+ $("#modal-item-group-set").modal("hide"); >+ }, >+ }); > >- $("#modal-item-group-set-form").validate({ >- submitHandler: function(form) { >- $('#modal-item-group-set-submit').attr('disabled', 'disabled'); >+ // Remove item(s) from an item group >+ $(".itemselection_action_item_group_unset").on("click", function () { >+ $("#modal-item-group-unset").modal("show"); >+ }); > >- const item_group_id = $('#item-group-add-form-select').val(); >+ $("#modal-item-group-unset-submit").on("click", function () { >+ $("#modal-item-group-unset-submit").attr("disabled", "disabled"); > > let itemnumbers = new Array(); >- $("input[name='itemnumber'][type='checkbox']:checked").each(function() { >+ $("input[name='itemnumber'][type='checkbox']:checked").each(function () { > const itemnumber = $(this).val(); >- itemnumbers.push( itemnumber ); >+ itemnumbers.push(itemnumber); > }); > if (itemnumbers.length > 0) { >- let url = '/cgi-bin/koha/catalogue/detail.pl?op=set_item_group'; >- url += '&itemnumber=' + itemnumbers.join('&itemnumber='); >- url += '&biblionumber=' + biblionumber; >- url += `&item_group_id=${item_group_id}`; >+ let url = "/cgi-bin/koha/catalogue/detail.pl?op=unset_item_group"; >+ url += "&itemnumber=" + itemnumbers.join("&itemnumber="); >+ url += "&biblionumber=" + biblionumber; > > window.location.replace(url); > } > >- $('#modal-item-group-set').modal('hide'); >- } >- }); >- >- // Remove item(s) from an item group >- $('.itemselection_action_item_group_unset').on('click', function(){ >- $('#modal-item-group-unset').modal('show'); >- }); >- >- $("#modal-item-group-unset-submit").on('click', function(){ >- $('#modal-item-group-unset-submit').attr('disabled', 'disabled'); >- >- let itemnumbers = new Array(); >- $("input[name='itemnumber'][type='checkbox']:checked").each(function() { >- const itemnumber = $(this).val(); >- itemnumbers.push( itemnumber ); >+ $("#modal-item-group-unset").modal("hide"); > }); >- if (itemnumbers.length > 0) { >- let url = '/cgi-bin/koha/catalogue/detail.pl?op=unset_item_group'; >- url += '&itemnumber=' + itemnumbers.join('&itemnumber='); >- url += '&biblionumber=' + biblionumber; >- >- window.location.replace(url); >- } >- >- $('#modal-item-group-unset').modal('hide'); > }); >- >- }); > </script> > [% END # /IF EnableItemGroups %] >- > <script> >- $(".delete-comment").on("click", function(){ >- return confirm( _("Are you sure you want to delete this comment?") ); >+ $(".delete-comment").on("click", function () { >+ return confirm(_("Are you sure you want to delete this comment?")); > }); > </script> > [% CoverImagePlugins | $raw %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/issuehistory.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/issuehistory.tt >index efa29b5d64d..ae1e270cede 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/issuehistory.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/issuehistory.tt >@@ -134,9 +134,8 @@ > table_settings['columns'].splice(0,1); > [% END %] > </script> >- > <script> >- $(document).ready(function() { >+ $(document).ready(function () { > var table = $("#table_issues").kohaTable( > { > dom: 'C<"top pager"ilpfB><"#filter_c">tr<"bottom pager"ip>', >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/itemsearch.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/itemsearch.tt >index 5ac14fb05ba..76d7b16d9b6 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/itemsearch.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/itemsearch.tt >@@ -439,14 +439,16 @@ > return av; > } ); > </script> >- > <script> >- function showItemSelections( number ){ >+ function showItemSelections(number) { > let caret = ' <span class="caret">'; >- if( number > 0 ){ >- $("#table_search_selections").show().find("span").html(_("Items selected: ") + number ); >+ if (number > 0) { >+ $("#table_search_selections") >+ .show() >+ .find("span") >+ .html(_("Items selected: ") + number); > $("#batch_mod_menu").removeClass("disabled").prop("disabled", false); >- $("#export-button").html(_("Export selected results (%s) to").format ( number ) + caret); >+ $("#export-button").html(_("Export selected results (%s) to").format(number) + caret); > } else { > $("#table_search_selections").hide(); > $("#batch_mod_menu").prop("disabled", true).addClass("disabled"); >@@ -456,22 +458,22 @@ > } > > function loadAuthorisedValuesSelect(select) { >- var selected = select.find('option:selected'); >- var category = selected.data('authorised-values-category'); >- var form_field_value = select.siblings('.form-field-value'); >+ var selected = select.find("option:selected"); >+ var category = selected.data("authorised-values-category"); >+ var form_field_value = select.siblings(".form-field-value"); > if (category && category in authorised_values) { > var values = authorised_values[category]; > var html = '<select name="q" class="form-field-value">\n'; > for (i in values) { > var value = values[i]; >- html += '<option value="' + value.authorised_value + '">' + value.lib + '</option>\n'; >+ html += '<option value="' + value.authorised_value + '">' + value.lib + "</option>\n"; > } >- html += '</select>\n'; >+ html += "</select>\n"; > var new_form_field_value = $(html); > new_form_field_value.val(form_field_value.val()); > form_field_value.replaceWith(new_form_field_value); > } else { >- if (form_field_value.prop('tagName').toLowerCase() == 'select') { >+ if (form_field_value.prop("tagName").toLowerCase() == "select") { > html = '<input name="q" type="text" class="form-field-value" />'; > var new_form_field_value = $(html); > form_field_value.replaceWith(new_form_field_value); >@@ -479,24 +481,24 @@ > } > } > >- function addNewField( link ) { >- var form_field = $('div.form-field-select-text').last(); >+ function addNewField(link) { >+ var form_field = $("div.form-field-select-text").last(); > var copy = form_field.clone(true); >- copy.find('input,select').not('[type="hidden"]').each(function() { >- $(this).val(''); >- }); >- copy.find('.form-field-conjunction').prop('disabled', false).val('and'); >+ copy.find("input,select") >+ .not('[type="hidden"]') >+ .each(function () { >+ $(this).val(""); >+ }); >+ copy.find(".form-field-conjunction").prop("disabled", false).val("and"); > form_field.after(copy); > link.remove(); >- copy.find('select.form-field-column').change(); >+ copy.find("select.form-field-column").change(); > } > > function exportItems(format) { > let item_search_selections = JSON.parse(localStorage.getItem("item_search_selections")) || []; > if (item_search_selections.length > 0) { >- let inputs = item_search_selections.map(itemnumber => >- `<input type="hidden" name="itemnumber" value="${itemnumber}">` >- ).join(''); >+ let inputs = item_search_selections.map(itemnumber => `<input type="hidden" name="itemnumber" value="${itemnumber}">`).join(""); > > const csrf_token = $('meta[name="csrf-token"]').attr("content"); > let form = $(` >@@ -508,24 +510,24 @@ > </form> > `); > >- $('body').append(form); >+ $("body").append(form); > form.submit(); > form.remove(); > } else { >- $('#format-' + format).prop('checked', true); >- $('#itemsearchform').submit(); >- $('#format-html').prop('checked', true); >+ $("#format-" + format).prop("checked", true); >+ $("#itemsearchform").submit(); >+ $("#format-html").prop("checked", true); > } > } > >- function prepSelections(){ >- let item_search_selections = JSON.parse( localStorage.getItem("item_search_selections") ) || []; >- if( item_search_selections.length > 0 ){ >- showItemSelections( item_search_selections.length ); >- $("#item_search input[type='checkbox']").each(function(){ >+ function prepSelections() { >+ let item_search_selections = JSON.parse(localStorage.getItem("item_search_selections")) || []; >+ if (item_search_selections.length > 0) { >+ showItemSelections(item_search_selections.length); >+ $("#item_search input[type='checkbox']").each(function () { > var itemnumber = $(this).val(); >- if( item_search_selections.indexOf( itemnumber ) >= 0 ){ >- $(this).prop("checked", true ); >+ if (item_search_selections.indexOf(itemnumber) >= 0) { >+ $(this).prop("checked", true); > } > }); > } >@@ -533,132 +535,194 @@ > > function getParams($form) { > var params = []; >- $form.find('select:not(:disabled) option:selected,input[type="text"]:not(:disabled),input[type="hidden"]:not(:disabled),input[type="radio"]:checked').each(function() { >- if ( $(this).prop('tagName').toLowerCase() == 'option' ) { >- var name = $(this).parents('select').first().attr('name'); >+ $form.find('select:not(:disabled) option:selected,input[type="text"]:not(:disabled),input[type="hidden"]:not(:disabled),input[type="radio"]:checked').each(function () { >+ if ($(this).prop("tagName").toLowerCase() == "option") { >+ var name = $(this).parents("select").first().attr("name"); > var value = $(this).val(); >- params.push({ 'name': name, 'value': value }); >+ params.push({ name: name, value: value }); > } else { >- params.push({ 'name': $(this).attr('name'), 'value': $(this).val() }); >+ params.push({ name: $(this).attr("name"), value: $(this).val() }); > } > }); > return params; > } > > function submitForm($form) { >- var tr = '' >- + ' <tr>' >- + ' <th id="items_checkbox" data-colname="itemsearch_checkbox"></th>' >- + ' <th id="items_title" data-colname="title">' + _("Title") + '</th>' >- + ' <th id="items_pubdate" data-colname="publication_date">' + _("Publication date") + '</th>' >- + ' <th id="items_publisher" data-colname="publisher">' + _("Publisher") + '</th>' >- + ' <th id="items_collection" data-colname="collection">' + _("Collection") + '</th>' >- + ' <th id="items_barcode" data-colname="barcode">' + _("Barcode") + '</th>' >- + ' <th id="items_itemnumber" data-colname="item_number">' + _("Item number") + '</th>' >- + ' <th id="items_enumchron" data-colname="serial_enumeration">' + _("Serial enumeration") + '</th>' >- + ' <th id="items_callno" data-colname="call_number">' + _("Call number") + '</th>' >- + ' <th id="items_homebranch" data-colname="home_library">' + _("Home library") + '</th>' >- + ' <th id="items_holdingbranch" data-colname="current_library">' + _("Current library") + '</th>' >- + ' <th id="items_location" data-colname="shelving_location">' + _("Shelving location") + '</th>' >- + ' <th id="items_itype" data-colname="item_type">' + _("Itemtype") + '</th>' >- + ' <th id="item_inventoryno" data-colname="inventory_number">' + _("Inventory number") + '</th>' >- + ' <th id="items_status" data-colname="notforloan_status">' + _("Not for loan status") + '</th>' >- + ' <th id="items_itemlost" data-colname="lost_status">' + _("Lost status") + '</th>' >- + ' <th id="items_widthdrawn" data-colname="withdrawn_status">' + _("Withdrawn status") + '</th>' >- + ' <th id="items_damaged" data-colname="damaged_status">' + _("Damaged status") + '</th>' >- + ' <th id="items_dateaccessioned" data-colname="dateaccessioned">' + _("Date accessioned") + '</th>' >- + ' <th id="items_checkouts" data-colname="checkouts">' + _("Checkouts") + '</th>' >- + ' <th id="items_datelastborrowed" data-colname="last_checkout_date">' + _("Last checkout date") + '</th>' >- + ' <th id="items_date_due" data-colname="due_date">' + _("Due date") + '</th>' >- + ' <th id="items_actions" data-colname="actions">' + _("Actions") + '</th>' >- + ' </tr>'; >- >- var table = '' >- + '<div class="page-section">' >- + ' <div id="searchheader" class="searchheader">' >- + ' <a href="#" id="select_all" class="btn btn-link"><i class="fa fa-check"></i> ' >- + _("Select visible rows") >- + ' </a> | ' >- + ' <a href="#" id="clear_all" class="btn btn-link"><i class="fa fa-times"></i> ' >- + _("Clear selection") >- + ' </a>' >- + ' <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>' >- + ' <ul class="dropdown-menu">' >- + ' <li><a class="dropdown-item" href="#" id="csvExportLink">' + _("CSV") + '</a></li>' >- + ' <li><a class="dropdown-item" href="#" id="barcodesExportLink">' + _("Barcode file") + '</a></li>' >- + ' </ul>' >- + ' </div>'; >- if ( permissions.CAN_user_tools_items_batchmod || permissions.CAN_user_tools_items_batchdel ){ >- table += '' >- + ' <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>' >- + ' <ul class="dropdown-menu" aria-labelledby="batch_mod_menu">'; >- if ( permissions.CAN_user_tools_items_batchmod ){ >- table += '' >- + ' <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>'; >+ var tr = >+ "" + >+ " <tr>" + >+ ' <th id="items_checkbox" data-colname="itemsearch_checkbox"></th>' + >+ ' <th id="items_title" data-colname="title">' + >+ _("Title") + >+ "</th>" + >+ ' <th id="items_pubdate" data-colname="publication_date">' + >+ _("Publication date") + >+ "</th>" + >+ ' <th id="items_publisher" data-colname="publisher">' + >+ _("Publisher") + >+ "</th>" + >+ ' <th id="items_collection" data-colname="collection">' + >+ _("Collection") + >+ "</th>" + >+ ' <th id="items_barcode" data-colname="barcode">' + >+ _("Barcode") + >+ "</th>" + >+ ' <th id="items_itemnumber" data-colname="item_number">' + >+ _("Item number") + >+ "</th>" + >+ ' <th id="items_enumchron" data-colname="serial_enumeration">' + >+ _("Serial enumeration") + >+ "</th>" + >+ ' <th id="items_callno" data-colname="call_number">' + >+ _("Call number") + >+ "</th>" + >+ ' <th id="items_homebranch" data-colname="home_library">' + >+ _("Home library") + >+ "</th>" + >+ ' <th id="items_holdingbranch" data-colname="current_library">' + >+ _("Current library") + >+ "</th>" + >+ ' <th id="items_location" data-colname="shelving_location">' + >+ _("Shelving location") + >+ "</th>" + >+ ' <th id="items_itype" data-colname="item_type">' + >+ _("Itemtype") + >+ "</th>" + >+ ' <th id="item_inventoryno" data-colname="inventory_number">' + >+ _("Inventory number") + >+ "</th>" + >+ ' <th id="items_status" data-colname="notforloan_status">' + >+ _("Not for loan status") + >+ "</th>" + >+ ' <th id="items_itemlost" data-colname="lost_status">' + >+ _("Lost status") + >+ "</th>" + >+ ' <th id="items_widthdrawn" data-colname="withdrawn_status">' + >+ _("Withdrawn status") + >+ "</th>" + >+ ' <th id="items_damaged" data-colname="damaged_status">' + >+ _("Damaged status") + >+ "</th>" + >+ ' <th id="items_dateaccessioned" data-colname="dateaccessioned">' + >+ _("Date accessioned") + >+ "</th>" + >+ ' <th id="items_checkouts" data-colname="checkouts">' + >+ _("Checkouts") + >+ "</th>" + >+ ' <th id="items_datelastborrowed" data-colname="last_checkout_date">' + >+ _("Last checkout date") + >+ "</th>" + >+ ' <th id="items_date_due" data-colname="due_date">' + >+ _("Due date") + >+ "</th>" + >+ ' <th id="items_actions" data-colname="actions">' + >+ _("Actions") + >+ "</th>" + >+ " </tr>"; >+ >+ var table = >+ "" + >+ '<div class="page-section">' + >+ ' <div id="searchheader" class="searchheader">' + >+ ' <a href="#" id="select_all" class="btn btn-link"><i class="fa fa-check"></i> ' + >+ _("Select visible rows") + >+ " </a> | " + >+ ' <a href="#" id="clear_all" class="btn btn-link"><i class="fa fa-times"></i> ' + >+ _("Clear selection") + >+ " </a>" + >+ ' <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>" + >+ ' <ul class="dropdown-menu">' + >+ ' <li><a class="dropdown-item" href="#" id="csvExportLink">' + >+ _("CSV") + >+ "</a></li>" + >+ ' <li><a class="dropdown-item" href="#" id="barcodesExportLink">' + >+ _("Barcode file") + >+ "</a></li>" + >+ " </ul>" + >+ " </div>"; >+ if (permissions.CAN_user_tools_items_batchmod || permissions.CAN_user_tools_items_batchdel) { >+ table += >+ "" + >+ ' <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>" + >+ ' <ul class="dropdown-menu" aria-labelledby="batch_mod_menu">'; >+ if (permissions.CAN_user_tools_items_batchmod) { >+ table += >+ "" + >+ ' <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>"; > } >- if ( permissions.CAN_user_tools_items_batchdel ){ >- table += '' >- + ' <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>'; >+ if (permissions.CAN_user_tools_items_batchdel) { >+ table += >+ "" + >+ ' <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>"; > } >- table += '' >- + ' </ul>' >- + ' </div>'; >+ table += "" + " </ul>" + " </div>"; > } >- table += '' >- + ' <div id="table_search_selections" class="btn-group" style="display:none;">' >- + ' <span></span>' >- + ' <a href="#" id="clear-row-selection"><i class="fa fa-times"></i> ' + _("Clear") + '</a>' >- + ' </div>' >- + ' </div>' >- + ' <table id="item_search">' >- + ' <thead>' + tr + '</thead>' >- + ' <tbody></tbody>' >- + ' </table>' >- + '</div>'; >- >- var advSearchLink = $('<a>') >- .attr('href', '/cgi-bin/koha/catalogue/search.pl') >- .html(_("Go to advanced search")); >- >- var editSearchLink = $('<a>') >- .attr('href', '#') >- .html("<i class='fa fa-pencil'></i> " + _("Edit search") ) >- .addClass('btn btn-default') >- .on('click', function(e) { >+ table += >+ "" + >+ ' <div id="table_search_selections" class="btn-group" style="display:none;">' + >+ " <span></span>" + >+ ' <a href="#" id="clear-row-selection"><i class="fa fa-times"></i> ' + >+ _("Clear") + >+ "</a>" + >+ " </div>" + >+ " </div>" + >+ ' <table id="item_search">' + >+ " <thead>" + >+ tr + >+ "</thead>" + >+ " <tbody></tbody>" + >+ " </table>" + >+ "</div>"; >+ >+ var advSearchLink = $("<a>").attr("href", "/cgi-bin/koha/catalogue/search.pl").html(_("Go to advanced search")); >+ >+ var editSearchLink = $("<a>") >+ .attr("href", "#") >+ .html("<i class='fa fa-pencil'></i> " + _("Edit search")) >+ .addClass("btn btn-default") >+ .on("click", function (e) { > e.preventDefault(); >- $('#item-search-block').show(); >+ $("#item-search-block").show(); > }); > >- var getShareableLink = $('<a>') >- .attr('href', '#') >- .html("<i class='fa fa-copy'></i> " + _("Copy shareable link") ) >- .addClass('btn btn-default') >- .on('click', function(e) { >+ var getShareableLink = $("<a>") >+ .attr("href", "#") >+ .html("<i class='fa fa-copy'></i> " + _("Copy shareable link")) >+ .addClass("btn btn-default") >+ .on("click", function (e) { > e.preventDefault(); >- var params = getParams( $('#itemsearchform') ); >+ var params = getParams($("#itemsearchform")); > params = params.map(p => { >- if(p.name === 'format') { >- return { ...p, value: 'shareable' }; >+ if (p.name === "format") { >+ return { ...p, value: "shareable" }; > } > return p; >- }) >- var url = window.location.origin + window.location.pathname + '?' + $.param(params); >+ }); >+ var url = window.location.origin + window.location.pathname + "?" + $.param(params); > navigator.clipboard.writeText(url); >- $(this).tooltip({trigger: 'manual', title: _("Copied!")}).tooltip('show'); >+ $(this) >+ .tooltip({ trigger: "manual", title: _("Copied!") }) >+ .tooltip("show"); > }); > >- var results_heading = $('<div>').addClass('results-heading') >+ var results_heading = $("<div>") >+ .addClass("results-heading") > .append("<h1>" + _("Item search results") + "</h1>") >- .append($('<p>').append(advSearchLink)) >- .append($('<div>') >- .addClass("btn-toolbar") >- .attr("id","toolbar") >- .append(editSearchLink) >- .append(getShareableLink) >- ); >- $('#results-wrapper').empty() >- .append(results_heading) >- .append(table); >+ .append($("<p>").append(advSearchLink)) >+ .append($("<div>").addClass("btn-toolbar").attr("id", "toolbar").append(editSearchLink).append(getShareableLink)); >+ $("#results-wrapper").empty().append(results_heading).append(table); > > var params = getParams($form); > >@@ -673,62 +737,68 @@ > av_damaged: all_damageds, > }; > >- $('#item_search').kohaTable( { >- bKohaColumnsUseNames: true, >- destroy: true, >- serverSide: true, >- processing: true, >- ajax: { >- url: '/cgi-bin/koha/catalogue/itemsearch.pl', >- data: function ( d ) { >- for (i in params) { >- if(d[params[i].name]){ >- d[params[i].name] = [].concat(d[params[i].name], params[i].value); >- }else{ >- d[params[i].name] = params[i].value; >+ $("#item_search").kohaTable( >+ { >+ bKohaColumnsUseNames: true, >+ destroy: true, >+ serverSide: true, >+ processing: true, >+ ajax: { >+ url: "/cgi-bin/koha/catalogue/itemsearch.pl", >+ data: function (d) { >+ for (i in params) { >+ if (d[params[i].name]) { >+ d[params[i].name] = [].concat(d[params[i].name], params[i].value); >+ } else { >+ d[params[i].name] = params[i].value; >+ } > } >- } >- d.format = 'json'; >- d.columns = JSON.stringify( d.columns ); >- return d; >- } >- }, >- bKohaAjaxSVC: true, >- dom: 'C<"top pager"ilpB>tr<"bottom pager"ip>', >- order: [[1, 'asc']], >- columns: [ >- { 'name': 'checkbox', 'orderable': false, searchable: false, }, >- { 'name': 'title' }, >- { 'name': 'publicationyear' }, >- { 'name': 'publishercode' }, >- { 'name': 'ccode', dataFilter: 'collection_codes' }, >- { 'name': 'barcode' }, >- { 'name': 'itemnumber' }, >- { 'name': 'enumchron' }, >- { 'name': 'itemcallnumber' }, >- { 'name': 'homebranch', dataFilter: 'libraries' }, >- { 'name': 'holdingbranch', dataFilter: 'libraries' }, >- { 'name': 'location', dataFilter: 'locations' }, >- { 'name': 'itype', dataFilter: 'item_types' }, >- { 'name': 'stocknumber' }, >- { 'name': 'notforloan', dataFilter: 'av_notforloan' }, >- { 'name': 'itemlost', dataFilter: 'av_lost' }, >- { 'name': 'withdrawn', dataFilter: 'av_widthdrawn' }, >- { 'name': 'damaged', dataFilter: 'av_damaged' }, >- { 'name': 'dateaccessioned' }, >- { 'name': 'issues' }, >- { 'name': 'datelastborrowed' }, >- { 'name': 'date_due' }, >- { 'name': 'actions', 'orderable': false, searchable: false, } >- ], >- pagingType: "full_numbers", >- drawCallback: function( settings ) { >- prepSelections(); >+ d.format = "json"; >+ d.columns = JSON.stringify(d.columns); >+ return d; >+ }, >+ }, >+ bKohaAjaxSVC: true, >+ dom: 'C<"top pager"ilpB>tr<"bottom pager"ip>', >+ order: [[1, "asc"]], >+ columns: [ >+ { name: "checkbox", orderable: false, searchable: false }, >+ { name: "title" }, >+ { name: "publicationyear" }, >+ { name: "publishercode" }, >+ { name: "ccode", dataFilter: "collection_codes" }, >+ { name: "barcode" }, >+ { name: "itemnumber" }, >+ { name: "enumchron" }, >+ { name: "itemcallnumber" }, >+ { name: "homebranch", dataFilter: "libraries" }, >+ { name: "holdingbranch", dataFilter: "libraries" }, >+ { name: "location", dataFilter: "locations" }, >+ { name: "itype", dataFilter: "item_types" }, >+ { name: "stocknumber" }, >+ { name: "notforloan", dataFilter: "av_notforloan" }, >+ { name: "itemlost", dataFilter: "av_lost" }, >+ { name: "withdrawn", dataFilter: "av_widthdrawn" }, >+ { name: "damaged", dataFilter: "av_damaged" }, >+ { name: "dateaccessioned" }, >+ { name: "issues" }, >+ { name: "datelastborrowed" }, >+ { name: "date_due" }, >+ { name: "actions", orderable: false, searchable: false }, >+ ], >+ pagingType: "full_numbers", >+ drawCallback: function (settings) { >+ prepSelections(); >+ }, >+ fixedHeader: false, // There is a bug on this view > }, >- fixedHeader: false // There is a bug on this view >- }, table_settings, true, null, filters_options ); >+ table_settings, >+ true, >+ null, >+ filters_options >+ ); > >- $('#item_search').on('draw.dt', function (e, settings) { >+ $("#item_search").on("draw.dt", function (e, settings) { > prepSelections(); > $('[data-bs-toggle="tooltip"]').tooltip(); > }); >@@ -736,135 +806,126 @@ > > $(document).ready(function () { > // Add the "New field" link. >- var form_field = $('div.form-field-select-text').last() >+ var form_field = $("div.form-field-select-text").last(); > var NEW_FIELD = _("New field"); >- var button_field_new = $('<a href="#" class="button-field-new" title="Add a new field"><i class="fa fa-plus"></i> ' + NEW_FIELD + '</a>'); >- button_field_new.click(function(e) { >+ var button_field_new = $('<a href="#" class="button-field-new" title="Add a new field"><i class="fa fa-plus"></i> ' + NEW_FIELD + "</a>"); >+ button_field_new.click(function (e) { > e.preventDefault(); >- addNewField( $(this) ); >+ addNewField($(this)); > }); > form_field.append(button_field_new); > > // If a field is linked to an authorised values list, display the list. >- $('div.form-field-select-text select[name="f"]').change(function() { >- loadAuthorisedValuesSelect($(this)); >- }).change(); >+ $('div.form-field-select-text select[name="f"]') >+ .change(function () { >+ loadAuthorisedValuesSelect($(this)); >+ }) >+ .change(); > > // Prevent user to select the 'All ...' option with other options. >- $('div.form-field-select').each(function() { >- $(this).find('select').filter(':last').change(function() { >- values = $(this).val(); >- if (values.length > 1) { >- var idx = $.inArray('', values); >- if (idx != -1) { >- values.splice(idx, 1); >- $(this).val(values); >+ $("div.form-field-select").each(function () { >+ $(this) >+ .find("select") >+ .filter(":last") >+ .change(function () { >+ values = $(this).val(); >+ if (values.length > 1) { >+ var idx = $.inArray("", values); >+ if (idx != -1) { >+ values.splice(idx, 1); >+ $(this).val(values); >+ } > } >- } >- }); >+ }); > }); > >- $('#itemsearchform').submit(function() { >+ $("#itemsearchform").submit(function () { > var searchform = $(this); >- if( $("#forget_item_selections").is(':checked') ){ >- localStorage.removeItem("item_search_selections"); >+ if ($("#forget_item_selections").is(":checked")) { >+ localStorage.removeItem("item_search_selections"); > } > var format = searchform.find('input[name="format"]:checked').val(); >- if (format == 'html') { >+ if (format == "html") { > submitForm(searchform); > $("#item-search-block").hide(); > return false; > } > }); > >- $("body").on("click", "#select_all", function(e) { >+ $("body").on("click", "#select_all", function (e) { > e.preventDefault(); >- $("#item_search input[type='checkbox']").each(function(){ >- if( $(this).prop("checked") == false ){ >- $(this).prop( "checked", true ).change(); >+ $("#item_search input[type='checkbox']").each(function () { >+ if ($(this).prop("checked") == false) { >+ $(this).prop("checked", true).change(); > } > }); > }); > >- $("body").on("click", "#clear_all", function(e) { >+ $("body").on("click", "#clear_all", function (e) { > e.preventDefault(); >- $("#item_search input[type='checkbox']").each(function(){ >- if( $(this).prop("checked") == true ){ >- $(this).prop( "checked", false ).change(); >+ $("#item_search input[type='checkbox']").each(function () { >+ if ($(this).prop("checked") == true) { >+ $(this).prop("checked", false).change(); > } > }); > }); > >- $("body").on("click", "#clear-row-selection", function(e){ >+ $("body").on("click", "#clear-row-selection", function (e) { > e.preventDefault(); >- $("#item_search input[type='checkbox']").prop("checked" ,false ).change(); >+ $("#item_search input[type='checkbox']").prop("checked", false).change(); > localStorage.removeItem("item_search_selections"); >- showItemSelections( 0 ); >+ showItemSelections(0); > }); > >- $("body").on('change', '#item_search input[type="checkbox"]', function() { >- let item_search_selections = JSON.parse( localStorage.getItem("item_search_selections") ) || []; >+ $("body").on("change", '#item_search input[type="checkbox"]', function () { >+ let item_search_selections = JSON.parse(localStorage.getItem("item_search_selections")) || []; > var itemnumber = $(this).val(); >- if( $(this).prop("checked") ){ >- item_search_selections.push( $(this).val() ); >- localStorage.setItem('item_search_selections', JSON.stringify( item_search_selections )); >- showItemSelections( item_search_selections.length ); >+ if ($(this).prop("checked")) { >+ item_search_selections.push($(this).val()); >+ localStorage.setItem("item_search_selections", JSON.stringify(item_search_selections)); >+ showItemSelections(item_search_selections.length); > } else { >- var filtered = item_search_selections.filter(function( value ){ >+ var filtered = item_search_selections.filter(function (value) { > return value !== itemnumber; > }); >- if( filtered.length > 0 ){ >- localStorage.setItem('item_search_selections', JSON.stringify( filtered )); >+ if (filtered.length > 0) { >+ localStorage.setItem("item_search_selections", JSON.stringify(filtered)); > item_search_selections = filtered; >- showItemSelections( filtered.length ); >+ showItemSelections(filtered.length); > } else { > item_search_selections = []; >- localStorage.removeItem('item_search_selections'); >- showItemSelections( 0 ); >+ localStorage.removeItem("item_search_selections"); >+ showItemSelections(0); > } > } > }); > >- $("body").on("click", "#csvExportLink", function(e){ >+ $("body").on("click", "#csvExportLink", function (e) { > e.preventDefault(); >- exportItems('csv'); >+ exportItems("csv"); > }); > >- $("body").on("click", "#barcodesExportLink", function(e){ >+ $("body").on("click", "#barcodesExportLink", function (e) { > e.preventDefault(); >- exportItems('barcodes'); >+ exportItems("barcodes"); > }); > >- $("body").on("click", ".batch_op", function(e){ >+ $("body").on("click", ".batch_op", function (e) { > e.preventDefault(); > let batch_mod_form = $("#batch_item_operations"); > batch_mod_form.empty(); >- batch_mod_form.append( >- $("<input>").attr("type","hidden") >- .attr("name", "op") >- .val("cud-show") >- ); >- batch_mod_form.append( >- $("<input>").attr("type","hidden") >- .attr("name", "csrf_token") >- .val($('meta[name="csrf-token"]').attr('content')) >- ); >- batch_mod_form.append( >- $("<input>").attr("type","hidden") >- .attr("name", "del") >- .attr("id", "batch_mod_del") >- ); >- let item_search_selections = JSON.parse( localStorage.getItem("item_search_selections") ) || []; >+ batch_mod_form.append($("<input>").attr("type", "hidden").attr("name", "op").val("cud-show")); >+ batch_mod_form.append($("<input>").attr("type", "hidden").attr("name", "csrf_token").val($('meta[name="csrf-token"]').attr("content"))); >+ batch_mod_form.append($("<input>").attr("type", "hidden").attr("name", "del").attr("id", "batch_mod_del")); >+ let item_search_selections = JSON.parse(localStorage.getItem("item_search_selections")) || []; > // Populate batch forms with itemnumbers in local storage >- for (let item of item_search_selections){ >- var field = $("<input>").attr("type","hidden") >- .attr("name","itemnumber") >- .val( item ); >- batch_mod_form.append( field ); >+ for (let item of item_search_selections) { >+ var field = $("<input>").attr("type", "hidden").attr("name", "itemnumber").val(item); >+ batch_mod_form.append(field); > } >- if( $(this).hasClass("send_to_item_mod") ){ >+ if ($(this).hasClass("send_to_item_mod")) { > $("#batch_mod_del").val(0); >- } else if ( $(this).hasClass("send_to_item_del") ){ >+ } else if ($(this).hasClass("send_to_item_del")) { > $("#batch_mod_del").val(1); > } else { > return false; >@@ -872,24 +933,24 @@ > batch_mod_form.submit(); > }); > >- $("body").on('click','#item_search tbody td',function(e){ >+ $("body").on("click", "#item_search tbody td", function (e) { > var checkbox = $(this).find("input[type=checkbox]"); > if (e.target.type != "checkbox") { >- checkbox.prop('checked', !checkbox.prop("checked")); >+ checkbox.prop("checked", !checkbox.prop("checked")); > checkbox.change(); > } > }); > > // Apply select2 to all select fields having a "multiple" attribute >- let selectFields = document.querySelectorAll('select[multiple]'); >- selectFields.forEach((selectField) => { >- selectField.style.minWidth = '320px'; >+ let selectFields = document.querySelectorAll("select[multiple]"); >+ selectFields.forEach(selectField => { >+ selectField.style.minWidth = "320px"; > $(selectField).select2(); > }); > >- let urlParams = new URLSearchParams(window.location.search) >- if (urlParams.get('format') === 'shareable') { >- submitForm($('#itemsearchform')); >+ let urlParams = new URLSearchParams(window.location.search); >+ if (urlParams.get("format") === "shareable") { >+ submitForm($("#itemsearchform")); > $("#item-search-block").hide(); > } > }); >-- >2.43.0 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 41566
:
191103
|
191104
|
191105
| 191106