From 0b7dc201c855aab717e8f5e263d17f5e3736f615 Mon Sep 17 00:00:00 2001
From: Martin Renvoize <martin.renvoize@ptfs-europe.com>
Date: Tue, 24 Jan 2023 12:22:34 +0000
Subject: [PATCH] Bug 32711: Add biblio details to modal
This patch adds biblio details to the self-checkout modal. As part of
this we add 'biblio' to the x-koha-embed option on the public items
endpoint, clone the js-biblio-format include from the staff client
adapting it slightly for OPAC use along the way and also import
escape_str and escapeHtml from staff to opac too.
Signed-off-by: Silvia Meakins <smeakins@eso.org>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
---
api/v1/swagger/paths/items.yaml | 1 +
.../en/includes/js-biblio-format.inc | 64 +++++++++++++++++++
.../bootstrap/en/includes/modals/checkout.inc | 4 +-
.../bootstrap/en/includes/opac-bottom.inc | 1 +
koha-tmpl/opac-tmpl/bootstrap/js/global.js | 14 ++++
.../opac-tmpl/bootstrap/js/modals/checkout.js | 23 +++++--
6 files changed, 101 insertions(+), 6 deletions(-)
create mode 100644 koha-tmpl/opac-tmpl/bootstrap/en/includes/js-biblio-format.inc
diff --git a/api/v1/swagger/paths/items.yaml b/api/v1/swagger/paths/items.yaml
index ac8c313a14..2a1591ec44 100644
--- a/api/v1/swagger/paths/items.yaml
+++ b/api/v1/swagger/paths/items.yaml
@@ -426,6 +426,7 @@
type: string
enum:
- +strings
+ - biblio
collectionFormat: csv
consumes:
- application/json
diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/includes/js-biblio-format.inc b/koha-tmpl/opac-tmpl/bootstrap/en/includes/js-biblio-format.inc
new file mode 100644
index 0000000000..77c2fe5c18
--- /dev/null
+++ b/koha-tmpl/opac-tmpl/bootstrap/en/includes/js-biblio-format.inc
@@ -0,0 +1,64 @@
+<script>
+ (function() {
+ /**
+ * Format the biblio response from a Koha RESTful API request.
+ * @param {Object} biblio The biblio json object as returned from the Koha RESTful API
+ * @param {Object} config A configuration object
+ * Valid keys are: `link`
+ * @return {string} The formatted HTML string
+ */
+ window.$biblio_to_html = function(biblio, config) {
+
+ if (biblio === undefined) {
+ return ''; // empty string for no biblio
+ }
+
+ var title = '<span class="biblio-title">';
+ if (biblio.title != null && biblio.title != '') {
+ title += escape_str(biblio.title);
+ } else {
+ title += __("No title");
+ }
+ title += '</span>';
+
+ // add subtitle
+ if (biblio.subtitle != null && biblio.subtitle != '') {
+ title += ' <span class="biblio-subtitle">' + escape_str(biblio.subtitle) + '</span>';
+ }
+
+ // set title as link
+ if (config && config.link) {
+ if (config.link === 'marcdetail') {
+ title = '<a href="/cgi-bin/koha/opac-MARCdetail.pl?biblionumber=' + encodeURIComponent(biblio.biblio_id) + '" class="title">' + title + '</a>';
+ } else if (config.link === 'labeled_marc') {
+ title = '<a href="/cgi-bin/koha/opac-labeledMARCdetail.pl?biblionumber=' + encodeURIComponent(biblio.biblio_id) + '" class="title">' + title + '</a>';
+ } else if (config.link === 'isbd') {
+ title = '<a href="/cgi-bin/koha/opac-ISBDdetail.pl?biblionumber=' + encodeURIComponent(biblio.biblio_id) + '" class="title">' + title + '</a>';
+ } else {
+ title = '<a href="/cgi-bin/koha/opac-detail.pl?biblionumber=' + encodeURIComponent(biblio.biblio_id) + '" class="title">' + title + '</a>';
+ }
+ }
+
+ // add medium
+ if (biblio.medium != null && biblio.medium != '') {
+ title += ' <span class="biblio-medium">' + escape_str(biblio.medium) + '</span>';
+ }
+
+ // add part numbers/names
+ let part_numbers = (typeof biblio.part_number === 'string') ? biblio.part_number.split("|") : [];
+ let part_names = (typeof biblio.part_name === 'string') ? biblio.part_name.split("|") : [];
+ let i = 0;
+ while (part_numbers[i] || part_names[i]) {
+ if (part_numbers[i]) {
+ title += ' <span class="part-number">' + escape_str(part_numbers[i]) + '</span>';
+ }
+ if (part_names[i]) {
+ title += ' <span class="part-name">' + escape_str(part_names[i]) + '</span>';
+ }
+ i++;
+ }
+
+ return title;
+ };
+ })();
+</script>
diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/includes/modals/checkout.inc b/koha-tmpl/opac-tmpl/bootstrap/en/includes/modals/checkout.inc
index 6a19e717de..615345ef77 100644
--- a/koha-tmpl/opac-tmpl/bootstrap/en/includes/modals/checkout.inc
+++ b/koha-tmpl/opac-tmpl/bootstrap/en/includes/modals/checkout.inc
@@ -19,6 +19,8 @@
<thead>
<tr>
<th>Barcode</th>
+ <th>Title</th>
+ <th>Call number</th>
<th>Due date</th>
</tr>
</thead>
@@ -26,7 +28,7 @@
</tbody>
<tfoot>
<tr>
- <td colspan="2" class="text-right"><span id="checkoutsCount"></span> items checked out</td>
+ <td colspan="4" class="text-right"><span id="checkoutsCount"></span> items checked out</td>
</tr>
</tfoot>
</table>
diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-bottom.inc b/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-bottom.inc
index 518aed4e24..5f8cf1a50e 100644
--- a/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-bottom.inc
+++ b/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-bottom.inc
@@ -295,6 +295,7 @@ $(document).ready(function() {
});
</script>
[% INCLUDE 'js-date-format.inc' %]
+[% INCLUDE 'js-biblio-format.inc' %]
[% PROCESS jsinclude %]
[% IF ( Koha.Preference('OPACUserJS') ) %]
<script>
diff --git a/koha-tmpl/opac-tmpl/bootstrap/js/global.js b/koha-tmpl/opac-tmpl/bootstrap/js/global.js
index b9ea0b6edf..020b593e79 100644
--- a/koha-tmpl/opac-tmpl/bootstrap/js/global.js
+++ b/koha-tmpl/opac-tmpl/bootstrap/js/global.js
@@ -27,6 +27,20 @@ function formatstr(str, col) {
});
};
+var HtmlCharsToEscape = {
+ '&': '&',
+ '<': '<',
+ '>': '>'
+};
+String.prototype.escapeHtml = function() {
+ return this.replace(/[&<>]/g, function(c) {
+ return HtmlCharsToEscape[c] || c;
+ });
+};
+function escape_str(s){
+ return s != null ? s.escapeHtml() : "";
+}
+
function confirmDelete(message) {
return (confirm(message) ? true : false);
}
diff --git a/koha-tmpl/opac-tmpl/bootstrap/js/modals/checkout.js b/koha-tmpl/opac-tmpl/bootstrap/js/modals/checkout.js
index 1243ee67c8..09bea14da0 100644
--- a/koha-tmpl/opac-tmpl/bootstrap/js/modals/checkout.js
+++ b/koha-tmpl/opac-tmpl/bootstrap/js/modals/checkout.js
@@ -55,8 +55,18 @@ $(document).ready(function() {
// Display checkouts table if not already visible
$('#checkoutsTable').show();
// Add checkout to checkouts table
- $('#checkoutsTable > tbody').append('<tr><td>' + current_item.external_id +'</td><td>'+ $date(checkout.due_date) +'</td></tr>');
- $('#checkoutsCount').html(++checkouts_count);
+ $("#checkoutsTable > tbody").append(
+ "<tr><td>" +
+ current_item.external_id +
+ "</td><td>" +
+ $biblio_to_html(current_item.biblio, { link: 0 }) +
+ "</td><td>" +
+ current_item.callnumber +
+ "</td><td>" +
+ $date(checkout.due_date) +
+ "</td></tr>"
+ );
+ $("#checkoutsCount").html(++checkouts_count);
// Reset to submission
$('#checkoutConfirm').replaceWith('<button type="submit" id="checkoutSubmit" class="btn btn-primary">Submit</button>');
};
@@ -108,9 +118,12 @@ $(document).ready(function() {
let item_id;
let items = $.ajax({
- url: '/api/v1/public/items?external_id=' + external_id,
- dataType: 'json',
- type: 'GET'
+ url: "/api/v1/public/items?external_id=" + external_id,
+ headers: {
+ "x-koha-embed": "biblio",
+ },
+ dataType: "json",
+ type: "GET",
});
$('#availabilityResult').replaceWith('<div id="availabilityResult"></div>');
--
2.40.1