View | Details | Raw Unified | Return to bug 30093
Collapse All | Expand All

(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/js-patron-format-address.inc (-9 / +101 lines)
Lines 1-20 Link Here
1
<!-- js-patron-format-address.inc -->
1
<!-- js-patron-format-address.inc -->
2
[% USE raw %]
3
[% USE To %]
4
[% USE AuthorisedValues %]
2
<script>
5
<script>
3
    (function() {
6
    (function() {
4
7
5
        window.$format_address = function(data, options) {
8
        const roadtypes = [% To.json(AuthorisedValues.Get('ROADTYPE')) | $raw %];
9
        let roadtypes_map = roadtypes.reduce((map, r) => {
10
            map[r.street_type] = r;
11
            return map;
12
        }, {});
13
14
        function member_display_address_style_us(data, line_break) {
15
            let address = "";
16
            if ( data.address || data.address2 ) {
17
                if ( data.address ) {
18
                    let roadtype_desc = '';
19
                    if ( data.street_type ) {
20
                        roadtype_desc = roadtypes_map[data.street_type] ? roadtypes_map[data.street_type].street_type : data.street_type;
21
                    }
22
                    address += '<li class="patronaddress1">' + escape_str(data.streetnumber) + ' ' + escape_str(data.address) + ' ' + escape_str(roadtype_desc) + '</li>';
23
                }
24
            }
25
            if ( data.address2 ) {
26
                address += '<li class="patronaddress2">' + escape_str(data.address2) + '</li>'
27
            }
28
            if ( data.city || data.postal_code || data.state || data.country ) {
29
                address += '<li class="patroncity">' + escape_str(data.city);
30
                if ( data.state ) {
31
                    if ( data.city ) {
32
                        address += ', ';
33
                    }
34
                    address += escape_str(data.city);
35
                }
36
                if ( data.postal_code ) {
37
                    address += " " + escape_str(data.postal_code);
38
                }
39
                if ( data.country ) {
40
                    if ( data.postal_code || data.state || data.city ) {
41
                        address += ', ';
42
                    }
43
                    address += escape_str(data.country)
44
                }
45
                address += '</li>'
46
            }
6
47
7
            let address = '';
8
            address += (data.street_number ? data.street_number + ' ' : '' );
9
            address += (data.address ? data.address + ' ' : '' );
10
            address += (data.address2 ? data.address2 + ' ' : '' );
11
            address += (data.city ? data.city + ' ' : '' );
12
            address += (data.state ? data.state + ' ' : '' );
13
            address += (data.postal_code ? data.postal_code + ' ' : '' );
14
            address += (data.country ? data.country + ' ' : '' );
15
            return address;
48
            return address;
16
        }
49
        }
17
50
51
        function member_display_address_style_de(data, line_break) {
52
            let address = "";
53
            if ( data.address || data.address2 ) {
54
                if ( data.address ) {
55
                    let roadtype_desc = '';
56
                    if ( data.street_type ) {
57
                        roadtype_desc = roadtypes_map[data.street_type] ? roadtypes_map[data.street_type].street_type : data.street_type;
58
                    }
59
                    address += '<li class="patronaddress1">' + escape_str(data.address) + ' ' + escape_str(roadtype_desc) + escape_str(data.street_number) + '</li>';
60
                }
61
            }
62
            if ( data.address2 ) {
63
                address += '<li class="patronaddress2">' + escape_str(data.address2) + '</li>'
64
            }
65
            if ( data.city || data.postal_code || data.state || data.country ) {
66
                address += '<li class="patroncity">';
67
                address += escape_str(data.postal_code) + ' ' + escape_str(data.city);
68
                address += data.state   ? line_break + escape_str(data.state)   : '';
69
                address += data.country ? line_break + escape_str(data.country) : '';
70
                address += '</li>'
71
            }
72
73
            return address;
74
        }
75
76
        function member_display_address_style_fr(data, line_break) {
77
            let address = "";
78
            if ( data.address || data.address2 ) {
79
                if ( data.address ) {
80
                    let roadtype_desc = '';
81
                    if ( data.street_type ) {
82
                        roadtype_desc = roadtypes_map[data.street_type] ? roadtypes_map[data.street_type].street_type : data.street_type;
83
                    }
84
                    address += '<li class="patronaddress1">' + escape_str(data.street_number) + ' ' + escape_str(roadtype_desc) + escape_str(data.address) + '</li>';
85
                }
86
            }
87
            if ( data.address2 ) {
88
                address += '<li class="patronaddress2">' + escape_str(data.address2) + '</li>'
89
            }
90
            if ( data.city || data.postal_code || data.state || data.country ) {
91
                address += '<li class="patroncity">';
92
                address += escape_str(data.postal_code) + ' ' + escape_str(data.city);
93
                address += data.state   ? line_break + escape_str(data.state)   : '';
94
                address += data.country ? line_break + escape_str(data.country) : '';
95
                address += '</li>'
96
            }
97
98
            return address;
99
        }
100
101
        window.$format_address = function(data, options) {
102
            let line_break = options && options.no_line_break ? ' ' : '<br/>';
103
            [%~ IF Koha.Preference( 'AddressFormat' ) ~%]
104
                return member_display_address_style_[% Koha.Preference( 'AddressFormat' ) %](data, line_break);
105
            [%~ ELSE ~%]
106
                return member_display_address_style_us(data, line_break);
107
            [%~ END ~%]
108
        }
109
18
    })();
110
    })();
19
</script>
111
</script>
20
<!-- / js-patron-format-address.inc -->
112
<!-- / js-patron-format-address.inc -->
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/patron-search.inc (+500 lines)
Line 0 Link Here
1
[% USE Koha %]
2
[% USE Branches %]
3
[% USE raw %]
4
[% USE To %]
5
6
[% BLOCK patron_search_filters_simple  %]
7
    <form id="patron_search_form">
8
        <div class="hint">Enter patron card number or partial name:</div>
9
        <input type="text" size="40" id="search_patron_filter" class="focus" autocomplete="off" />
10
        <input type="submit" value="Search" />
11
    </form>
12
[% END %]
13
14
[% BLOCK patron_search_filters %]
15
    <form id="patron_search_form">
16
        <fieldset class="brief">
17
            <h3>Search for patron</h3>
18
            <ol>
19
                <li>
20
                    <label for="search_patron_filter">Search:</label>
21
                    <div class="hint">Enter patron card number or partial name:</div>
22
                    <input type="text" id="search_patron_filter" value="[% search_filter | html %]" class="focus" />
23
                </li>
24
25
                [% FOR column IN columns %]
26
                    [% SWITCH column %]
27
                    [% CASE 'branch' %]
28
                        <li>
29
                            <label for="branchcode_filter">Library:</label>
30
                            <select id="branchcode_filter">
31
                                [% SET libraries = Branches.all( only_from_group => 1 ) %]
32
                                [% IF libraries.size != 1 %]
33
                                    <option value="">Any</option>
34
                                [% END %]
35
                                [% FOREACH l IN libraries %]
36
                                    <option value="[% l.branchcode | html %]">[% l.branchname | html %]</option>
37
                                [% END %]
38
                            </select>
39
                        </li>
40
                    [% CASE 'category' %]
41
                        <li>
42
                            <label for="categorycode_filter">Category:</label>
43
                            <select id="categorycode_filter">
44
                                <option value="">Any</option>
45
                                [% FOREACH category IN categories %]
46
                                    <option value="[% category.categorycode | html %]">[% category.description | html %]</option>
47
                                [% END %]
48
                            </select>
49
                        </li>
50
                    [% END %]
51
                [% END %]
52
            </ol>
53
            <fieldset class="action">
54
                <input type="submit" value="Search" />
55
            </fieldset>
56
        </fieldset>
57
    </form>
58
[% END %]
59
60
[% BLOCK patron_search_table %]
61
62
    [% IF filter == 'suggestions_managers' %]
63
        <div class="hint">Only staff with superlibrarian or suggestions_manage permissions are returned in the search results</div>
64
    [% ELSIF filter == 'orders_managers' %]
65
        <div class="hint">Only staff with superlibrarian or acquisitions permissions (or order_manage permission if granular permissions are enabled) are returned in the search results</div>
66
    [% ELSIF filter == 'funds_owners' OR filter == 'funds_users' %]
67
        <div class="hint">Only staff with superlibrarian or acquisitions permissions (or budget_modify permission if granular permissions are enabled) are returned in the search results</div>
68
    [% END %]
69
70
    <div class="browse">
71
        Browse by last name:
72
        [% SET alphabet = Koha.Preference('alphabet').split(' ') %]
73
        [% UNLESS alphabet.size %]
74
            [% alphabet = ['A' .. 'Z'] %]
75
        [% END %]
76
        [% FOREACH letter IN alphabet %]
77
            <a href="#" class="filterByLetter">[% letter | html %]</a>
78
        [% END %]
79
    </div>
80
81
    <div id="[% table_id %]_search_results" style="display:none;">
82
83
        <div id="info" class="dialog message" style="display: none;"></div>
84
        <div id="error" class="dialog alert" style="display: none;"></div>
85
86
87
        <input type="hidden" id="firstletter_filter" value="" />
88
        [% IF open_on_row_click %]
89
        <table id="[% table_id %]" class="selections-table">
90
        [% ELSE %]
91
        <table id="[% table_id %]">
92
        [% END %]
93
            <thead>
94
                <tr>
95
                    [% FOR column IN columns %]
96
                        [% SWITCH column %]
97
                            [% CASE 'cardnumber' %]<th>Card</th>
98
                            [% CASE 'dateofbirth' %]<th>Date of birth</th>
99
                            [% CASE 'name' %]<th>Name</th>
100
                            [% CASE 'name-address' %]<th>Name</th>
101
                            [% CASE 'address' %]<th>Address</th>
102
                            [% CASE 'address-library' %]<th>Address</th>
103
                            [% CASE 'branch' %]<th data-filter="libraries">Library</th>
104
                            [% CASE 'category' %]<th data-filter="categories">Category</th>
105
                            [% CASE 'dateexpiry' %]<th>Expires on</td>
106
                            [% CASE 'borrowernotes' %]<th>Notes</th>
107
                            [% CASE 'phone' %]<th>Phone</th>
108
                            [% CASE 'action' %]<th>&nbsp;</th>
109
                        [% END %]
110
                    [% END %]
111
                </tr>
112
              </thead>
113
            <tbody></tbody>
114
        </table>
115
    </div>
116
117
<!-- Patron preview modal -->
118
<div class="modal" id="patronPreview" tabindex="-1" role="dialog" aria-labelledby="patronPreviewLabel">
119
    <div class="modal-dialog" role="document">
120
        <div class="modal-content">
121
            <div class="modal-header">
122
                <button type="button" class="closebtn" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
123
                <h4 class="modal-title" id="patronPreviewLabel"></h4>
124
            </div>
125
            <div class="modal-body">
126
                <div id="loading">
127
                    <img src="[% interface | html %]/[% theme | html %]/img/spinner-small.gif" alt="" /> Loading
128
                </div>
129
            </div>
130
            <div class="modal-footer">
131
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
132
            </div>
133
        </div>
134
    </div>
135
</div>
136
137
[% END %]
138
139
[% BLOCK patron_search_js %]
140
141
    [% IF redirect_if_one_result && !redirect_url %]
142
        <script>console.log("Wrong call of patron_searh_js - missing redirect_url");</script>
143
    [% END %]
144
    <script>
145
        let categories = [% To.json(categories) | $raw %];
146
        let categories_map = categories.reduce((map, c) => {
147
            map[c.categorycode] = c;
148
            return map;
149
        }, {});
150
        let libraries  = [% To.json(libraries) | $raw %];
151
        let libraries_map = libraries.reduce((map, l) => {
152
            map[l.branchcode] = l;
153
            return map;
154
        }, {});
155
156
        [% IF Koha.Preference('ExtendedPatronAttributes') %]
157
            let extended_attribute_types = [% To.json(attribute_type_codes || []) | $raw %];
158
        [% END %]
159
160
    </script>
161
162
    [% INCLUDE 'datatables.inc' %]
163
    [% INCLUDE 'js-date-format.inc' %]
164
    [% INCLUDE 'js-patron-get-age.inc' %]
165
    [% INCLUDE 'js-patron-format.inc' %]
166
    [% INCLUDE 'js-patron-format-address.inc' %]
167
168
    <script>
169
        var first_draw = 0;
170
        let patrons_table;
171
172
        $(document).ready(function(){
173
174
175
            $("#info").hide();
176
            $("#error").hide();
177
178
            let additional_filters = {
179
                surname: function(){
180
                    let start_with = $("#firstletter_filter").val()
181
                    if (!start_with) return "";
182
                    return { "like": start_with + "%" }
183
                },
184
                "-and": function(){
185
                    let filter = $("#search_patron_filter").val();
186
                    if (!filter) return "";
187
                    [% SET search_fields = Koha.Preference('DefaultPatronSearchFields') || 'surname,firstname,othernames,cardnumber,userid' %]
188
                    return [
189
                        [% FOR search_field IN search_fields.split(',') %]
190
                        {"me.[% search_field | html %]":{"like":"%"+filter+"%"}},
191
                        [% END %]
192
                        [% IF Koha.Preference('ExtendedPatronAttributes') %]
193
                        {
194
                            "extended_attributes.value": { "like": "%" + filter + "%" },
195
                            "extended_attributes.code": extended_attribute_types
196
                        }
197
                        [% END %]
198
                    ];
199
                }
200
            };
201
            [% UNLESS default_sort_column %]
202
                [% default_sort_column = "name" %]
203
            [% END %]
204
            [% SET order_column_index = 0 %]
205
            patrons_table = $("#[% table_id %]").kohaTable({
206
                "ajax": {
207
                    [% SWITCH filter %]
208
                    [% CASE 'suggestions_managers' %]
209
                        "url": '/api/v1/suggestions/managers',
210
                    [% CASE 'baskets_managers' %]
211
                        "url": '/api/v1/acquisitions/baskets/managers',
212
                    [% CASE 'funds_owners' %]
213
                        "url": '/api/v1/acquisitions/funds/owners',
214
                    [% CASE 'funds_users' %]
215
                        "url": '/api/v1/acquisitions/funds/users',
216
                    [% CASE %]
217
                        "url": '/api/v1/patrons',
218
                    [% END %]
219
                    "dataSrc": function ( json ) {
220
                        [% IF redirect_if_one_result %]
221
                            // redirect if there is only 1 result.
222
                            if ( first_draw && json.recordsFiltered == 1 ) {
223
                                document.location.href = '[% redirect_url | url %]&borrowernumber=' + json.data[0].patron_id;
224
                                return false;
225
                            }
226
                            first_draw = 0;
227
                        [% END %]
228
                        return json.data;
229
                    }
230
                },
231
                embed: ['extended_attributes'],
232
                "drawCallback": function( settings ) {
233
                    var api = this.api();
234
                    var data = api.data();
235
                    if ( data.length == 0 ) return;
236
237
                    [% IF open_on_row_click %]
238
                    $.each($(this).find("tbody tr"), function(index, tr) {
239
                        let url = "[% on_click_url | url %]&borrowernumber=" + data[index].patron_id;
240
                        $(tr).off('click').on('click', function() {
241
                            document.location.href = url;
242
                        }).addClass('clickable');
243
                        $(tr).find("a.patron_name").attr('href', url);
244
                    });
245
                    [% ELSE %]
246
                    $.each($(this).find("tbody tr"), function(index, tr) {
247
                        $(tr).find("a.patron_name").addClass("patron_preview");
248
                    });
249
                    [% END %]
250
                },
251
                "iDeferLoading": 0,
252
                "columns": [
253
                    [% FOR column IN columns %]
254
                        [% IF default_sort_column == column %]
255
                            [% order_column_index = loop.count - 1%]
256
                        [% END %]
257
                        [% SWITCH column %]
258
                            [% CASE 'cardnumber' %]
259
                            {
260
                                "data": "cardnumber",
261
                                "searchable": true,
262
                                "orderable": true
263
                            }
264
                            [% CASE 'dateofbirth' %]
265
                            {
266
                                "data": "date_of_birth",
267
                                "searchable": true,
268
                                "orderable": true,
269
                                "render": function( data, type, row, meta ) {
270
                                    return data ? escape_str($date(data) + " (" + _("%s years").format($get_age(data)) + ")") : "";
271
                                }
272
                            }
273
                            [% CASE 'address' %]
274
                            {
275
                                "data": "me.street_number:me.address:me.address2:me.city:me.state:me.postal_code:me.country",
276
                                "searchable": true,
277
                                "orderable": true,
278
                                 "render": function( data, type, row, meta ) {
279
                                    let r = '<div class="address"><ul>';
280
                                    r += $format_address(row, { no_line_break: 1 });
281
                                    r += '</div></ul>';
282
                                    return r;
283
                                }
284
                            }
285
                            [% CASE 'address-library' %]
286
                            {
287
                                "data": "me.street_number:me.address:me.address2:me.city:me.state:me.postal_code:me.country",
288
                                "searchable": true,
289
                                "orderable": true,
290
                                "render": function( data, type, row, meta ) {
291
                                    let r = '<div class="address"><ul>';
292
                                    r += $format_address(row, { no_line_break: 1 });
293
                                    r += '</div></ul>';
294
                                    r += " " + escape_str(libraries_map[row.library_id].branchname);
295
                                    return r;
296
                                }
297
                            }
298
                            [% CASE 'name-address' %]
299
                            {
300
                                "data": "me.firstname:me.surname:me.othernames:me.street_number:me.address:me.address2:me.city:me.state:me.postal_code:me.country",
301
                                "searchable": true,
302
                                "orderable": true,
303
                                "render": function( data, type, row, meta ) {
304
                                    let patron_id = encodeURIComponent(row.patron_id);
305
                                    let r = '';
306
                                    [% IF ! open_on_row_click %]
307
                                    r += "<a href=\"/cgi-bin/koha/members/moremember.pl?borrowernumber=" + patron_id + "\" class=\"patron_name\" data-borrowernumber=\"" + patron_id + "\" style=\"white-space:nowrap\">" + $patron_to_html(row, { invert_name: 1 }) + "</a>";
308
                                    [% ELSE %]
309
                                    r += $patron_to_html(row, { invert_name: 1 });
310
                                    [% END %]
311
                                    r += '<br/>';
312
                                    r += '<div class="address"><ul>';
313
                                    r += $format_address(row, { no_line_break: 1 });
314
315
                                    if ( row.email ) {
316
                                        r += "<li>" + _("Email: ") + "<a href='mailto:" + encodeURIComponent(row.email) + "'>" + escape_str(row.email) + "</a></li>";
317
                                    }
318
                                    r += '</ul></div>'
319
320
                                    return r;
321
                                }
322
                            }
323
                            [% CASE 'name' %]
324
                            {
325
                                "data": "me.firstname:me.surname:me.othernames",
326
                                "searchable": true,
327
                                "orderable": true,
328
                                "render": function( data, type, row, meta ) {
329
                                    let patron_id = encodeURIComponent(row.patron_id);
330
                                    return "<a href=\"/cgi-bin/koha/members/moremember.pl?borrowernumber=" + patron_id + "\" class=\"patron_name\" data-borrowernumber=\"" + patron_id + "\" style=\"white-space:nowrap\">" + $patron_to_html(row, { invert_name: 1 }) + "</a>";
331
                                }
332
                            }
333
                            [% CASE 'branch' %]
334
                            {
335
                                "data": "library_id",
336
                                "searchable": true,
337
                                "orderable": true,
338
                                "render": function( data, type, row, meta ) {
339
                                    return escape_str(libraries_map[data].branchname);
340
                                }
341
                            }
342
                            [% CASE 'category' %]
343
                            {
344
                                "data": "category_id",
345
                                "searchable": true,
346
                                "orderable": true,
347
                                "render": function( data, type, row, meta ) {
348
                                    return escape_str(categories_map[data].description);
349
                                }
350
                            }
351
                            [% CASE 'dateexpiry' %]
352
                            {
353
                                "data": "expiry_date",
354
                                "searchable": true,
355
                                "orderable": true,
356
                                "render": function( data, type, row, meta ) {
357
                                    return data ? escape_str($date(data)) : "";
358
                                }
359
                            }
360
                            [% CASE 'borrowernotes' %]
361
                            {
362
                                "data": "staff_notes",
363
                                "searchable": true,
364
                                "orderable": true,
365
                                [%# We don't escape here, we allow html tag in staff notes %]
366
                            }
367
                            [% CASE 'phone' %]
368
                            {
369
                                "data": "phone",
370
                                "searchable": true,
371
                                "orderable": true,
372
                                "render": function( data, type, row, meta ) {
373
                                    return escape_str(data);
374
                                }
375
                            }
376
                            [% CASE 'action' %]
377
                            {
378
                                "data": function( row, type, val, meta ) {
379
380
                                    let patron_id = encodeURIComponent(row.patron_id);
381
                                    [% IF selection_type == 'select' %]
382
                                        return '<a href="#" class="btn btn-default btn-xs select_user" data-borrowernumber="' + patron_id + '">Select</a><input type="hidden" id="borrower_data' + patron_id + '" name="borrower_data'+ patron_id + '" value=\''+JSON.stringify(row)+'\' />';
383
                                    [% ELSE %]
384
                                        return '<a href="#" class="btn btn-default btn-xs add_user" data-borrowernumber="' + patron_id + '" data-firstname="' + encodeURIComponent(row.firstname) + '" data-surname="' + encodeURIComponent(row.surname) + '">Add</a><input type="hidden" id="borrower_data' + patron_id + '" name="borrower_data'+ patron_id + '" />';
385
                                    [% END %]
386
                                },
387
                                "searchable": false,
388
                                "orderable": false
389
                            }
390
                        [% END %]
391
                        [% UNLESS loop.last %],[% END %]
392
                    [% END %]
393
                ],
394
                "order": [[ [% order_column_index | html %], "asc" ]],
395
                'bAutoWidth': false,
396
                'sPaginationType': 'full_numbers',
397
                "iDisplayLength": [% Koha.Preference('PatronsPerPage') | html %],
398
            }, typeof table_settings !== 'undefined' ? table_settings : null, 1, additional_filters);
399
400
            $("#patron_search_form").on('submit', filter);
401
            $(".filterByLetter").on("click",function(e){
402
                e.preventDefault();
403
                filterByFirstLetterSurname($(this).text());
404
            });
405
            $("body").on("click",".add_user",function(e){
406
                e.preventDefault();
407
                var borrowernumber = $(this).data("borrowernumber");
408
                var firstname = $(this).data("firstname");
409
                var surname = $(this).data("surname");
410
                add_user( borrowernumber, firstname + " " + surname );
411
            });
412
413
            $("body").on("click",".select_user",function(e){
414
                e.preventDefault();
415
                var borrowernumber = $(this).data("borrowernumber");
416
                var borrower_data = $("#borrower_data"+borrowernumber).val();
417
                select_user( borrowernumber, JSON.parse(borrower_data) );
418
            });
419
420
            $("body").on("click",".patron_preview", function( e ){
421
                e.preventDefault();
422
                var borrowernumber = $(this).data("borrowernumber");
423
                var page = "/cgi-bin/koha/members/moremember.pl?print=brief&borrowernumber=" + borrowernumber;
424
                $("#patronPreview .modal-body").load( page + " div.container-fluid" );
425
                $('#patronPreview').modal({show:true});
426
            });
427
428
            $("#patronPreview").on('hidden.bs.modal', function (e) {
429
                $("#patronPreview .modal-body").html("<img src=\"[% interface | html %]/[% theme | html %]/img/spinner-small.gif\" alt=\"\" /> Loading");
430
            });
431
432
        });
433
434
        function filter() {
435
            $("#firstletter_filter").val('');
436
            $("#[% table_id %]_search_results").show();
437
438
            let table_dt = patrons_table.DataTable();
439
            [% FOR c IN columns %]
440
                [% SWITCH c %]
441
                [% CASE 'branch' %]
442
                    library_id = $("#branchcode_filter").val() || "";
443
                    patrons_table.find('thead tr:eq(1) th[data-filter="libraries"] select').val(library_id);
444
                    table_dt.column([% loop.count - 1 %]).search(library_id ? '^'+library_id+'$' : '');
445
                [% CASE 'category' %]
446
                    let category_id = $("#categorycode_filter").val() || "";
447
                    patrons_table.find('thead tr:eq(1) th[data-filter="categories"] select').val(category_id);
448
                    table_dt.column([% loop.count - 1 %]).search(category_id ? '^'+category_id+'$' : '');
449
                [% END %]
450
            [% END %]
451
            table_dt.search("");
452
            first_draw = 1; // Only redirect if we are coming from here
453
            table_dt.draw();
454
            return false;
455
        }
456
457
        // User has clicked on a letter
458
        function filterByFirstLetterSurname(letter) {
459
            $("#firstletter_filter").val(letter);
460
            $("#[% table_id %]_search_results").show();
461
            patrons_table.DataTable().draw();
462
        }
463
464
        // modify parent window owner element
465
        [% IF selection_type == 'add' %]
466
            function add_user(borrowernumber, borrowername) {
467
                var p = window.opener;
468
                // In one place (serials/routing.tt), the page is reload on every add
469
                // We have to wait for the page to be there
470
                function wait_for_opener () {
471
                    if ( ! $(opener.document).find('body').size() ) {
472
                        setTimeout(wait_for_opener, 500);
473
                    } else {
474
                        [%# Note that add_user could sent data instead of borrowername too %]
475
                        $("#info").hide();
476
                        $("#error").hide();
477
                        if ( p.add_user(borrowernumber, borrowername) < 0 ) {
478
                            $("#error").html(_("Patron '%s' is already in the list.").format(borrowername));
479
                            $("#error").show();
480
                        } else {
481
                            $("#info").html(_("Patron '%s' added.").format(borrowername));
482
                            $("#info").show();
483
                        }
484
                    }
485
                }
486
                wait_for_opener();
487
            }
488
        [% ELSIF selection_type == 'select' %]
489
            function select_user(borrowernumber, data) {
490
                var p = window.opener;
491
                [%  IF callback %]
492
                    p.[% callback | html %](borrowernumber, data);
493
                [%  ELSE %]
494
                    p.select_user(borrowernumber, data);
495
                [%  END %]
496
                window.close();
497
            }
498
        [% END %]
499
    </script>
500
[% END %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/search.tt (-377 / +15 lines)
Lines 1-5 Link Here
1
[% USE raw %]
1
[% USE raw %]
2
[% USE To %]
3
[% USE Asset %]
2
[% USE Asset %]
4
[% USE Koha %]
3
[% USE Koha %]
5
[% USE Branches %]
4
[% USE Branches %]
Lines 8-405 Link Here
8
[% INCLUDE 'doc-head-open.inc' %]
7
[% INCLUDE 'doc-head-open.inc' %]
9
[% SET libraries = Branches.all %]
8
[% SET libraries = Branches.all %]
10
[% SET categories = Categories.all.unblessed %]
9
[% SET categories = Categories.all.unblessed %]
10
[% PROCESS 'patron-search.inc' %]
11
<title>Patron search &rsaquo; Koha</title>
11
<title>Patron search &rsaquo; Koha</title>
12
[% INCLUDE 'doc-head-close.inc' %]
12
[% INCLUDE 'doc-head-close.inc' %]
13
<style> .modal-body .close { display: none; } </style>
13
<style> .modal-body .close { display: none; } </style>[%# FIXME This is not great, we should make members/memberentrygen.tt use a modal as well and we won't need that here %]
14
</head>
14
</head>
15
15
16
<body id="common_patron_search" class="common">
16
<body id="common_patron_search" class="common">
17
<div id="patron_search" class="yui-t7">
17
<div id="patron_search" class="yui-t7">
18
    <div class="container-fluid">
18
    <div class="container-fluid">
19
19
20
        <form id="searchform">
20
        [% PROCESS patron_search_filters categories => categories, libraries => libraries, columns => columns, search_filter => searchmember %]
21
            <fieldset class="brief">
22
                <h3>Search for patron</h3>
23
                <ol>
24
                    <li>
25
                        <label for="searchmember_filter">Search:</label>
26
                        <input type="text" id="searchmember_filter" value="[% searchmember | html %]" class="focus" />
27
                    </li>
28
29
                    [% FOR column IN columns %]
30
                        [% SWITCH column %]
31
                        [% CASE 'branch' %]
32
                            <li>
33
                                <label for="branchcode_filter">Library:</label>
34
                                <select id="branchcode_filter">
35
                                    [% SET libraries = Branches.all( only_from_group => 1 ) %]
36
                                    [% IF libraries.size != 1 %]
37
                                        <option value="">Any</option>
38
                                    [% END %]
39
                                    [% FOREACH l IN libraries %]
40
                                        <option value="[% l.branchcode | html %]">[% l.branchname | html %]</option>
41
                                    [% END %]
42
                                </select>
43
                            </li>
44
                        [% CASE 'category' %]
45
                            <li>
46
                                <label for="categorycode_filter">Category:</label>
47
                                <select id="categorycode_filter">
48
                                    <option value="">Any</option>
49
                                    [% FOREACH category IN categories %]
50
                                        <option value="[% category.categorycode | html %]">[% category.description | html %]</option>
51
                                    [% END %]
52
                                </select>
53
                            </li>
54
                        [% END %]
55
                    [% END %]
56
                </ol>
57
                <fieldset class="action">
58
                    <input type="submit" value="Search" />
59
                </fieldset>
60
            </fieldset>
61
        </form>
21
        </form>
62
22
63
        [% IF filter == 'suggestions_managers' %]
23
        [% PROCESS patron_search_table table_id => 'memberresultst' columns => columns %]
64
            <div class="hint">Only staff with superlibrarian or suggestions_manage permissions are returned in the search results</div>
65
        [% ELSIF filter == 'orders_managers' %]
66
            <div class="hint">Only staff with superlibrarian or acquisitions permissions (or order_manage permission if granular permissions are enabled) are returned in the search results</div>
67
        [% ELSIF filter == 'funds_owners' OR filter == 'funds_users' %]
68
            <div class="hint">Only staff with superlibrarian or acquisitions permissions (or budget_modify permission if granular permissions are enabled) are returned in the search results</div>
69
        [% END %]
70
71
        <div class="browse">
72
            Browse by last name:
73
            [% FOREACH letter IN alphabet.split(' ') %]
74
                <a href="#" class="filterByLetter">[% letter | html %]</a>
75
            [% END %]
76
        </div>
77
78
        <div id="info" class="dialog message" style="display: none;"></div>
79
        <div id="error" class="dialog alert" style="display: none;"></div>
80
24
81
        <input type="hidden" id="firstletter_filter" value="" />
25
        <div id="closewindow"><a href="#" class="btn btn-default btn-default close">Close</a></div>
82
        <div id="searchresults" style="display:none;">
83
            <table id="memberresultst">
84
                <thead>
85
                    <tr>
86
                        [% FOR column IN columns %]
87
                            [% SWITCH column %]
88
                                [% CASE 'cardnumber' %]<th>Card</th>
89
                                [% CASE 'dateofbirth' %]<th>Date of birth</th>
90
                                [% CASE 'address' %]<th>Address</th>
91
                                [% CASE 'name' %]<th>Name</th>
92
                                [% CASE 'branch' %]<th data-filter="libraries">Library</th>
93
                                [% CASE 'category' %]<th data-filter="categories">Category</th>
94
                                [% CASE 'dateexpiry' %]<th>Expires on</td>
95
                                [% CASE 'borrowernotes' %]<th>Notes</th>
96
                                [% CASE 'action' %]<th>&nbsp;</th>
97
                            [% END %]
98
                        [% END %]
99
                    </tr>
100
                  </thead>
101
                <tbody></tbody>
102
            </table>
103
        </div>
104
26
105
<div id="closewindow"><a href="#" class="btn btn-default btn-default close">Close</a></div>
106
107
<!-- Patron preview modal -->
108
<div class="modal" id="patronPreview" tabindex="-1" role="dialog" aria-labelledby="patronPreviewLabel">
109
    <div class="modal-dialog" role="document">
110
        <div class="modal-content">
111
            <div class="modal-header">
112
                <button type="button" class="closebtn" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
113
                <h4 class="modal-title" id="patronPreviewLabel"></h4>
114
            </div>
115
            <div class="modal-body">
116
                <div id="loading">
117
                    <img src="[% interface | html %]/[% theme | html %]/img/spinner-small.gif" alt="" /> Loading
118
                </div>
119
            </div>
120
            <div class="modal-footer">
121
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
122
            </div>
123
        </div>
124
    </div>
27
    </div>
125
</div>
28
</div>
126
29
127
</div>
128
</div>
129
130
[% MACRO jsinclude BLOCK %]
30
[% MACRO jsinclude BLOCK %]
131
    <script>
31
    [% PROCESS patron_search_js
132
        let categories = [% To.json(categories) | $raw %];
32
        table_id    => 'memberresultst',
133
        let categories_map = categories.reduce((map, c) => {
33
        categories  => categories,
134
            map[c.categorycode] = c;
34
        libraries   => libraries,
135
            return map;
35
        extended_attribute_types => extended_attribute_types,
136
        }, {});
36
        columns     => columns,
137
        let libraries  = [% To.json(libraries) | $raw %];
37
        filter      => filter,
138
        let libraries_map = libraries.reduce((map, l) => {
38
        selection_type => selection_type,
139
            map[l.branchcode] = l;
39
        callback    => callback
140
            return map;
40
    %]
141
        }, {});
142
143
        [% IF Koha.Preference('ExtendedPatronAttributes') %]
144
            let extended_attribute_types = [% To.json(attribute_type_codes || []) | $raw %];
145
        [% END %]
146
    </script>
147
    [% INCLUDE 'datatables.inc' %]
148
    [% INCLUDE 'js-date-format.inc' %]
149
    [% INCLUDE 'js-patron-get-age.inc' %]
150
    [% INCLUDE 'js-patron-format.inc' %]
151
    [% INCLUDE 'js-patron-format-address.inc' %]
152
153
    <script>
154
        var search = 0;
155
        let patrons_table;
156
        $(document).ready(function(){
157
            $("#info").hide();
158
            $("#error").hide();
159
160
            $("#searchresults").hide();
161
162
            let additional_filters = {
163
                surname: function(){
164
                    let start_with = $("#firstletter_filter").val()
165
                    if (!start_with) return "";
166
                    return { "like": start_with + "%" }
167
                },
168
                "-and": function(){
169
                    let filter = $("#searchmember_filter").val();
170
                    if (!filter) return "";
171
                    [% SET search_fields = Koha.Preference('DefaultPatronSearchFields') || 'surname,firstname,othernames,cardnumber,userid' %]
172
                    return [
173
                        [% FOR search_field IN search_fields.split(',') %]
174
                        {"me.[% search_field | html %]":{"like":"%"+filter+"%"}},
175
                        [% END %]
176
                        [% IF Koha.Preference('ExtendedPatronAttributes') %]
177
                        {
178
                            "extended_attributes.value": { "like": "%" + filter + "%" },
179
                            "extended_attributes.code": extended_attribute_types
180
                        }
181
                        [% END %]
182
                    ];
183
                },
184
            };
185
            [% SET default_sort_column = "name" %]
186
            [% SET order_column_index = 0 %]
187
            patrons_table = $("#memberresultst").kohaTable({
188
                "ajax": {
189
                    [% SWITCH filter %]
190
                    [% CASE 'suggestions_managers' %]
191
                        "url": '/api/v1/suggestions/managers'
192
                    [% CASE 'baskets_managers' %]
193
                        "url": '/api/v1/acquisitions/baskets/managers'
194
                    [% CASE 'funds_owners' %]
195
                        "url": '/api/v1/acquisitions/funds/owners'
196
                    [% CASE 'funds_users' %]
197
                        "url": '/api/v1/acquisitions/funds/users'
198
                    [% CASE %]
199
                        "url": '/api/v1/patrons'
200
                    [% END %]
201
                },
202
                embed: ['extended_attributes'],
203
                "iDeferLoading": 0,
204
                "columns": [
205
                    [% FOR column IN columns %]
206
                        [% IF default_sort_column == column %]
207
                            [% order_column_index = loop.count - 1%]
208
                        [% END %]
209
                        [% SWITCH column %]
210
                            [% CASE 'cardnumber' %]
211
                            {
212
                                "data": "cardnumber",
213
                                "searchable": true,
214
                                "orderable": true
215
                            }
216
                            [% CASE 'dateofbirth' %]
217
                            {
218
                                "data": "date_of_birth",
219
                                "searchable": true,
220
                                "orderable": true,
221
                                "render": function( data, type, row, meta ) {
222
                                    return data ? escape_str($date(data) + " (" + _("%s years").format($get_age(data)) + ")") : "";
223
                                }
224
                            }
225
                            [% CASE 'address' %]
226
                            {
227
                                "data": "me.street_number:me.address:me.address2:me.city:me.state:me.postal_code:me.country",
228
                                "searchable": true,
229
                                "orderable": true,
230
                                "render": function( data, type, row, meta ) {
231
                                    return escape_str($format_address(row) + " ") + escape_str(libraries_map[row.library_id].branchname);
232
                                }
233
                            }
234
                            [% CASE 'name' %]
235
                            {
236
                                "data": "me.firstname:me.surname:me.othernames",
237
                                "searchable": true,
238
                                "orderable": true,
239
                                "render": function( data, type, row, meta ) {
240
                                    let patron_id = encodeURIComponent(row.patron_id);
241
                                    return "<a href=\"/cgi-bin/koha/members/moremember.pl?borrowernumber=" + patron_id + "\" class=\"patron_preview\" data-borrowernumber=\"" + patron_id + "\" style=\"white-space:nowrap\">" + $patron_to_html(row, { invert_name: 1 }) + "</a>";
242
                                }
243
                            }
244
                            [% CASE 'branch' %]
245
                            {
246
                                "data": "library_id",
247
                                "searchable": true,
248
                                "orderable": true,
249
                                "render": function( data, type, row, meta ) {
250
                                    return escape_str(libraries_map[data].branchname);
251
                                }
252
                            }
253
                            [% CASE 'category' %]
254
                            {
255
                                "data": "category_id",
256
                                "searchable": true,
257
                                "orderable": true,
258
                                "render": function( data, type, row, meta ) {
259
                                    return escape_str(categories_map[data].description);
260
                                }
261
                            }
262
                            [% CASE 'dateexpiry' %]
263
                            {
264
                                "data": "expiry_date",
265
                                "searchable": true,
266
                                "orderable": true,
267
                                "render": function( data, type, row, meta ) {
268
                                    return data ? escape_str($date(data)) : "";
269
                                }
270
                            }
271
                            [% CASE 'borrowernotes' %]
272
                            {
273
                                "data": "staff_notes",
274
                                "searchable": true,
275
                                "orderable": true,
276
                                [%# We don't escape here, we allow html tag in staff notes %]
277
                            }
278
                            [% CASE 'action' %]
279
                            {
280
                                "data": function( row, type, val, meta ) {
281
282
                                    let patron_id = encodeURIComponent(row.patron_id);
283
                                    [% IF selection_type == 'select' %]
284
                                        return '<a href="#" class="btn btn-default btn-xs select_user" data-borrowernumber="' + patron_id + '">Select</a><input type="hidden" id="borrower_data' + patron_id + '" name="borrower_data'+ patron_id + '" value=\''+JSON.stringify(row)+'\' />';
285
                                    [% ELSE %]
286
                                        return '<a href="#" class="btn btn-default btn-xs add_user" data-borrowernumber="' + patron_id + '" data-firstname="' + encodeURIComponent(row.firstname) + '" data-surname="' + encodeURIComponent(row.surname) + '">Add</a><input type="hidden" id="borrower_data' + patron_id + '" name="borrower_data'+ patron_id + '" />';
287
                                    [% END %]
288
                                },
289
                                "searchable": false,
290
                                "orderable": false
291
                            }
292
                        [% END %]
293
                        [% UNLESS loop.last %],[% END %]
294
                    [% END %]
295
                ],
296
                "order": [[ [% order_column_index | html %], "asc" ]],
297
                'bAutoWidth': false,
298
                'sPaginationType': 'full_numbers',
299
                "iDisplayLength": [% Koha.Preference('PatronsPerPage') | html %],
300
            }, null, 1, additional_filters);
301
302
            $("#searchform").on('submit', filter);
303
            $(".filterByLetter").on("click",function(e){
304
                e.preventDefault();
305
                filterByFirstLetterSurname($(this).text());
306
            });
307
            $("body").on("click",".add_user",function(e){
308
                e.preventDefault();
309
                var borrowernumber = $(this).data("borrowernumber");
310
                var firstname = $(this).data("firstname");
311
                var surname = $(this).data("surname");
312
                add_user( borrowernumber, firstname + " " + surname );
313
            });
314
315
            $("body").on("click",".select_user",function(e){
316
                e.preventDefault();
317
                var borrowernumber = $(this).data("borrowernumber");
318
                var borrower_data = $("#borrower_data"+borrowernumber).val();
319
                select_user( borrowernumber, JSON.parse(borrower_data) );
320
            });
321
322
            $("body").on("click",".patron_preview", function( e ){
323
                e.preventDefault();
324
                var borrowernumber = $(this).data("borrowernumber");
325
                var page = "/cgi-bin/koha/members/moremember.pl?print=brief&borrowernumber=" + borrowernumber;
326
                $("#patronPreview .modal-body").load( page + " div.container-fluid" );
327
                $('#patronPreview').modal({show:true});
328
            });
329
330
            $("#patronPreview").on('hidden.bs.modal', function (e) {
331
                $("#patronPreview .modal-body").html("<img src=\"[% interface | html %]/[% theme | html %]/img/spinner-small.gif\" alt=\"\" /> Loading");
332
            });
333
334
        });
335
336
        function filter() {
337
            search = 1;
338
            $("#firstletter_filter").val('');
339
            $("#searchresults").show();
340
341
            let table_dt = patrons_table.DataTable();
342
            [% FOR c IN columns %]
343
                [% SWITCH c %]
344
                [% CASE 'branch' %]
345
                    let library_id = $("#branchcode_filter").val();
346
                    patrons_table.find('thead tr:eq(1) th[data-filter="libraries"] select').val(library_id);
347
                    table_dt.column([% loop.count - 1 %]).search(library_id ? '^'+library_id+'$' : '');
348
                [% CASE 'category' %]
349
                    let category_id = $("#categorycode_filter").val();
350
                    patrons_table.find('thead tr:eq(1) th[data-filter="categories"] select').val(category_id);
351
                    table_dt.column([% loop.count - 1 %]).search(category_id ? '^'+category_id+'$' : '');
352
                [% END %]
353
            [% END %]
354
            table_dt.search("");
355
            table_dt.draw();
356
            return false;
357
        }
358
359
        // User has clicked on a letter
360
        function filterByFirstLetterSurname(letter) {
361
            $("#firstletter_filter").val(letter);
362
            search = 1;
363
            $("#searchresults").show();
364
            patrons_table.fnDraw();
365
        }
366
367
        // modify parent window owner element
368
        [% IF selection_type == 'add' %]
369
            function add_user(borrowernumber, borrowername) {
370
                var p = window.opener;
371
                // In one place (serials/routing.tt), the page is reload on every add
372
                // We have to wait for the page to be there
373
                function wait_for_opener () {
374
                    if ( ! $(opener.document).find('body').size() ) {
375
                        setTimeout(wait_for_opener, 500);
376
                    } else {
377
                        [%# Note that add_user could sent data instead of borrowername too %]
378
                        $("#info").hide();
379
                        $("#error").hide();
380
                        if ( p.add_user(borrowernumber, borrowername) < 0 ) {
381
                            $("#error").html(_("Patron '%s' is already in the list.").format(borrowername));
382
                            $("#error").show();
383
                        } else {
384
                            $("#info").html(_("Patron '%s' added.").format(borrowername));
385
                            $("#info").show();
386
                        }
387
                    }
388
                }
389
                wait_for_opener();
390
            }
391
        [% ELSIF selection_type == 'select' %]
392
            function select_user(borrowernumber, data) {
393
                var p = window.opener;
394
                [%  IF callback %]
395
                    p.[% callback | html %](borrowernumber, data);
396
                [%  ELSE %]
397
                    p.select_user(borrowernumber, data);
398
                [%  END %]
399
                window.close();
400
            }
401
        [% END %]
402
    </script>
403
[% END %]
41
[% END %]
404
42
405
[% SET popup_window = 1 %]
43
[% SET popup_window = 1 %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt (-95 / +30 lines)
Lines 14-19 Link Here
14
[% PROCESS 'i18n.inc' %]
14
[% PROCESS 'i18n.inc' %]
15
[% SET footerjs = 1 %]
15
[% SET footerjs = 1 %]
16
[% INCLUDE 'doc-head-open.inc' %]
16
[% INCLUDE 'doc-head-open.inc' %]
17
[% SET libraries = Branches.all %]
18
[% SET categories = Categories.all.unblessed %]
19
[% SET columns = ['name', 'cardnumber', 'dateofbirth', 'category', 'branch', 'address', 'phone'] %]
20
[% PROCESS "patron-search.inc" %]
17
[% UNLESS ( multi_hold ) %]
21
[% UNLESS ( multi_hold ) %]
18
    <title>Place a hold on [% INCLUDE 'biblio-title-head.inc' %] &rsaquo; Holds &rsaquo; Circulation &rsaquo; Koha</title>
22
    <title>Place a hold on [% INCLUDE 'biblio-title-head.inc' %] &rsaquo; Holds &rsaquo; Circulation &rsaquo; Koha</title>
19
[% ELSE %]
23
[% ELSE %]
Lines 163-192 Link Here
163
                            [% END %]
167
                            [% END %]
164
                        </ul>
168
                        </ul>
165
                        <div id="holds_patronsearch_pane">
169
                        <div id="holds_patronsearch_pane">
166
                            <form id="holds_patronsearch" method="get">
170
                            [% PROCESS patron_search_filters_simple %]
167
                                <div class="hint">Enter patron card number or partial name:</div>
168
                                <input type="text" size="40" id="patron" class="focus" autocomplete="off" />
169
                                <input type="submit" value="Search" />
170
                                [% FOREACH biblionumber IN biblionumbers %]
171
                                <input type="hidden" name="biblionumber" value="[% biblionumber | html %]"/>
172
                                [% END %]
173
                            </form> <!-- /#holds_patronsearch -->
174
175
                            <table id="table_borrowers" class="selections-table" style="display: none;">
176
                              <thead>
177
                                <tr>
178
                                  <th>Name</th>
179
                                  <th>Address</th>
180
                                  <th>Card number</th>
181
                                  <th>Date of birth</th>
182
                                  <th>Category</th>
183
                                  <th>Library</th>
184
                                  <th>Primary phone</th>
185
                                </tr>
186
                              </thead>
187
                              <tbody></tbody>
188
                            </table>
189
171
172
                            [% PROCESS patron_search_table table_id => 'table_borrowers', open_on_row_click => 1 %]
190
                        </div>
173
                        </div>
191
                        [% IF clubcount %]
174
                        [% IF clubcount %]
192
                            <div id="holds_clubsearch_pane">
175
                            <div id="holds_clubsearch_pane">
Lines 1189-1195 Link Here
1189
        }
1172
        }
1190
1173
1191
        var MSG_CANCEL_SELECTED = _("Cancel selected (%s)");
1174
        var MSG_CANCEL_SELECTED = _("Cancel selected (%s)");
1192
        columns_settings_borrowers_table = [% TablesSettings.GetColumns( 'circ', 'circulation', 'table_borrowers', 'json' ) | $raw %];
1193
        $.fn.select2.defaults.set("width", "100%" );
1175
        $.fn.select2.defaults.set("width", "100%" );
1194
        $.fn.select2.defaults.set("dropdownAutoWidth", true );
1176
        $.fn.select2.defaults.set("dropdownAutoWidth", true );
1195
1177
Lines 1571-1649 Link Here
1571
                }
1553
                }
1572
                return false;
1554
                return false;
1573
            });
1555
            });
