From ce5daeb83132d20e59e871702a6370bc9c0c4c81 Mon Sep 17 00:00:00 2001
From: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Date: Tue, 1 Feb 2022 11:06:49 +0100
Subject: [PATCH] Bug 29136: Ajaxify the patron search when placing a hold

Signed-off-by: David Nind <david@davidnind.com>
---
 .../includes/circ-patron-search-results.inc   |  45 ------
 .../prog/en/modules/reserve/request.tt        | 133 ++++++++++++------
 .../modules/reserve/tables/members_results.tt |  32 +++++
 .../prog/js/circ-patron-search-results.js     |  13 --
 reserve/request.pl                            |  20 +--
 5 files changed, 124 insertions(+), 119 deletions(-)
 delete mode 100644 koha-tmpl/intranet-tmpl/prog/en/includes/circ-patron-search-results.inc
 create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/reserve/tables/members_results.tt
 delete mode 100644 koha-tmpl/intranet-tmpl/prog/js/circ-patron-search-results.js

diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-patron-search-results.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/circ-patron-search-results.inc
deleted file mode 100644
index f7ab99ba93..0000000000
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-patron-search-results.inc
+++ /dev/null
@@ -1,45 +0,0 @@
-[% USE KohaDates %]
-<table id="table_borrowers" class="selections-table">
-    <thead>
-        <tr>
-            <th>Name</th>
-            <th>Card number</th>
-            <th>Date of birth</th>
-            <th>Category</th>
-            <th>Library</th>
-            <th>Address</th>
-            <th>Primary phone</th>
-        </tr>
-    </thead>
-    <tbody>
-        [% FOREACH borrower IN borrowers %]
-            [% IF destination == "circ" %]
-                <tr class="clickable" data-url="/cgi-bin/koha/circ/circulation.pl?borrowernumber=[% borrower.borrowernumber | html %]">
-                    <td><a href="/cgi-bin/koha/circ/circulation.pl?borrowernumber=[% borrower.borrowernumber | uri %]">[% borrower.surname | html %], [% borrower.firstname | html %]</a></td>
-            [% ELSIF destination == "holds" %]
-                [% SET data_url = "/cgi-bin/koha/reserve/request.pl?borrowernumber=" _ borrower.borrowernumber %]
-                [% FOREACH biblionumber IN biblionumbers %]
-                    [% SET data_url = data_url _ "&amp;biblionumber=" _ biblionumber %]
-                [% END %]
-                [% IF multi_hold %]
-                    [% SET data_url = data_url _ "&amp;multi_hold=1" %]
-                [% END %]
-                <tr class="clickable" data-url="[% data_url | url %]">
-                    <td><a href="[% data_url | url %]">[% borrower.surname | html %], [% borrower.firstname | html %]</a></td>
-            [% END %]
-                <td>[% borrower.cardnumber | html %]</td>
-                <td data-order="[% borrower.dateofbirth | html %]">[% INCLUDE 'patron-age.inc' patron = borrower %]</td>
-                <td>[% Categories.GetName( borrower.categorycode ) | html %]</td>
-                <td>
-                    [% IF ( Branches.GetLoggedInBranchcode == borrower.branchcode && !singleBranchMode ) %]
-                        <span class="currentlibrary">[% Branches.GetName( borrower.branchcode ) | html %]</span>
-                    [% ELSE %]
-                        [% Branches.GetName( borrower.branchcode ) | html %]
-                    [% END %]
-                </td>
-                <td>[% borrower.address | html %]</td>
-                <td>[% borrower.phone | html %]</td>
-            </tr>
-        [% END %]
-    </tbody>
-</table>
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt
index 8a0c9401d8..c452d0bf8a 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt
@@ -163,18 +163,30 @@
                             [% END %]
                         </ul>
                         <div id="holds_patronsearch_pane">
-                            <form id="holds_patronsearch" action="request.pl" method="post">
+                            <form id="holds_patronsearch" method="get">
                                 <div class="hint">Enter patron card number or partial name:</div>
-                                <input type="text" size="40" id="patron" class="focus" name="findborrower" autocomplete="off" />
+                                <input type="text" size="40" id="patron" class="focus" autocomplete="off" />
                                 <input type="submit" value="Search" />
                                 [% FOREACH biblionumber IN biblionumbers %]
                                 <input type="hidden" name="biblionumber" value="[% biblionumber | html %]"/>
                                 [% END %]
-
                             </form> <!-- /#holds_patronsearch -->
-                            [% IF borrowers %]
-                                [% INCLUDE 'circ-patron-search-results.inc' destination = "holds" %]
-                            [% END %]
+
+                            <table id="table_borrowers" class="selections-table" style="display: none;">
+                              <thead>
+                                <tr>
+                                  <th>Name</th>
+                                  <th>Address</th>
+                                  <th>Card number</th>
+                                  <th>Date of birth</th>
+                                  <th>Category</th>
+                                  <th>Library</th>
+                                  <th>Primary phone</th>
+                                </tr>
+                              </thead>
+                              <tbody></tbody>
+                            </table>
+
                         </div>
                         [% IF clubcount %]
                             <div id="holds_clubsearch_pane">
