Bug 34519: Add a template plugin for fetch searchable patron attributes
[koha.git] / koha-tmpl / intranet-tmpl / prog / en / modules / members / member.tt
1 [% USE raw %]
2 [% USE AdditionalContents %]
3 [% USE Asset %]
4 [% USE Koha %]
5 [% USE TablesSettings %]
6 [% USE Branches %]
7 [% USE Categories %]
8 [% PROCESS 'i18n.inc' %]
9 [% SET footerjs = 1 %]
10 [% PROCESS 'patronfields.inc' %]
11 [% SET libraries = Branches.all %]
12 [% SET categories = Categories.all.unblessed %]
13 [% SET columns = ['cardnumber', 'name-address', 'dateofbirth', 'branch', 'category', 'dateexpiry', 'checkouts', 'account_balance', 'borrowernotes', 'action'] %]
14 [% SET searchtype = searchtype || Koha.Preference('DefaultPatronSearchMethod') %]
15 [% PROCESS 'patron-search.inc' %]
16 [% INCLUDE 'doc-head-open.inc' %]
17 <title>[% FILTER collapse %]
18     [% IF ( searching ) %]
19         [% t("Search results") | html %] &rsaquo;
20     [% END %]
21     [% t("Patrons") | html %] &rsaquo;
22     [% t("Koha") | html %]
23 [% END %]</title>
24 [% INCLUDE 'doc-head-close.inc' %]
25 </head>
26
27 <body id="pat_member" class="pat">
28 [% WRAPPER 'header.inc' %]
29     [% INCLUDE 'patron-search-header.inc' %]
30 [% END %]
31
32 [% WRAPPER 'sub-header.inc' %]
33     [% WRAPPER breadcrumbs %]
34         [% WRAPPER breadcrumb_item bc_active= 1 %]
35             <span>Patrons</span>
36         [% END %]
37     [% END #/ WRAPPER breadcrumbs %]
38 [% END #/ WRAPPER sub-header.inc %]
39
40 <div class="main container-fluid">
41     <div class="row">
42         <div class="col-sm-10 col-sm-push-2">
43             <main>
44
45           [% IF CAN_user_tools_manage_patron_lists %]
46             <div id="patron_list_dialog" class="dialog message">
47               Added <span class="patrons-length"></span> patrons to <a></a>.
48             </div>
49           [% END %]
50
51           [% INCLUDE 'patron-toolbar.inc' %]
52           [% INCLUDE 'noadd-warnings.inc' %]
53
54           [% IF CAN_user_borrowers_edit_borrowers && pending_borrower_modifications %]
55             <div class="pending-info" id="patron_updates_pending">
56               <a href="/cgi-bin/koha/members/members-update.pl">Patrons requesting modifications</a>:
57               <span class="number_box"><a href="/cgi-bin/koha/members/members-update.pl">[% pending_borrower_modifications | html %]</a></span>
58             </div>
59           [% END %]
60
61           <div id="searchresults">
62             [% IF CAN_user_tools_manage_patron_lists || CAN_user_borrowers_edit_borrowers %]
63               <div class="searchheader fh-fixedHeader" id="searchheader" style="display:none;">
64                   <div>
65                       <a href="#" class="btn btn-link" id="select_all"><i class="fa fa-check"></i> Select all</a>
66                       |
67                       <a href="#" class="btn btn-link" id="clear_all"><i class="fa fa-times"></i> Clear all</a>
68                     [% IF CAN_user_tools_manage_patron_lists %]
69
70                     [% END %]
71
72                     [% IF CAN_user_tools_manage_patron_lists %]
73                         <div id="patronlist-dropdown" class="btn-group">
74                             <button id="patronlist-menu" type="button" class="btn btn-sm btn-default dropdown-toggle patron-edits disabled" disabled="disabled" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
75                                 Add to patron list <span class="caret"></span>
76                             </button>
77                             <ul class="dropdown-menu">
78                                 [% IF patron_lists %]
79                                     [% FOREACH pl IN patron_lists %]
80                                         <li><a href="#" class="patron-list-add" data-listid="[% pl.patron_list_id | html %]">[% pl.name | html %]</a></li>
81                                     [% END %]
82                                 [% END %]
83                                 <li role="separator" class="divider"></li>
84                                 <li><a href="#" class="patron-list-add" data-listid="new">New list</a></li>
85                             </ul>
86                         </div>
87                     [% END %]
88
89                     [% IF CAN_user_borrowers_edit_borrowers %]
90                         <div class="btn-group">
91                             <button id="merge-patrons" class="btn btn-sm btn-default disabled" disabled="disabled" type="submit"><i class="fa fa-compress" aria-hidden="true"></i> Merge selected patrons</button>
92                         </div>
93                     [% END %]
94
95                     [% IF CAN_user_tools_edit_patrons %]
96                         <div class="btn-group">
97                             <button id="batch-mod-patrons" class="btn btn-default btn-sm" type="button"><i class="fa fa-pencil" aria-hidden="true"></i> Batch patron modification</button>
98                         </div>
99                     [% END %]
100
101                     <div id="table_search_selections" class="btn-group" style="display:none;">
102                         <span></span>
103                         <a href="#" id="clear-row-selection"><i class="fa fa-times"></i> Clear</a>
104                     </div>
105                   </div>
106                 </div>
107             [% END %]
108
109             [% IF CAN_user_borrowers_edit_borrowers || CAN_user_tools_manage_patron_lists %]
110                 [% columns.unshift('checkbox') | html %]
111             [% END %]
112             [% PROCESS patron_search_table table_id => 'memberresultst' columns => columns %]
113           </div>
114         [% IF CAN_user_tools_edit_patrons %]
115             <form id="patron_batchmod_form" method="post" action="/cgi-bin/koha/tools/modborrowers.pl">
116                 <input type="hidden" name="op" value="show" />
117                 <textarea style="display:none" id="borrowernumberlist" name="borrowernumberlist"></textarea>
118             </form>
119         [% END %]
120
121                 [%- SET StaffPatronsHome = AdditionalContents.get( location => "StaffPatronsHome", lang => lang, library => logged_in_user.branchcode ) -%]
122                 [%- FOREACH block IN StaffPatronsHome.content -%]
123                 <div class="page-section">
124                     [%- block.content | $raw -%]
125                 </div>
126                 [%- END -%]
127
128             </main>
129         </div> <!-- /.col-sm-10.col-sm-push-2 -->
130
131         <div class="col-sm-2 col-sm-pull-10">
132             <aside>
133                 [% PROCESS patron_search_filters categories => categories, libraries => libraries, filters => ['search_field', 'search_type', 'category', 'branch'], search_filter => searchmember %]
134             </aside>
135         </div> <!-- /.col-sm-2.col-sm-pull-10 -->
136     </div> <!-- /.row -->
137
138     <!-- New Patron List Modal -->
139     <div class="modal" id="new-patron-list" tabindex="-1" role="dialog" aria-labelledby="new-patron-listLabel">
140         <div class="modal-dialog" role="document">
141             <div class="modal-content">
142                 <div class="modal-header">
143                     <button type="button" class="closebtn" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
144                     <h4 class="modal-title" id="new-patron-listLabel">Add patrons to a new patron list</h4>
145                 </div>
146                 <form id="new-patron-list_form">
147                     <div class="modal-body">
148                         <div class="form-group">
149                             <label for="new_patron_list" class="required">Patron list name: </label>
150                             <input class="form-control required" type="text" name="new_patron_list" id="new_patron_list" required="required" />
151                             <input type="hidden" name="add_to_patron_list" id="add_to_patron_list" />
152                             <span class="required">Required</span>
153                         </div>
154                     </div> <!-- /.modal-body -->
155                     <div class="modal-footer">
156                         <button type="submit" id="add_to_patron_list_submit" class="btn btn-default approve">Submit</button>
157                         <button type="button" class="btn btn-default deny" data-dismiss="modal">Cancel</button>
158                     </div> <!-- /.modal-footer -->
159                 </form> <!-- /#new-patron-list_form -->
160             </div> <!-- /.modal-content -->
161         </div> <!-- /.modal-dialog -->
162     </div> <!-- /#new-patron-list -->
163
164 [% MACRO jsinclude BLOCK %]
165     [% INCLUDE 'datatables.inc' %]
166     [% INCLUDE 'columns_settings.inc' %]
167     [% INCLUDE 'str/members-menu.inc' %]
168     [% Asset.js("js/members-menu.js") | $raw %]
169     [% INCLUDE 'select2.inc' %]
170     <script>
171         function showPatronSelections( number ){
172             $("#table_search_selections").show().find("span").text(_("Patrons selected: " + number ) );
173         }
174
175         $(document).ready(function() {
176             $('#merge-patrons, #batch-mod-patrons').prop('disabled', true);
177             $('#memberresultst').on('change', 'input.selection', function() {
178                 var patron_search_selections = JSON.parse( localStorage.getItem("patron_search_selections") ) || [];
179                 var borrowernumber = $(this).val();
180                 if( $(this).prop("checked") ){
181                     patron_search_selections.push( $(this).val() );
182                     localStorage.setItem('patron_search_selections', JSON.stringify( patron_search_selections ));
183                     showPatronSelections( patron_search_selections.length );
184                 } else {
185                     var filtered = patron_search_selections.filter(function( value ){
186                         return value !== borrowernumber;
187                     });
188                     if( filtered.length > 0 ){
189                         localStorage.setItem('patron_search_selections', JSON.stringify( filtered ));
190                         patron_search_selections = filtered;
191                         showPatronSelections( filtered.length );
192                     } else {
193                         patron_search_selections = [];
194                         localStorage.removeItem('patron_search_selections');
195                         $("#table_search_selections").hide();
196                     }
197                 }
198                 if ( patron_search_selections.length > 1 ) {
199                     /* More than one checkbox has been checked. All batch options enabled */
200                     $("#batch-mod-patrons, #merge-patrons, #patronlist-menu").removeClass("disabled").prop("disabled", false);
201                 } else if ( patron_search_selections.length == 1 ) {
202                     /* Only one checkbox has been checked */
203                     $("#batch-mod-patrons, #patronlist-menu").removeClass("disabled").prop("disabled", false);
204                     /* Merge requires more than one selection */
205                     $('#merge-patrons').prop('disabled', true).addClass("disabled");
206                 } else {
207                     /* No checkbox has been checked. No batch options enabled */
208                     $("#batch-mod-patrons, #merge-patrons, #patronlist-menu").addClass("disabled").prop("disabled", true);
209                 }
210             });
211
212             $('#merge-patrons').on('click', function() {
213                 var patron_search_selections = JSON.parse( localStorage.getItem("patron_search_selections") ) || [];
214                 var merge_patrons_url = 'merge-patrons.pl?id=' + patron_search_selections.join("&id=");
215                 window.location.href = merge_patrons_url;
216             });
217
218             $("#clear-row-selection").on("click", function(e){
219                 e.preventDefault();
220                 $("input.selection").prop("checked", false).change();
221                 localStorage.removeItem("patron_search_selections");
222                 $("#table_search_selections").hide();
223                 $('#merge-patrons, #patronlist-menu, #batch-mod-patrons').prop('disabled', true).addClass("disabled");
224                 $("#borrowernumberlist").val("");
225             });
226
227             $("#patronlist-dropdown").on("click", ".patron-list-add", function(e){
228                 e.preventDefault();
229                 var patron_search_selections = JSON.parse( localStorage.getItem("patron_search_selections") ) || [];
230                 if ( patron_search_selections.length == 0 ) {
231                     alert( _("You have not selected any patrons to add to a list!") );
232                     $(".btn-group").removeClass("open"); /* Close button menu */
233                     return false;
234                 }
235
236                 var listid = $(this).data("listid");
237                 $("#add_to_patron_list").val( listid );
238                 if( listid == "new" ){
239                     /* #add_to_patron_list value "new" in the modal form will tell API to create a new list */
240                     $("#new-patron-list").modal("show");
241                 } else {
242                     /* Ajax submit the patrons to list */
243
244                     patronListAdd();
245                 }
246             });
247
248             $("#batch-mod-patrons").on("click", function(e) {
249                 e.preventDefault();
250                 var patron_search_selections = JSON.parse( localStorage.getItem("patron_search_selections") ) || [];
251                 if( patron_search_selections.length > 0 ){
252                     $("#borrowernumberlist").html( patron_search_selections.join('\n') );
253                     $("#patron_batchmod_form").submit();
254                 }
255             });
256
257             /* Submit selected patrons to a list via AJAX */
258             $("#new-patron-list_form").on('submit', function(e){
259                 e.preventDefault();
260                 /* Upon submitting modal patron list add form... */
261                 if ( $('#new_patron_list').val() ) {
262                     $(".patron-list-add").each(function() {
263                         /* Check each list name in the menu of patron lists */
264                         /* If submitted list name matches... */
265                         if ( $(this).text() == $('#new_patron_list').val() ) {
266                             alert( _("You already have a list with that name!") );
267                             return false;
268                         }
269                     });
270                 } else {
271                     alert( _("You must give your new patron list a name!") );
272                     return false;
273                 }
274                 $("#new-patron-list").modal("hide");
275                 patronListAdd();
276             });
277
278             $("#select_all").on("click",function(e){
279                 e.preventDefault();
280                 $("input.selection").each(function(){
281                     if( $(this).prop("checked") == false ){
282                         $(this).prop( "checked", true ).change();
283                     }
284                 });
285             });
286             $("#clear_all").on("click",function(e){
287                 e.preventDefault();
288                 $("input.selection").each(function(){
289                     if( $(this).prop("checked") ){
290                         $(this).prop("checked", false ).change();
291                     }
292                 });
293             });
294
295             [% IF searchmember %]
296                 $("#searchmember_filter").val("[% searchmember | html %]");
297             [% END %]
298             [% IF searchfieldstype %]
299                 $("searchfieldstype_filter").val("[% searchfieldstype | html %]");
300             [% END %]
301             [% IF searchtype %]
302                 $("#searchtype_filter option[value='[% searchtype | html %]']").prop("selected", true);
303             [% END %]
304             [% IF categorycode_filter %]
305                 $("#categorycode_filter").val("[% categorycode_filter | html %]");
306             [% END %]
307             [% IF branchcode_filter %]
308                 $("#branchcode_filter").val("[% branchcode_filter | html %]");
309             [% END %]
310
311             $("#searchheader").hide();
312             $("#patron_search_form").on('submit', function(){$("#searchheader").show();});
313             $("#clear_search").on("click",function(e){$("#searchheader").hide();});
314         });
315
316         function patronListAdd(){
317             var borrowernumbers = JSON.parse( localStorage.getItem("patron_search_selections") ) || [];
318             if ( borrowernumbers.length > 0 ){
319                 var data = {
320                     add_to_patron_list: $("#add_to_patron_list").val(),
321                     new_patron_list: $("#new_patron_list").val(),
322                     borrowernumbers: borrowernumbers
323                 };
324                 $.ajax({
325                     data: data,
326                     type: 'POST',
327                     url: '/cgi-bin/koha/svc/members/add_to_list',
328                     success: function(data) {
329                         $("#patron_list_dialog").show();
330                         $("#patron_list_dialog > span.patrons-length").html(data.patrons_added_to_list);
331                         $("#patron_list_dialog > a").attr("href", "/cgi-bin/koha/patron_lists/list.pl?patron_list_id=" + data.patron_list.patron_list_id);
332                         $("#patron_list_dialog > a").html(data.patron_list.name);
333
334                         if ( $('#add_to_patron_list').val() == 'new' ) {
335                             /* Add a new entry to the menu */
336                             $("#patronlist-dropdown .divider").before('<li><a class="patron-list-add" href="#" data-listid="' + data.patron_list.patron_list_id + '">' + data.patron_list.name + '</li>');
337                         }
338                     },
339                     error: function() {
340                         alert( _("An error occurred. Patron list could not be updated.") );
341                     }
342                 });
343                 return true;
344             } else {
345                 alert( _("You have not selected any patrons to add to a list!") );
346                 return false;
347             }
348         }
349
350         function prepSelections(){
351             var selected_patrons = JSON.parse( localStorage.getItem("patron_search_selections") );
352             if( selected_patrons && selected_patrons.length > 0 ){
353                 showPatronSelections( selected_patrons.length );
354
355                 $('#merge-patrons').prop('disabled', true);
356                 $("input.selection").each(function(){
357                     var cardnumber = $(this).val();
358                     if( selected_patrons.indexOf( cardnumber ) >= 0 ){
359                         $(this).prop("checked", true );
360                     }
361                 });
362
363                 if( selected_patrons.length > 1 ){
364                     $('#batch-mod-patrons, #merge-patrons, #patronlist-menu').removeClass("disabled").prop('disabled', false);
365                 }
366             }
367         }
368
369         $('#memberresultst tbody').on('click','td',function(e){
370             var $checkbox = $(this).find("input[type=checkbox]");
371             if (e.target.type != "checkbox") {
372                 $checkbox.prop('checked', !$checkbox.prop("checked"));
373                 $checkbox.change();
374             }
375         });
376
377     </script>
378
379     <script>
380         // Apply DataTables on the results table
381         var table_settings = [% TablesSettings.GetTableSettings( 'members', 'member', 'memberresultst', 'json' ) | $raw %];
382         [% UNLESS CAN_user_borrowers_edit_borrowers OR CAN_user_tools_manage_patron_lists %]
383             [%# Remove the first column if we do not display the checkbox %]
384             table_settings['columns'].splice(0, 1);
385         [% END %]
386     </script>
387
388     [% IF circsearch == 1 %]
389         [% SET redirect_url = '/cgi-bin/koha/circ/circulation.pl' %]
390     [% ELSE %]
391         [% SET redirect_url = '/cgi-bin/koha/members/moremember.pl' %]
392     [% END %]
393     [% PROCESS patron_search_js table_id => 'memberresultst', categories => categories, libraries => libraries, columns => columns,actions => ['edit', 'checkout'], redirect_if_one_result => 1, redirect_url => redirect_url, sticky_header => "searchheader", sticky_to => "searchresults", default_sort_column => 'name-address', display_search_description => 1, remember_selections => 1 %]
394
395 [% END %]
396 [% INCLUDE 'intranet-bottom.inc' %]