1556
        });
1557
    </script>
1574
1558
1575
            [% FOREACH biblionumber IN biblionumbers %]
1559
    <script>
1576
                [% SET url_biblio_params = url_biblio_params _ "&amp;biblionumber=" _ biblionumber | uri %]
1560
        table_settings = [% TablesSettings.GetColumns( 'circ', 'circulation', 'table_borrowers', 'json' ) | $raw %];
1577
            [% END %]
1561
    </script>
1578
            [% IF multi_hold %]
1579
                [% SET url_biblio_params = url_biblio_params _ "&amp;multi_hold=1" %]
1580
            [% END %]
1581
            search = 0;
1582
            dtMemberResults = KohaTable("table_borrowers", {
1583
                'bServerSide': true,
1584
                'sAjaxSource': "/cgi-bin/koha/svc/members/search",
1585
                'fnServerData': function(sSource, aoData, fnCallback) {
1586
                    if ( ! search ) {
1587
                        return;
1588
                    }
1589
                    aoData.push({
1590
                        'name': 'searchmember',
1591
                        'value': $("#patron").val()
1592
                    },{
1593
                        'name': 'template_path',
1594
                        'value': 'reserve/tables/members_results.tt',
1595
                    });
1596
                    $.ajax({
1597
                        'dataType': 'json',
1598
                        'type': 'POST',
1599
                        'url': sSource,
1600
                        'data': aoData,
1601
                        'success': function(json){
1602
                            // redirect if there is only 1 result.
1603
                            if ( json.iTotalDisplayRecords == 1 ) {
1604
                                var borrowernumber = json.aaData[0].borrowernumber;
1605
                                document.location.href = '/cgi-bin/koha/reserve/request.pl?borrowernumber=' + borrowernumber + "[% url_biblio_params | $raw %]"
1606
                                return false;
1607
                            }
1608
                            fnCallback(json);
1609
                        }
1610
                    });
1611
                },
1612
                'fnDrawCallback': function (oSettings) {
1613
                    var data = this.fnGetData();
1614
                    $.each($(this).find("tbody tr"), function(index, tr) {
1615
                        let url = '/cgi-bin/koha/reserve/request.pl?borrowernumber=' + data[index].borrowernumber + "[% url_biblio_params | $raw %]"
1616
                        $(tr).off('click').on('click', function() {
1617
                            document.location.href = url;
1618
                        }).addClass('clickable');
1619
                        $(tr).find("a.patron_preview").attr('href', url);
1620
                    });
1621
                },
1622
                'aoColumns':[
1623
                    { 'mDataProp': 'dt_name' },
1624
                    { 'mDataProp': 'dt_address' },
1625
                    { 'mDataProp': 'dt_cardnumber' },
1626
                    { 'mDataProp': 'dt_dateofbirth' },
1627
                    { 'mDataProp': 'dt_category' },
1628
                    { 'mDataProp': 'dt_branch' },
1629
                    { 'mDataProp': 'dt_phone' },
1630
                ],
1631
                'bFilter': false,
1632
                'bAutoWidth': false,
1633
                'sPaginationType': 'full_numbers',
1634
                "bProcessing": true
1635
            }, columns_settings_borrowers_table );