@@ -1144,7 +1156,6 @@
     [% INCLUDE 'calendar.inc' %]
     [% INCLUDE 'columns_settings.inc' %]
     [% Asset.js("lib/hc-sticky.js") | $raw %]
-    [% Asset.js("js/circ-patron-search-results.js") | $raw %]
     [% INCLUDE 'select2.inc' %]
     [% Asset.js("js/holds.js") | $raw%]
     <script>
@@ -1402,6 +1413,7 @@
         }
 
          $(document).ready(function() {
+
             $("#always_show_holds").change(function(){
                 if( $(this).prop('checked') ){
                     document.cookie = 'always_show_holds=DO';
@@ -1505,41 +1517,6 @@
                 return false;
             });
 
-            [% UNLESS ( patron || patron.borrowernumber || borrowers || noitems || nobiblio ) %]
-                [% IF ( PatronAutoComplete ) %]
-                $( "#patron" ).autocomplete({
-                    source: "/cgi-bin/koha/circ/ysearch.pl",
-                    minLength: 3,
-                    select: function( event, ui ) {
-                        $( "#patron" ).val( ui.item.cardnumber );
-                        $( "#holds_patronsearch" ).submit();
-                        return false;
-                    }
-                })
-                .data( "ui-autocomplete" )._renderItem = function( ul, item ) {
-                    return $( "<li></li>" )
-                    .data( "ui-autocomplete-item", item )
-                    .append(
-                        "<a>"
-                            + ( item.surname ? item.surname.escapeHtml() : "" )
-                            + ", "
-                            + ( item.firstname ? item.firstname.escapeHtml() : "" )
-                            + " (" + ( item.cardnumber ? item.cardnumber.escapeHtml() : "" ) + ")"
-                            + " "
-                            + "<small>"
-                                + ( item.address ? item.address.escapeHtml() : "" )
-                                + " "
-                                + ( item.city ? item.city.escapeHtml() : "" )
-                                + " "
-                                + ( item.zipcode ? item.zipcode.escapeHtml() : "" )
-                                + " "
-                                + ( item.country ? item.country.escapeHtml() : "" )
-                            + "</small>"
-                        + "</a>" )
-                    .appendTo( ul );
-                };
-                [% END %]
-            [% END %]
             Sticky = $("#toolbar");
             Sticky.hcSticky({
                 stickTo: "#existing_holds",
@@ -1591,6 +1568,78 @@
                 return false;
             });
 
+            [% FOREACH biblionumber IN biblionumbers %]
+                [% SET url_biblio_params = url_biblio_params _ "&amp;biblionumber=" _ biblionumber %]
+            [% END %]
+            [% IF multi_hold %]
+                [% SET url_biblio_params = url_biblio_params _ "&amp;multi_hold=1" %]
+            [% END %]
+            search = 0;
+            dtMemberResults = KohaTable("table_borrowers", {
+                'bServerSide': true,
+                'sAjaxSource': "/cgi-bin/koha/svc/members/search",
+                'fnServerData': function(sSource, aoData, fnCallback) {
+                    if ( ! search ) {
+                        return;
+                    }
+                    aoData.push({
+                        'name': 'searchmember',
+                        'value': $("#patron").val()
+                    },{
+                        'name': 'template_path',
+                        'value': 'reserve/tables/members_results.tt',
+                    });
+                    $.ajax({
+                        'dataType': 'json',
+                        'type': 'POST',
+                        'url': sSource,
+                        'data': aoData,
+                        'success': function(json){
+                            // redirect if there is only 1 result.
+                            if ( json.aaData.length == 1 ) {
+                                var borrowernumber = json.aaData[0].borrowernumber;
+                                document.location.href = '/cgi-bin/koha/reserve/request.pl?borrowernumber=' + borrowernumber + "[% url_biblio_params %]"
+                                return false;
+                            }
+                            fnCallback(json);
+                        }
+                    });
+                },
+                'fnDrawCallback': function (oSettings) {
+                    var data = this.fnGetData();
+                    $.each($(this).find("tbody tr"), function(index, tr) {
+                        let url = '/cgi-bin/koha/reserve/request.pl?borrowernumber=' + data[index].borrowernumber + "[% url_biblio_params %]"
+                        $(tr).off('click').on('click', function() {
+                            document.location.href = url;
+                        }).addClass('clickable');
+                        $(tr).find("a.patron_preview").attr('href', url);
+                    });
+                },
+                'aoColumns':[
+                    { 'mDataProp': 'dt_name' },
+                    { 'mDataProp': 'dt_address' },
+                    { 'mDataProp': 'dt_cardnumber' },
+                    { 'mDataProp': 'dt_dateofbirth' },
+                    { 'mDataProp': 'dt_category' },
+                    { 'mDataProp': 'dt_branch' },
+                    { 'mDataProp': 'dt_phone' },
+                ],
+                'bFilter': false,
+                'bAutoWidth': false,
+                'sPaginationType': 'full_numbers',
+                "bProcessing": true
+            }, columns_settings_borrowers_table );
+            $("#table_borrowers_wrapper").hide();
+
+            function filter() {
+                search = 1;
+                $("#table_borrowers").show();
+                $("#table_borrowers_wrapper").show();
+                dtMemberResults.fnDraw();
+                return false;
+            }
+            $("#holds_patronsearch").on("submit", filter);
+
         });
     </script>
 [% END %]
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/tables/members_results.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/tables/members_results.tt
new file mode 100644
index 0000000000..15370307a5
--- /dev/null
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/tables/members_results.tt
@@ -0,0 +1,32 @@
+[% USE raw %]
+[% USE I18N %]
+[% USE To %]
+[% USE Price %]
+[% PROCESS 'member-display-address-style.inc' %]
+{
+    "sEcho": [% sEcho | html %],
+    "iTotalRecords": [% iTotalRecords | html %],
+    "iTotalDisplayRecords": [% iTotalDisplayRecords | html %],
+    "aaData": [
+        [% FOREACH data IN aaData %]
+            {
+                "dt_name":
+                    "<a href=\"/cgi-bin/koha/members/moremember.pl?borrowernumber=[% data.borrowernumber | html %]\" class=\"patron_preview\" data-borrowernumber=\"[% data.borrowernumber | html %]\" style='white-space:nowrap' title=\"[% I18N.t("View") | html %]\">[% INCLUDE 'patron-title.inc' borrowernumber = data.borrowernumber category_type = data.category_type firstname = data.firstname surname = data.surname othernames = data.othernames invert_name = 1 | $To %]</a><br />",
+                "dt_address":
+                    "[%~ INCLUDE 'display-address-style' patron=data no_line_break=1 | $To ~%]",
+                "dt_cardnumber":
+                    "[% data.cardnumber | html | $To %]",
+                "dt_dateofbirth":
+                    "[% INCLUDE 'patron-age.inc' patron = data %]",
+                "dt_category":
+                    "[% data.category_description | html | $To %] <span class=\"patron_category_type\">([% data.category_type | html | $To %])</span>",
+                "dt_branch":
+                    "[% data.branchname | html | $To %]",
+                "dt_phone":
+                    "[% data.phone| html | $To %]",
+                "borrowernumber":
+                    "[% data.borrowernumber | html %]"
+            }[% UNLESS loop.last %],[% END %]
+        [% END %]
+    ]
+}
diff --git a/koha-tmpl/intranet-tmpl/prog/js/circ-patron-search-results.js b/koha-tmpl/intranet-tmpl/prog/js/circ-patron-search-results.js
deleted file mode 100644
index 578a1b8a2d..0000000000
--- a/koha-tmpl/intranet-tmpl/prog/js/circ-patron-search-results.js
+++ /dev/null
@@ -1,13 +0,0 @@
-/* global dataTablesDefaults */
-$(document).ready(function() {
-    $(".clickable").click(function() {
-        window.document.location = $(this).data('url');
-    });
-    var table = KohaTable("table_borrowers",
-        {
-            "aaSorting": [ 0, "asc" ],
-            "sDom": "t",
-            "paging": false
-        },
-        columns_settings_borrowers_table, null);
-});
diff --git a/reserve/request.pl b/reserve/request.pl
index 12a8b17130..bc53d78857 100755
--- a/reserve/request.pl
+++ b/reserve/request.pl
@@ -144,25 +144,7 @@ elsif ( $action eq 'cancelBulk' ) {
 
 if ($findborrower) {
     my $patron = Koha::Patrons->find( { cardnumber => $findborrower } );
-    if ( $patron ) {
-        $borrowernumber_hold = $patron->borrowernumber;
-    } else {
-        my $dt_params = { iDisplayLength => -1 };
-        my $results = C4::Utils::DataTables::Members::search(
-            {
-                searchmember => $findborrower,
-                dt_params => $dt_params,
-            }
-        );
-        my $borrowers = $results->{patrons};
-        if ( scalar @$borrowers == 1 ) {
-            $borrowernumber_hold = $borrowers->[0]->{borrowernumber};
-        } elsif ( @$borrowers ) {
-            $template->param( borrowers => $borrowers );
-        } else {
-            $messageborrower = "'$findborrower'";
-        }
-    }
+    $borrowernumber_hold = $patron->borrowernumber if $patron;
 }
 
 if($findclub) {
-- 
2.30.2