From 8472ffd47ffabf98881c2617f4c533d40d02408a Mon Sep 17 00:00:00 2001 From: Sam Lau Date: Mon, 19 Aug 2024 20:44:22 +0000 Subject: [PATCH] Bug 37637: Use the API to load the items table This patch removes the previous use of the database to load the additem table and instead uses the API. To test: 1) Test the current datatable behavior: visit an item's detail page and select 'Edit' then 'Edit items' 2) Apply the patches, restart_all, reset_all, clear caches, etc. 3) Again, test the table behaviors. Try adding items, using the actions, filtering and sorting the items, etc. --- cataloguing/additem.pl | 3 + .../prog/en/modules/cataloguing/additem.tt | 174 +++---- .../prog/js/cataloging_additem.js | 493 +++++++++++++++++- 3 files changed, 551 insertions(+), 119 deletions(-) diff --git a/cataloguing/additem.pl b/cataloguing/additem.pl index 3d361ec1e6..1982fd1584 100755 --- a/cataloguing/additem.pl +++ b/cataloguing/additem.pl @@ -679,6 +679,9 @@ if ($op) { # now, build existiing item list +my @libraries = $patron->libraries_where_can_edit_items; +$template->param(can_edit_items_from => \@libraries); + my @items; for my $item ( $biblio->items->as_list, $biblio->host_items->as_list ) { my $i = $item->columns_to_str; diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tt index 57e8b73173..ba26f23f10 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tt @@ -5,6 +5,11 @@ [% USE KohaDates %] [% USE Price %] [% USE TablesSettings %] +[% USE ItemTypes %] +[% USE To %] +[% USE tojson = To %] +[% USE AuthorisedValues %] +[% USE ClassSources %] [% PROCESS 'i18n.inc' %] [% INCLUDE 'doc-head-open.inc' %] [% FILTER collapse %] @@ -34,7 +39,39 @@ [% Asset.js("js/browser.js") | $raw %] [% INCLUDE 'calendar.inc' %] [% INCLUDE 'str/cataloging_additem.inc' %] +[% INCLUDE 'csrf-token.inc' %] [% Asset.js("js/cataloging_additem.js") | $raw %] + <script> + const can_edit_items_from = [% To.json(can_edit_items_from || []) | $raw %]; + + // filter dropdown variables + const all_libraries = [% To.json(Branches.all) | $raw %]; + const all_item_types = [% To.json(ItemTypes.Get) | $raw %]; + const all_damaged_statuses = [% To.json(AuthorisedValues.Get("DAMAGED")) | $raw %]; + const all_lost_statuses = [% To.json(AuthorisedValues.Get("LOST")) | $raw %]; + const all_stack = [% To.json(AuthorisedValues.Get("STACK")) | $raw %]; + const all_collection_codes = [% To.json(AuthorisedValues.Get("CCODE")) | $raw %]; + const all_shelivng_locations = [% To.json(AuthorisedValues.Get("LOC")) | $raw %]; + const all_not_for_loan_statuses = [% To.json(AuthorisedValues.Get("NOT_LOAN")) | $raw %]; + const all_restricted_statuses = [% To.json(AuthorisedValues.Get("RESTRICTED")) | $raw %]; + const all_withdrawn = [% To.json(AuthorisedValues.Get("WITHDRAWN")) | $raw %]; + const all_class_sources = [ + [% FOREACH class_source IN ClassSources.all %] + { + cn_source: "[% class_source.cn_source | html %]", + description: "[% class_source.description | html %]" + }, + [% END %] + ]; + + var opac_base_url; + [% IF ( Koha.Preference('OPACBaseURL') ) %] + var opac_base_url = "[% Koha.Preference('OPACBaseURL') | url %]"; + [% END %] + + var is_independent_branches = [% Koha.Preference('IndependentBranches') | html %] && ![% logged_in_user.is_superlibrarian | html %]; + var logged_in_branchname = "[% Branches.GetLoggedInBranchname() | html %]"; + </script> [% Asset.js("js/form-submit.js") | $raw %] <script> var has_item_groups = "[% item_groups.size | html %]"; @@ -88,99 +125,50 @@ [% IF item_not_found %]<div class="dialog alert"><strong>Cannot delete</strong>: Item not found.</div>[% END %] <div id="cataloguing_additem_itemlist"> - [% IF items %] - [% SET date_fields = [ 'dateaccessioned', 'onloan', 'datelastseen', 'datelastborrowed', 'replacementpricedate' ] %] - <div class="page-section"> - <table id="itemst"> - <thead> - <tr> - <th class="NoSort"> </th> - [% FOREACH item_header IN item_header_loop %] - <th data-colname="[% item_header.attribute | html %]"> - [% item_header.header_value | html %] - </th> - [% END %] - </tr> - </thead> - <tbody> - [% FOREACH item IN items %] - [% SET can_be_edited = ! ( Koha.Preference('IndependentBranches') && ! logged_in_user.is_superlibrarian && item.homebranch != Branches.GetLoggedInBranchname() ) %] - [% IF item.itemnumber == itemnumber%] - [% UNLESS can_be_edited %] - <tr id="row[% item.itemnumber | html %]" class="active"> - [% ELSE %] - <tr id="row[% item.itemnumber | html %]" class="active editable"> - [% END %] - [% ELSE %] - [% UNLESS can_be_edited %] - <tr id="row[% item.itemnumber | html %]"> - [% ELSE %] - <tr id="row[% item.itemnumber | html %]" class="editable"> - [% END %] - [% END %] - [% UNLESS can_be_edited %] - <td> </td> - [% ELSE %] - <td> - <div class="btn-group dropup"> - <a class="btn btn-default btn-xs dropdown-toggle" id="itemactions[% item.itemnumber | html %]" role="button" data-toggle="dropdown" href="#"> - Actions <b class="caret"></b> - </a> - <ul class="dropdown-menu" role="menu" aria-labelledby="itemactions[% item.itemnumber | html %]"> - - [% IF item.biblionumber != biblio.biblionumber %] [%# Host item %] - <li><a href="additem.pl?op=edititem&biblionumber=[% item.biblionumber | uri %]&itemnumber=[% item.itemnumber | uri %]#edititem">Edit in host</a>   <a class="delete" href="/cgi-bin/koha/cataloguing/additem.pl?op=delinkitem&biblionumber=[% biblio.biblionumber | html %]&hostitemnumber=[% item.itemnumber | html %]&searchid=[% searchid | html %]">Delink</a></li> - [% ELSE %] - [% UNLESS item.nomod %] - <li><a href="additem.pl?op=edititem&biblionumber=[% biblio.biblionumber | uri %]&itemnumber=[% item.itemnumber | uri %]&searchid=[% searchid | uri %]#edititem">Edit</a></li> - [% END %] - <li><a href="additem.pl?op=dupeitem&biblionumber=[% biblio.biblionumber | uri %]&itemnumber=[% item.itemnumber | uri %]&searchid=[% searchid | uri %]#additema">Duplicate</a></li> - <li class="print_label"> - <a class="submit-form-link" target="_blank" href="#" data-op="cud-add" data-number_list="[% item.itemnumber | html %]" data-number_type="itemnumber" data-method="post" data-action="/cgi-bin/koha/labels/label-edit-batch.pl" data-new_tab="true">Print label</a> - </li> - [% UNLESS item.nomod %] - <li> - <form id="[% item.itemnumber | html %]-delete-item-form" action="/cgi-bin/koha/cataloguing/additem.pl" method="post"> - [% INCLUDE 'csrf-token.inc' %] - <input type="hidden" name="op" value="cud-delitem" /> - <input type="hidden" name="biblionumber" value="[% item.biblionumber | html %]" /> - <input type="hidden" name="itemnumber" value="[% item.itemnumber | html %]" /> - <input type="hidden" name="searchid" value="[% searchid | html %]" /> - </form> - <a class="delete" data-item="[% item.itemnumber | html %]" href="#">Delete</a> - </li> - [% END %] - [% END %] - [% IF ( OPACBaseURL ) %] - <li class="view-in-opac"><a target="_blank" href="[% Koha.Preference('OPACBaseURL') | url %]/cgi-bin/koha/opac-detail.pl?biblionumber=[% item.biblionumber | uri %]">OPAC view</a></li> - [% END %] - </ul> - </div> - </td> - [% END %] - [% FOREACH header IN item_header_loop %] - [% SET attribute = header.attribute %] - [% SET can_mod = item.nomod ? "nomod" : "canmod" %] - [% IF attribute AND date_fields.grep('^' _ attribute _ '$').size %] - [% IF attribute == 'datelastseen' %] - <td class="[% can_mod | html %]" data-order="[% item.$attribute | html %]">[% item.$attribute | $KohaDates with_hours => 1 %]</td> - [% ELSE %] - <td class="[% can_mod | html %]" data-order="[% item.$attribute | html %]">[% item.$attribute | $KohaDates %]</td> - [% END %] - [% ELSIF ( item.$attribute && ( attribute == 'price' || attribute == 'replacementprice' ) ) %] - <td class="[% can_mod | html %]" data-order="[% item.$attribute | html %]">[% item.$attribute | $Price %]</td> - [% ELSIF item.$attribute && attribute == 'itemcallnumber' %] - <td class="[% can_mod | html %]" data-order="[% item.cn_sort | html %]">[% item.$attribute | html %]</td> - [% ELSE %] - <td class="[% can_mod | html %]">[% item.$attribute | html %]</td> - [% END %] - [% END %] - </tr> - [% END %] - </tbody> - </table> - </div> <!-- /.page-section --> - [% END %] + <div class="page-section"> + <span class="show_hide_filters"> + <a href="#" class="show_filters"><i class="fa fa-filter"></i> Show filters</a> + <a href="#" class="hide_filters" style="display: none;"><i class="fa fa-filter"></i> Hide filters</a> + </span> + <table id="itemst"> + <thead> + <tr> + <th data-colname="actions" class="NoSort noExport"> </th> + <th data-colname="barcode">Barcode</th> + <th data-colname="dateaccessioned">Date acquired</th> + <th data-colname="bookselleridf">Source of acquisition</th> + <th data-colname="homebranch">Home library</th> + <th data-colname="price">Cost, normal purchase price</th> + <th data-colname="replacementprice">Cost, replacement price</th> + <th data-colname="replacementpricedate">Price effective from</th> + <th data-colname="datelastborrowed">Date last checked out</th> + <th data-colname="datelastseen">Date last seen</th> + <th data-colname="stack">Shelving control number</th> + <th data-colname="notforloan">Not for loan</th> + <th data-colname="damaged">Damaged status</th> + <th data-colname="itemlost">Lost status</th> + <th data-colname="withdrawn">Withdrawn status</th> + <th data-colname="itemcallnumber">Full call number</th> + <th data-colname="coded_location_qualifier">Coded location qualifier</th> + <th data-colname="restricted">Use restrictions</th> + <th data-colname="itemnotes">Public note</th> + <th data-colname="itemnotes_nonpublic">Non-public note</th> + <th data-colname="holdingbranch">Current library</th> + <th data-colname="timestamp">Timestamp</th> + <th data-colname="location">Shelving location</th> + <th data-colname="onloan">Date due</th> + <th data-colname="cn_source">Source of classification or shelving scheme</th> + <th data-colname="ccode">Collection</th> + <th data-colname="materials">Materials specified (bound volume or other part)</th> + <th data-colname="uri">Uniform resource identifier</th> + <th data-colname="itype">Koha item type</th> + <th data-colname="enumchron">Serial enumeration / chronology</th> + <th data-colname="copynumber">Copy number</th> + <th data-colname="stocknumber">Inventory number</th> + </tr> + </thead> + </table> + </div> <!-- /.page-section --> <div class="row"> <div class="col-sm-2"> diff --git a/koha-tmpl/intranet-tmpl/prog/js/cataloging_additem.js b/koha-tmpl/intranet-tmpl/prog/js/cataloging_additem.js index 06fc9137e5..0f6e09111a 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/cataloging_additem.js +++ b/koha-tmpl/intranet-tmpl/prog/js/cataloging_additem.js @@ -4,6 +4,97 @@ var browser = KOHA.browser(searchid, parseInt(biblionumber, 10)); browser.show(); $(document).ready(function(){ + table_settings['columns'].unshift( { cannot_be_toggled: "1" } ); + build_itemst(false, {}); + + const filterContainer = document.querySelector('.show_hide_filters'); + const showFiltersLink = filterContainer.querySelector('.show_filters'); + const hideFiltersLink = filterContainer.querySelector('.hide_filters'); + + $(".show_filters").on("click",function(e){ + e.preventDefault(); + showFiltersLink.style.display = 'none'; + hideFiltersLink.style.display = 'inline'; + $("#itemst thead tr:eq(1)").remove(); + build_itemst(true, { destroy: true }); + }); + + $(".hide_filters").on("click",function(e){ + e.preventDefault(); + showFiltersLink.style.display = 'inline'; + hideFiltersLink.style.display = 'none'; + $("#itemst thead tr:eq(1)").remove(); + build_itemst(false, { destroy: true }); + }); + + // Build the filter dropdowns + const libraries_filters = all_libraries.map(e => { + e["_id"] = e["branchcode"]; + e["_str"] = e["branchname"]; + return e; + }); + const libraries_names = new Map(all_libraries.map( l => [l.branchcode, l.branchname] )); + + const item_types_filters = all_item_types.map(e => { + e["_id"] = e["itemtype"]; + e["_str"] = e["translated_description"]; + return e; + }); + + const damaged_filters = all_damaged_statuses.map(e => { + e["_id"] = e["authorised_value"]; + e["_str"] = e["lib"]; + return e; + }); + + const lost_filters = all_lost_statuses.map(e => { + e["_id"] = e["authorised_value"]; + e["_str"] = e["lib"]; + return e; + }); + + const stack_filters = all_stack.map(e => { + e["_id"] = e["authorised_value"]; + e["_str"] = e["lib"]; + return e; + }); + + const ccode_filters = all_collection_codes.map(e => { + e["_id"] = e["authorised_value"]; + e["_str"] = e["lib"]; + return e; + }); + + const shelving_location_filters = all_shelivng_locations.map(e => { + e["_id"] = e["authorised_value"]; + e["_str"] = e["lib"]; + return e; + }); + + const not_for_loan_filters = all_not_for_loan_statuses.map(e => { + e["_id"] = e["authorised_value"]; + e["_str"] = e["lib"]; + return e; + }); + + const withdrawn_filters = all_withdrawn.map(e => { + e["_id"] = e["authorised_value"]; + e["_str"] = e["lib"]; + return e; + }); + + + const restricted_filters = all_restricted_statuses.map(e => { + e["_id"] = e["authorised_value"]; + e["_str"] = e["lib"]; + return e; + }); + + const class_sources_filters = all_class_sources.map(e => { + e["_id"] = e["cn_source"]; + e["_str"] = e["description"]; + return e; + }); // Remove the onclick event defined in browser.js, // otherwise the deletion confirmation will not work correctly @@ -14,23 +105,7 @@ $(document).ready(function(){ } $("fieldset.rows input, fieldset.rows select").addClass("noEnterSubmit"); - /* Inline edit/delete links */ var biblionumber = $("input[name='biblionumber']").val(); - $("tr.editable").each(function(){ - $(this).find("td:not(:first)").on('click', function(){ - var rowid = $(this).parent().attr("id"); - var num_rowid = rowid.replace("row",""); - $(".linktools").remove(); - var edit_link = $('<a href="/cgi-bin/koha/cataloguing/additem.pl?op=edititem&frameworkcode=' + frameworkcode + '&biblionumber=' + biblionumber + '&itemnumber=' + num_rowid + '&searchid=' + searchid + '#edititem"></a>'); - $(edit_link).text( LABEL_EDIT_ITEM ); - var delete_link = $('<a class="delete" data-item="'+num_rowid+'" href="#"></a>'); - $(delete_link).text( LABEL_DELETE_ITEM ); - var tools_node = $('<span class="linktools"></span>'); - $(tools_node).append(edit_link); - $(tools_node).append(delete_link); - $(this).append(tools_node); - }); - }); $("#addnewitem").click(function(){ if ( confirm( MSG_CONFIRM_ADD_ITEM ) ){ @@ -38,16 +113,6 @@ $(document).ready(function(){ } }); - // Skip the first column - table_settings['columns'].unshift( { cannot_be_toggled: "1" } ); - - var itemst = KohaTable("itemst", { - "paging": false, - "info": false, - "autoWidth": false, - "bKohaColumnsUseNames": true - }, table_settings); - var multiCopyControl = $("#add_multiple_copies_span"); var addMultipleBlock = $("#addmultiple"); var addSingleBlock = $("#addsingle"); @@ -203,3 +268,379 @@ function Dopop(link,i) { var defaultvalue=document.forms[0].field_value[i].value; var newin=window.open(link+"&result=" + defaultvalue,"valuebuilder",'width=500,height=400,toolbar=false,scrollbars=yes'); } + +function build_itemst(show_filters, dt_options) { + + if ( dt_options && dt_options.hasOwnProperty('destroy') ) { + let table_id = "#itemst"; + if( $.fn.dataTable.isDataTable(table_id) ) { + $(table_id).DataTable().destroy(); + } + dt_options['destroy'] = null; + } + + // assign positions for the filter dropdowns + let default_filters = {}; + var offset = 4; + let filters_options = { + [offset] : () => all_libraries, + [offset+6] : () => all_stack, + [offset+7] : () => all_not_for_loan_statuses, + [offset+8] : () => all_damaged_statuses, + [offset+9] : () => all_lost_statuses, + [offset+10] : () => all_withdrawn, + [offset+13] : () => all_restricted_statuses, + [offset+16] : () => all_libraries, + [offset+18] : () => all_shelivng_locations, + [offset+20] : () => all_class_sources, + [offset+21] : () => all_collection_codes, + [offset+24] : () => all_item_types, + }; + + var biblionumber = $("input[name='biblionumber']").val(); + var items_table_url = '/api/v1/biblios/' + biblionumber + '/items?'; + var items_table = $("#itemst").kohaTable({ + ajax: { + url: items_table_url + }, + order: [], + embed: ["+strings"], + autoWidth: false, + columns: [ + { + data: function(row, type, val, meta) { + let nodes = ''; + + let can_be_edited = !(is_independent_branches && row.home_library_id != logged_in_branchname); + if (can_be_edited) { + nodes += '<td>' + nodes += '<div class="btn-group dropup">'; + nodes += '<a class="btn btn-default btn-xs dropdown-toggle" id="itemactions' + row.item_id + '" role="button" data-toggle="dropdown" href="#">'; + nodes += 'Actions <b class="caret"></b>'; + nodes += '</a>'; + nodes += '<ul class="dropdown-menu" role="menu" aria-labelledby="itemactions' + row.item_id + '">'; + if (row.biblio_id != biblionumber) { // Host item + nodes += '<li><a href="additem.pl?op=edititem&biblionumber=' + row.biblio_id + '&itemnumber=' + row.item_id + '#edititem">Edit in host</a>   <a class="delete" href="/cgi-bin/koha/cataloguing/additem.pl?op=delinkitem&biblionumber=' + row.biblio_id + '&hostitemnumber=' + row.item_id + '&searchid=' + row.searchid + '">Delink</a></li>'; + } else { + if (can_edit_items_from.includes(row.home_library_id) || !can_edit_items_from.length) { + nodes += '<li><a href="additem.pl?op=edititem&biblionumber=' + row.biblio_id + '&itemnumber=' + row.item_id + '&searchid=' + row.searchid + '#edititem">Edit</a></li>'; + } + nodes += '<li><a href="additem.pl?op=dupeitem&biblionumber=' + row.biblio_id + '&itemnumber=' + row.item_id + '&searchid=' + row.searchid + '#additema">Duplicate</a></li>'; + nodes += '<li class="print_label">'; + nodes += '<a class="submit-form-link" target="_blank" href="#" data-op="cud-add" data-number_list="' + row.item_id + '" data-number_type="itemnumber" data-method="post" data-action="/cgi-bin/koha/labels/label-edit-batch.pl" data-new_tab="true">Print label</a>'; + nodes += '</li>'; + if (can_edit_items_from.includes(row.home_library_id) || !can_edit_items_from.length) { + let csrfToken = $('meta[name="csrf-token"]').attr('content'); + nodes += '<li>'; + nodes += '<form id="' + row.item_id + '-delete-item-form" action="/cgi-bin/koha/cataloguing/additem.pl" method="post">'; + nodes += '<input type="hidden" name="csrf_token" value="' + csrfToken + '" />'; + nodes += '<input type="hidden" name="op" value="cud-delitem" />'; + nodes += '<input type="hidden" name="biblionumber" value="' + row.biblio_id + '" />'; + nodes += '<input type="hidden" name="itemnumber" value="' + row.item_id + '" />'; + nodes += '<input type="hidden" name="searchid" value="' + row.searchid + '" />'; + nodes += '</form>'; + nodes += '<a class="delete" data-item="' + row.item_id + '" href="#">Delete</a>'; + nodes += '</li>'; + } + } + if ( opac_base_url ) { + var href = opac_base_url + "/cgi-bin/koha/opac-detail.pl?biblionumber=" + row.biblio_id; + nodes+= '<li class="view-in-opac"><a target="_blank" href="' + href + '">OPAC view</a></li>' + } + nodes += '</ul>'; + nodes += '</div>'; + nodes += '</td>'; + } else { + nodes += '<td> </td>' + } + return nodes; + }, + searchable: false, + orderable: false, + }, + { + data: "external_id", + searchable: true, + orderable: true, + render: function (data, type, row, meta) { + 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 ''; + } + }, + { + data: "acquisition_date", + searchable: true, + orderable: true, + render: function (data, type, row, meta) { + return $date(row.acquisition_date); + } + }, + { + data: "acquisition_source", + searchable: true, + orderable: true, + }, + { + data: "home_library_id", + searchable: true, + orderable: true, + render: function (data, type, row, meta) { + return row._strings.home_library_id ? escape_str(row._strings.home_library_id.str) : ""; + } + }, + { + data: "purchase_price", + searchable: true, + orderable: true, + }, + { + data: "replacement_price", + searchable: true, + orderable: true, + }, + { + data: "replacement_price_date", + searchable: true, + orderable: true, + render: function (data, type, row, meta) { + return $date(row.replacement_price_date); + } + }, + { + data: "last_checkout_date", + searchable: true, + orderable: true, + render: function (data, type, row, meta) { + return $date(row.last_checkout_date); + } + }, + { + data: "last_seen_date", + searchable: true, + orderable: true, + render: function (data, type, row, meta) { + return $date(row.last_seen_date); + } + }, + { + data: "stack", + searchable: true, + orderable: true, + render: function (data, type, row, meta) { + return row._strings.stack ? escape_str(row._strings.stack.str) : ""; + } + }, + { + data: "not_for_loan_status", + searchable: true, + orderable: true, + render: function (data, type, row, meta) { + return row._strings.not_for_loan_status ? escape_str(row._strings.not_for_loan_status.str) : ""; + } + }, + { + data: "damaged_status", + searchable: true, + orderable: true, + render: function (data, type, row, meta) { + return row._strings.damaged_status ? escape_str(row._strings.damaged_status.str) : ""; + } + }, + { + data: "lost_status", + searchable: true, + orderable: true, + render: function (data, type, row, meta) { + return row._strings.lost_status ? escape_str(row._strings.lost_status.str) : ""; + } + }, + { + data: "withdrawn", + searchable: true, + orderable: true, + render: function (data, type, row, meta) { + return row._strings.withdrawn ? escape_str(row._strings.withdrawn.str) : ""; + } + }, + { + data: "callnumber", + searchable: true, + orderable: true, + }, + { + data: "coded_location_qualifier", + searchable: true, + orderable: true, + }, + { + data: "restricted_status", + searchable: true, + orderable: true, + render: function (data, type, row, meta) { + return row._strings.restricted_status ? escape_str(row._strings.restricted_status.str) : ""; + } + }, + { + data: "public_notes", + searchable: true, + orderable: true, + }, + { + data: "internal_notes", + searchable: true, + orderable: true, + }, + { + data: "holding_library_id", + searchable: true, + orderable: true, + render: function (data, type, row, meta) { + return row._strings.holding_library_id ? escape_str(row._strings.holding_library_id.str) : ""; + } + }, + { + data: "timestamp", + searchable: true, + orderable: true, + render: function (data, type, row, meta) { + return $date(row.timestamp); + } + }, + { + data: "location", + searchable: true, + orderable: true, + render: function (data, type, row, meta) { + return row._strings.location ? escape_str(row._strings.location.str) : ""; + } + + }, + { + data: "checked_out_date", + searchable: true, + orderable: true, + render: function (data, type, row, meta) { + return $date(row.checked_out_date); + } + }, + { + data: "call_number_source", + searchable: true, + orderable: true, + render: function (data, type, row, meta) { + return row._strings.call_number_source ? escape_str(row._strings.call_number_source.str) : ""; + } + }, + { + data: "collection_code", + searchable: true, + orderable: true, + render: function (data, type, row, meta) { + return row._strings.collection_code ? escape_str(row._strings.collection_code.str) : ""; + } + }, + { + data: "materials_notes", + searchable: true, + orderable: true, + }, + { + data: "uri", + searchable: true, + orderable: true, + }, + { + data: "item_type_id", + searchable: true, + orderable: true, + render: function (data, type, row, meta) { + return row._strings.item_type_id ? escape_str(row._strings.item_type_id.str) : ""; + } + }, + { + data: "serial_issue_number", + searchable: true, + orderable: true, + }, + { + data: "copy_number", + searchable: true, + orderable: true, + }, + { + data: "inventory_number", + searchable: true, + orderable: true, + }, + ], + createdRow: function(row, data, dataIndex) { + $(row).attr('id', 'row' + data.item_id); + + let can_be_edited = !(is_independent_branches && data.home_library_id != logged_in_branchname); + + if (can_be_edited) { + $(row).addClass('editable'); + } + }, + initComplete: function( settings, json ){ + let table = settings.oInstance.api(); + table.columns().every(function(i){ + let is_empty = true; + let nodes = this.nodes(); + nodes.each((td, ii) => { + if ( $(td).html() !== '' ) { + is_empty = false; + return; + } + }); + if ( is_empty ) { + table.columns(i).visible(false); + } + }); + + }, + drawCallback: function(settings){ + + if (!show_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(); + } + + setupRowClickHandlers(); + + }, + ...dt_options, + + }, table_settings, show_filters, default_filters, filters_options,); + + return items_table; + +} + +/* Inline edit/delete links */ +function setupRowClickHandlers() { + $("tr.editable").each(function(){ + $(this).find("td:not(:first)").off('click').on('click', function(){ + $("tr.editable").removeClass('active'); + $(this).parent().addClass('active'); + + var rowid = $(this).parent().attr("id"); + var num_rowid = rowid.replace("row",""); + $(".linktools").remove(); + var edit_link = $('<a href="/cgi-bin/koha/cataloguing/additem.pl?op=edititem&frameworkcode=' + frameworkcode + '&biblionumber=' + biblionumber + '&itemnumber=' + num_rowid + '&searchid=' + searchid + '#edititem"></a>'); + $(edit_link).text( LABEL_EDIT_ITEM ); + var delete_link = $('<a class="delete" data-item="'+num_rowid+'" href="#"></a>'); + $(delete_link).text( LABEL_DELETE_ITEM ); + var tools_node = $('<span class="linktools"></span>'); + $(tools_node).append(edit_link); + $(tools_node).append(delete_link); + $(this).append(tools_node); + }); + }); +} -- 2.39.2