1636
            $("#table_borrowers_wrapper").hide();
1637
1638
            function filter() {
1639
                search = 1;
1640
                $("#table_borrowers").show();
1641
                $("#table_borrowers_wrapper").show();
1642
                dtMemberResults.fnDraw();
1643
                return false;
1644
            }
1645
            $("#holds_patronsearch").on("submit", filter);
1646
1562
1563
    [% SET url_biblio_params = "biblionumber=" _ biblionumbers.join("&amp;biblionumber=") %]
1564
    [% IF multi_hold %]
1565
        [% SET url_biblio_params = url_biblio_params _ "&amp;multi_hold=1" %]
1566
    [% END %]
1567
1568
    [% PROCESS patron_search_js
1569
        table_id    => 'table_borrowers',
1570
        categories  => categories,
1571
        libraries   => libraries,
1572
        extended_attribute_types => attribute_type_codes,
1573
        columns     => columns,
1574
        open_on_row_click => 1,
1575
        on_click_url      => '/cgi-bin/koha/reserve/request.pl?' _ url_biblio_params,
1576
        redirect_if_one_result => 1,
1577
        redirect_url           => '/cgi-bin/koha/reserve/request.pl?' _ url_biblio_params
1578
    %]
1579
    <script>
1580
        $(document).ready(function() {
1581
            $("#holds_patronsearch").on("submit", filter);
1647
        });
1582
        });
1648
        $('.printholdslip').click(function(){
1583
        $('.printholdslip').click(function(){
1649
                var reserve_id = $(this).attr('data-reserve_id');
1584
                var reserve_id = $(this).attr('data-reserve_id');
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/tables/members_results.tt (-32 lines)
Lines 1-32 Link Here
1
[% USE raw %]
2
[% USE I18N %]
3
[% USE To %]
4
[% USE Price %]
5
[% PROCESS 'member-display-address-style.inc' %]
6
{
7
    "sEcho": [% sEcho | html %],
8
    "iTotalRecords": [% iTotalRecords | html %],
9
    "iTotalDisplayRecords": [% iTotalDisplayRecords | html %],
10
    "aaData": [
11
        [% FOREACH data IN aaData %]
12
            {
13
                "dt_name":
14
                    "<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 />",
15
                "dt_address":
16
                    "[%~ INCLUDE 'display-address-style' patron=data no_line_break=1 | $To ~%]",
17
                "dt_cardnumber":
18
                    "[% data.cardnumber | html | $To %]",
19
                "dt_dateofbirth":
20
                    "[% INCLUDE 'patron-age.inc' patron = data %]",
21
                "dt_category":
22
                    "[% data.category_description | html | $To %] <span class=\"patron_category_type\">([% data.category_type | html | $To %])</span>",
23
                "dt_branch":
24
                    "[% data.branchname | html | $To %]",
25
                "dt_phone":
26
                    "[% data.phone| html | $To %]",
27
                "borrowernumber":
28
                    "[% data.borrowernumber | html %]"
29
            }[% UNLESS loop.last %],[% END %]
30
        [% END %]
31
    ]
32
}
(-)a/members/search.pl (-1 lines)
Lines 46-52 $template->param( Link Here
46
    columns        => \@columns,
46
    columns        => \@columns,
47
    filter         => $filter,
47
    filter         => $filter,
48
    selection_type => $selection_type,
48
    selection_type => $selection_type,
49
    alphabet       => ( C4::Context->preference('alphabet') || join ' ', 'A' .. 'Z' ),
50
    attribute_type_codes => ( C4::Context->preference('ExtendedPatronAttributes')
49
    attribute_type_codes => ( C4::Context->preference('ExtendedPatronAttributes')
51
        ? [ Koha::Patron::Attribute::Types->search( { staff_searchable => 1 } )->get_column('code') ]
50
        ? [ Koha::Patron::Attribute::Types->search( { staff_searchable => 1 } )->get_column('code') ]
52
        : [] ),
51
        : [] ),
(-)a/reserve/request.pl (-2 / +9 lines)
Lines 39-45 use C4::Koha qw( getitemtypeimagelocation ); Link Here
39
use C4::Serials qw( CountSubscriptionFromBiblionumber );
39
use C4::Serials qw( CountSubscriptionFromBiblionumber );
40
use C4::Circulation qw( GetTransfers _GetCircControlBranch GetBranchItemRule );
40
use C4::Circulation qw( GetTransfers _GetCircControlBranch GetBranchItemRule );
41
use Koha::DateUtils qw( dt_from_string output_pref );
41
use Koha::DateUtils qw( dt_from_string output_pref );
42
use C4::Utils::DataTables::Members;
43
use C4::Search qw( enabled_staff_search_views );
42
use C4::Search qw( enabled_staff_search_views );
44
43
45
use Koha::Biblios;
44
use Koha::Biblios;
Lines 51-56 use Koha::Items; Link Here
51
use Koha::ItemTypes;
50
use Koha::ItemTypes;
52
use Koha::Libraries;
51
use Koha::Libraries;
53
use Koha::Patrons;
52
use Koha::Patrons;
53
use Koha::Patron::Attribute::Types;
54
use Koha::Clubs;
54
use Koha::Clubs;
55
use Koha::BackgroundJob::BatchCancelHold;
55
use Koha::BackgroundJob::BatchCancelHold;
56
56
Lines 690-695 if ( ( $findborrower && $borrowernumber_hold || $findclub && $club_hold ) Link Here
690
}
690
}
691
$template->param( biblionumbers => \@biblionumbers );
691
$template->param( biblionumbers => \@biblionumbers );
692
692
693
$template->param(
694
    attribute_type_codes => ( C4::Context->preference('ExtendedPatronAttributes')
695
        ? [ Koha::Patron::Attribute::Types->search( { staff_searchable => 1 } )->get_column('code') ]
696
        : []
697
    ),
698
);
699
700
693
# pass the userenv branch if no pickup location selected
701
# pass the userenv branch if no pickup location selected
694
$template->param( pickup => $pickup || C4::Context->userenv->{branch} );
702
$template->param( pickup => $pickup || C4::Context->userenv->{branch} );
695
703
696
- 

Return to bug 30093