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[l.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].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].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].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 (+493 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="dispay: 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 = $("#searchmember_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 %]":{"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
            patrons_table = $("#[% table_id %]").kohaTable({
202
                "ajax": {
203
                    [% SWITCH filter %]
204
                    [% CASE 'suggestions_managers' %]
205
                        "url": '/api/v1/suggestions/managers',
206
                    [% CASE 'baskets_managers' %]
207
                        "url": '/api/v1/acquisitions/baskets/managers',
208
                    [% CASE 'funds_owners' %]
209
                        "url": '/api/v1/acquisitions/funds/owners',
210
                    [% CASE 'funds_users' %]
211
                        "url": '/api/v1/acquisitions/funds/users',
212
                    [% CASE %]
213
                        "url": '/api/v1/patrons',
214
                    [% END %]
215
                    "dataSrc": function ( json ) {
216
                        [% IF redirect_if_one_result %]
217
                            // redirect if there is only 1 result.
218
                            if ( first_draw && json.recordsFiltered == 1 ) {
219
                                document.location.href = '[% redirect_url %]&borrowernumber=' + json.data[0].patron_id;
220
                                return false;
221
                            }
222
                            first_draw = 0;
223
                        [% END %]
224
                        return json.data;
225
                    }
226
                },
227
                embed: ['extended_attributes'],
228
                "drawCallback": function( settings ) {
229
                    var api = this.api();
230
                    var data = api.data();
231
                    if ( data.length == 0 ) return;
232
233
                    [% IF open_on_row_click %]
234
                    $.each($(this).find("tbody tr"), function(index, tr) {
235
                        let url = "[% on_click_url %]&borrowernumber=" + data[index].patron_id;
236
                        $(tr).off('click').on('click', function() {
237
                            document.location.href = url;
238
                        }).addClass('clickable');
239
                        $(tr).find("a.patron_name").attr('href', url);
240
                    });
241
                    [% ELSE %]
242
                    $.each($(this).find("tbody tr"), function(index, tr) {
243
                        $(tr).find("a.patron_name").addClass("patron_preview");
244
                    });
245
                    [% END %]
246
                },
247
                "order": [[ 1, "asc" ]],
248
                "iDeferLoading": 0,
249
                "columns": [
250
                    [% FOR column IN columns %]
251
                        [% SWITCH column %]
252
                            [% CASE 'cardnumber' %]
253
                            {
254
                                "data": "cardnumber",
255
                                "searchable": true,
256
                                "orderable": true
257
                            }
258
                            [% CASE 'dateofbirth' %]
259
                            {
260
                                "data": "date_of_birth",
261
                                "searchable": true,
262
                                "orderable": true,
263
                                "render": function( data, type, row, meta ) {
264
                                    return data ? escape_str($date(data) + " (" + _("%s years").format($get_age(data)) + ")") : "";
265
                                }
266
                            }
267
                            [% CASE 'address' %]
268
                            {
269
                                "data": "me.street_number:me.address:me.address2:me.city:me.state:me.postal_code:me.country",
270
                                "searchable": true,
271
                                "orderable": true,
272
                                 "render": function( data, type, row, meta ) {
273
                                    let r = '<div class="address"><ul>';
274
                                    r += $format_address(row, { no_line_break: 1 });
275
                                    r += '</div></ul>';
276
                                    return r;
277
                                }
278
                            }
279
                            [% CASE 'address-library' %]
280
                            {
281
                                "data": "me.street_number:me.address:me.address2:me.city:me.state:me.postal_code:me.country",
282
                                "searchable": true,
283
                                "orderable": true,
284
                                "render": function( data, type, row, meta ) {
285
                                    let r = '<div class="address"><ul>';
286
                                    r += $format_address(row, { no_line_break: 1 });
287
                                    r += '</div></ul>';
288
                                    r += " " + escape_str(libraries_map[row.library_id].branchname);
289
                                    return r;
290
                                }
291
                            }
292
                            [% CASE 'name-address' %]
293
                            {
294
                                "data": "me.firstname:me.surname:me.othernames:me.street_number:me.address:me.address2:me.city:me.state:me.postal_code:me.country",
295
                                "searchable": true,
296
                                "orderable": true,
297
                                "render": function( data, type, row, meta ) {
298
                                    let patron_id = encodeURIComponent(row.patron_id);
299
                                    let r = '';
300
                                    [% IF ! open_on_row_click %]
301
                                    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>";
302
                                    [% ELSE %]
303
                                    r += $patron_to_html(row, { invert_name: 1 });
304
                                    [% END %]
305
                                    r += '<br/>';
306
                                    r += '<div class="address"><ul>';
307
                                    r += $format_address(row, { no_line_break: 1 });
308
309
                                    if ( row.email ) {
310
                                        r += "<li>" + _("Email: ") + "<a href='mailto:" + encodeURIComponent(row.email) + "'>" + escape_str(row.email) + "</a></li>";
311
                                    }
312
                                    r += '</ul></div>'
313
314
                                    return r;
315
                                }
316
                            }
317
                            [% CASE 'name' %]
318
                            {
319
                                "data": "me.firstname:me.surname:me.othernames",
320
                                "searchable": true,
321
                                "orderable": true,
322
                                "render": function( data, type, row, meta ) {
323
                                    let patron_id = encodeURIComponent(row.patron_id);
324
                                    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>";
325
                                }
326
                            }
327
                            [% CASE 'branch' %]
328
                            {
329
                                "data": "library_id",
330
                                "searchable": true,
331
                                "orderable": true,
332
                                "render": function( data, type, row, meta ) {
333
                                    return escape_str(libraries_map[data].branchname);
334
                                }
335
                            }
336
                            [% CASE 'category' %]
337
                            {
338
                                "data": "category_id",
339
                                "searchable": true,
340
                                "orderable": true,
341
                                "render": function( data, type, row, meta ) {
342
                                    return escape_str(categories_map[data].description);
343
                                }
344
                            }
345
                            [% CASE 'dateexpiry' %]
346
                            {
347
                                "data": "expiry_date",
348
                                "searchable": true,
349
                                "orderable": true,
350
                                "render": function( data, type, row, meta ) {
351
                                    return data ? escape_str($date(data)) : "";
352
                                }
353
                            }
354
                            [% CASE 'borrowernotes' %]
355
                            {
356
                                "data": "staff_notes",
357
                                "searchable": true,
358
                                "orderable": true,
359
                                [%# We don't escape here, we allow html tag in staff notes %]
360
                            }
361
                            [% CASE 'phone' %]
362
                            {
363
                                "data": "phone",
364
                                "searchable": true,
365
                                "orderable": true,
366
                                "render": function( data, type, row, meta ) {
367
                                    return escape_str(data);
368
                                }
369
                            }
370
                            [% CASE 'action' %]
371
                            {
372
                                "data": function( row, type, val, meta ) {
373
374
                                    let patron_id = encodeURIComponent(row.patron_id);
375
                                    [% IF selection_type == 'select' %]
376
                                        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)+'\' />';
377
                                    [% ELSE %]
378
                                        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 + '" />';
379
                                    [% END %]
380
                                },
381
                                "searchable": false,
382
                                "orderable": false
383
                            }
384
                        [% END %]
385
                        [% UNLESS loop.last %],[% END %]
386
                    [% END %]
387
                ],
388
                'bAutoWidth': false,
389
                'sPaginationType': 'full_numbers',
390
                "iDisplayLength": [% Koha.Preference('PatronsPerPage') | html %],
391
            }, typeof table_settings !== 'undefined' ? table_settings : null, 1, additional_filters);
392
393
            $("#patron_search_form").on('submit', filter);
394
            $(".filterByLetter").on("click",function(e){
395
                e.preventDefault();
396
                filterByFirstLetterSurname($(this).text());
397
            });
398
            $("body").on("click",".add_user",function(e){
399
                e.preventDefault();
400
                var borrowernumber = $(this).data("borrowernumber");
401
                var firstname = $(this).data("firstname");
402
                var surname = $(this).data("surname");
403
                add_user( borrowernumber, firstname + " " + surname );
404
            });
405
406
            $("body").on("click",".select_user",function(e){
407
                e.preventDefault();
408
                var borrowernumber = $(this).data("borrowernumber");
409
                var borrower_data = $("#borrower_data"+borrowernumber).val();
410
                select_user( borrowernumber, JSON.parse(borrower_data) );
411
            });
412
413
            $("body").on("click",".patron_preview", function( e ){
414
                e.preventDefault();
415
                var borrowernumber = $(this).data("borrowernumber");
416
                var page = "/cgi-bin/koha/members/moremember.pl?print=brief&borrowernumber=" + borrowernumber;
417
                $("#patronPreview .modal-body").load( page + " div.container-fluid" );
418
                $('#patronPreview').modal({show:true});
419
            });
420
421
            $("#patronPreview").on('hidden.bs.modal', function (e) {
422
                $("#patronPreview .modal-body").html("<img src=\"[% interface | html %]/[% theme | html %]/img/spinner-small.gif\" alt=\"\" /> Loading");
423
            });
424
425
        });
426
427
        function filter() {
428
            $("#firstletter_filter").val('');
429
            $("#[% table_id %]_search_results").show();
430
431
            let table_dt = patrons_table.DataTable();
432
            [% FOR c IN columns %]
433
                [% SWITCH c %]
434
                [% CASE 'branch' %]
435
                    library_id = $("#branchcode_filter").val() || "";
436
                    patrons_table.find('thead tr:eq(1) th[data-filter="libraries"] select').val(library_id);
437
                    table_dt.column([% loop.count - 1 %]).search(library_id);
438
                [% CASE 'category' %]
439
                    let category_id = $("#categorycode_filter").val() || "";
440
                    patrons_table.find('thead tr:eq(1) th[data-filter="categories"] select').val(category_id);
441
                    table_dt.column([% loop.count - 1 %]).search(category_id);
442
                [% END %]
443
            [% END %]
444
            table_dt.search("");
445
            first_draw = 1; // Only redirect if we are coming from here
446
            table_dt.draw();
447
            return false;
448
        }
449
450
        // User has clicked on a letter
451
        function filterByFirstLetterSurname(letter) {
452
            $("#firstletter_filter").val(letter);
453
            $("#[% table_id %]_search_results").show();
454
            patrons_table.DataTable().draw();
455
        }
456
457
        // modify parent window owner element
458
        [% IF selection_type == 'add' %]
459
            function add_user(borrowernumber, borrowername) {
460
                var p = window.opener;
461
                // In one place (serials/routing.tt), the page is reload on every add
462
                // We have to wait for the page to be there
463
                function wait_for_opener () {
464
                    if ( ! $(opener.document).find('body').size() ) {
465
                        setTimeout(wait_for_opener, 500);
466
                    } else {
467
                        [%# Note that add_user could sent data instead of borrowername too %]
468
                        $("#info").hide();
469
                        $("#error").hide();
470
                        if ( p.add_user(borrowernumber, borrowername) < 0 ) {
471
                            $("#error").html(_("Patron '%s' is already in the list.").format(borrowername));
472
                            $("#error").show();
473
                        } else {
474
                            $("#info").html(_("Patron '%s' added.").format(borrowername));
475
                            $("#info").show();
476
                        }
477
                    }
478
                }
479
                wait_for_opener();
480
            }
481
        [% ELSIF selection_type == 'select' %]
482
            function select_user(borrowernumber, data) {
483
                var p = window.opener;
484
                [%  IF callback %]
485
                    p.[% callback | html %](borrowernumber, data);
486
                [%  ELSE %]
487
                    p.select_user(borrowernumber, data);
488
                [%  END %]
489
                window.close();
490
            }
491
        [% END %]
492
    </script>
493
[% END %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/search.tt (-372 / +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-400 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="dispay: 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 %]":{"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
            patrons_table = $("#memberresultst").kohaTable({
186
                "ajax": {
187
                    [% SWITCH filter %]
188
                    [% CASE 'suggestions_managers' %]
189
                        "url": '/api/v1/suggestions/managers'
190
                    [% CASE 'baskets_managers' %]
191
                        "url": '/api/v1/acquisitions/baskets/managers'
192
                    [% CASE 'funds_owners' %]
193
                        "url": '/api/v1/acquisitions/funds/owners'
194
                    [% CASE 'funds_users' %]
195
                        "url": '/api/v1/acquisitions/funds/users'
196
                    [% CASE %]
197
                        "url": '/api/v1/patrons'
198
                    [% END %]
199
                },
200
                embed: ['extended_attributes'],
201
                "order": [[ 1, "asc" ]],
202
                "iDeferLoading": 0,
203
                "columns": [
204
                    [% FOR column IN columns %]
205
                        [% SWITCH column %]
206
                            [% CASE 'cardnumber' %]
207
                            {
208
                                "data": "cardnumber",
209
                                "searchable": true,
210
                                "orderable": true
211
                            }
212
                            [% CASE 'dateofbirth' %]
213
                            {
214
                                "data": "date_of_birth",
215
                                "searchable": true,
216
                                "orderable": true,
217
                                "render": function( data, type, row, meta ) {
218
                                    return data ? escape_str($date(data) + " (" + _("%s years").format($get_age(data)) + ")") : "";
219
                                }
220
                            }
221
                            [% CASE 'address' %]
222
                            {
223
                                "data": "me.street_number:me.address:me.address2:me.city:me.state:me.postal_code:me.country",
224
                                "searchable": true,
225
                                "orderable": true,
226
                                "render": function( data, type, row, meta ) {
227
                                    return escape_str($format_address(row) + " ") + escape_str(libraries_map[row.library_id].branchname);
228
                                }
229
                            }
230
                            [% CASE 'name' %]
231
                            {
232
                                "data": "me.firstname:me.surname:othernames",
233
                                "searchable": true,
234
                                "orderable": true,
235
                                "render": function( data, type, row, meta ) {
236
                                    let patron_id = encodeURIComponent(row.patron_id);
237
                                    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>";
238
                                }
239
                            }
240
                            [% CASE 'branch' %]
241
                            {
242
                                "data": "library_id",
243
                                "searchable": true,
244
                                "orderable": true,
245
                                "render": function( data, type, row, meta ) {
246
                                    return escape_str(libraries_map[data].branchname);
247
                                }
248
                            }
249
                            [% CASE 'category' %]
250
                            {
251
                                "data": "category_id",
252
                                "searchable": true,
253
                                "orderable": true,
254
                                "render": function( data, type, row, meta ) {
255
                                    return escape_str(categories_map[data].description);
256
                                }
257
                            }
258
                            [% CASE 'dateexpiry' %]
259
                            {
260
                                "data": "expiry_date",
261
                                "searchable": true,
262
                                "orderable": true,
263
                                "render": function( data, type, row, meta ) {
264
                                    return data ? escape_str($date(data)) : "";
265
                                }
266
                            }
267
                            [% CASE 'borrowernotes' %]
268
                            {
269
                                "data": "staff_notes",
270
                                "searchable": true,
271
                                "orderable": true,
272
                                [%# We don't escape here, we allow html tag in staff notes %]
273
                            }
274
                            [% CASE 'action' %]
275
                            {
276
                                "data": function( row, type, val, meta ) {
277
278
                                    let patron_id = encodeURIComponent(row.patron_id);
279
                                    [% IF selection_type == 'select' %]
280
                                        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)+'\' />';
281
                                    [% ELSE %]
282
                                        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 + '" />';
283
                                    [% END %]
284
                                },
285
                                "searchable": false,
286
                                "orderable": false
287
                            }
288
                        [% END %]
289
                        [% UNLESS loop.last %],[% END %]
290
                    [% END %]
291
                ],
292
                'bAutoWidth': false,
293
                'sPaginationType': 'full_numbers',
294
                "iDisplayLength": [% Koha.Preference('PatronsPerPage') | html %],
295
            }, null, 1, additional_filters);
296
297
            $("#searchform").on('submit', filter);
298
            $(".filterByLetter").on("click",function(e){
299
                e.preventDefault();
300
                filterByFirstLetterSurname($(this).text());
301
            });
302
            $("body").on("click",".add_user",function(e){
303
                e.preventDefault();
304
                var borrowernumber = $(this).data("borrowernumber");
305
                var firstname = $(this).data("firstname");
306
                var surname = $(this).data("surname");
307
                add_user( borrowernumber, firstname + " " + surname );
308
            });
309
310
            $("body").on("click",".select_user",function(e){
311
                e.preventDefault();
312
                var borrowernumber = $(this).data("borrowernumber");
313
                var borrower_data = $("#borrower_data"+borrowernumber).val();
314
                select_user( borrowernumber, JSON.parse(borrower_data) );
315
            });
316
317
            $("body").on("click",".patron_preview", function( e ){
318
                e.preventDefault();
319
                var borrowernumber = $(this).data("borrowernumber");
320
                var page = "/cgi-bin/koha/members/moremember.pl?print=brief&borrowernumber=" + borrowernumber;
321
                $("#patronPreview .modal-body").load( page + " div.container-fluid" );
322
                $('#patronPreview').modal({show:true});
323
            });
324
325
            $("#patronPreview").on('hidden.bs.modal', function (e) {
326
                $("#patronPreview .modal-body").html("<img src=\"[% interface | html %]/[% theme | html %]/img/spinner-small.gif\" alt=\"\" /> Loading");
327
            });
328
329
        });
330
331
        function filter() {
332
            search = 1;
333
            $("#firstletter_filter").val('');
334
            $("#searchresults").show();
335
336
            let table_dt = patrons_table.DataTable();
337
            [% FOR c IN columns %]
338
                [% SWITCH c %]
339
                [% CASE 'branch' %]
340
                    let library_id = $("#branchcode_filter").val();
341
                    patrons_table.find('thead tr:eq(1) th[data-filter="libraries"] select').val(library_id);
342
                    table_dt.column([% loop.count - 1 %]).search(library_id);
343
                [% CASE 'category' %]
344
                    let category_id = $("#categorycode_filter").val();
345
                    patrons_table.find('thead tr:eq(1) th[data-filter="categories"] select').val(category_id);
346
                    table_dt.column([% loop.count - 1 %]).search(category_id);
347
                [% END %]
348
            [% END %]
349
            table_dt.search("");
350
            table_dt.draw();
351
            return false;
352
        }
353
354
        // User has clicked on a letter
355
        function filterByFirstLetterSurname(letter) {
356
            $("#firstletter_filter").val(letter);
357
            search = 1;
358
            $("#searchresults").show();
359
            patrons_table.fnDraw();
360
        }
361
362
        // modify parent window owner element
363
        [% IF selection_type == 'add' %]
364
            function add_user(borrowernumber, borrowername) {
365
                var p = window.opener;
366
                // In one place (serials/routing.tt), the page is reload on every add
367
                // We have to wait for the page to be there
368
                function wait_for_opener () {
369
                    if ( ! $(opener.document).find('body').size() ) {
370
                        setTimeout(wait_for_opener, 500);
371
                    } else {
372
                        [%# Note that add_user could sent data instead of borrowername too %]
373
                        $("#info").hide();
374
                        $("#error").hide();
375
                        if ( p.add_user(borrowernumber, borrowername) < 0 ) {
376
                            $("#error").html(_("Patron '%s' is already in the list.").format(borrowername));
377
                            $("#error").show();
378
                        } else {
379
                            $("#info").html(_("Patron '%s' added.").format(borrowername));
380
                            $("#info").show();
381
                        }
382
                    }
383
                }
384
                wait_for_opener();
385
            }
386
        [% ELSIF selection_type == 'select' %]
387
            function select_user(borrowernumber, data) {
388
                var p = window.opener;
389
                [%  IF callback %]
390
                    p.[% callback | html %](borrowernumber, data);
391
                [%  ELSE %]
392
                    p.select_user(borrowernumber, data);
393
                [%  END %]
394
                window.close();
395
            }
396
        [% END %]
397
    </script>
398
[% END %]
41
[% END %]
399
42
400
[% SET popup_window = 1 %]
43
[% SET popup_window = 1 %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt (-95 / +33 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 1185-1191 Link Here
1185
        }
1168
        }
1186
1169
1187
        var MSG_CANCEL_SELECTED = _("Cancel selected (%s)");
1170
        var MSG_CANCEL_SELECTED = _("Cancel selected (%s)");
1188
        columns_settings_borrowers_table = [% TablesSettings.GetColumns( 'circ', 'circulation', 'table_borrowers', 'json' ) | $raw %];
1189
        $.fn.select2.defaults.set("width", "100%" );
1171
        $.fn.select2.defaults.set("width", "100%" );
1190
        $.fn.select2.defaults.set("dropdownAutoWidth", true );
1172
        $.fn.select2.defaults.set("dropdownAutoWidth", true );
1191
1173
Lines 1567-1645 Link Here
1567
                }
1549
                }
1568
                return false;
1550
                return false;
1569
            });
1551
            });
1552
        });
1553
    </script>
1570
1554
1571
            [% FOREACH biblionumber IN biblionumbers %]
1572
                [% SET url_biblio_params = url_biblio_params _ "&amp;biblionumber=" _ biblionumber %]
1573
            [% END %]
1574
            [% IF multi_hold %]
1575
                [% SET url_biblio_params = url_biblio_params _ "&amp;multi_hold=1" %]
1576
            [% END %]
1577
            search = 0;
1578
            dtMemberResults = KohaTable("table_borrowers", {
1579
                'bServerSide': true,
1580
                'sAjaxSource': "/cgi-bin/koha/svc/members/search",
1581
                'fnServerData': function(sSource, aoData, fnCallback) {
1582
                    if ( ! search ) {
1583
                        return;
1584
                    }
1585
                    aoData.push({
1586
                        'name': 'searchmember',
1587
                        'value': $("#patron").val()
1588
                    },{
1589
                        'name': 'template_path',
1590
                        'value': 'reserve/tables/members_results.tt',
1591
                    });
1592
                    $.ajax({
1593
                        'dataType': 'json',
1594
                        'type': 'POST',
1595
                        'url': sSource,
1596
                        'data': aoData,
1597
                        'success': function(json){
1598
                            // redirect if there is only 1 result.
1599
                            if ( json.iTotalDisplayRecords == 1 ) {
1600
                                var borrowernumber = json.aaData[0].borrowernumber;
1601
                                document.location.href = '/cgi-bin/koha/reserve/request.pl?borrowernumber=' + borrowernumber + "[% url_biblio_params %]"
1602
                                return false;
1603
                            }
1604
                            fnCallback(json);
1605
                        }
1606
                    });
1607
                },
1608
                'fnDrawCallback': function (oSettings) {
1609
                    var data = this.fnGetData();
1610
                    $.each($(this).find("tbody tr"), function(index, tr) {
1611
                        let url = '/cgi-bin/koha/reserve/request.pl?borrowernumber=' + data[index].borrowernumber + "[% url_biblio_params %]"
1612
                        $(tr).off('click').on('click', function() {
1613
                            document.location.href = url;
1614
                        }).addClass('clickable');
1615
                        $(tr).find("a.patron_preview").attr('href', url);
1616
                    });
1617
                },
1618
                'aoColumns':[
1619
                    { 'mDataProp': 'dt_name' },
1620
                    { 'mDataProp': 'dt_address' },
1621
                    { 'mDataProp': 'dt_cardnumber' },
1622
                    { 'mDataProp': 'dt_dateofbirth' },
1623
                    { 'mDataProp': 'dt_category' },
1624
                    { 'mDataProp': 'dt_branch' },
1625
                    { 'mDataProp': 'dt_phone' },
1626
                ],
1627
                'bFilter': false,
1628
                'bAutoWidth': false,
1629
                'sPaginationType': 'full_numbers',
1630
                "bProcessing": true
1631
            }, columns_settings_borrowers_table );
1632
            $("#table_borrowers_wrapper").hide();
1633
1634
            function filter() {
1635
                search = 1;
1636
                $("#table_borrowers").show();
1637
                $("#table_borrowers_wrapper").show();
1638
                dtMemberResults.fnDraw();
1639
                return false;
1640
            }
1641
            $("#holds_patronsearch").on("submit", filter);
1642
1555
1556
    <script>
1557
        $(document).ready(function() {
1558
            table_settings = [% TablesSettings.GetColumns( 'circ', 'circulation', 'table_borrowers', 'json' ) | $raw %];
1559
        });
1560
    </script>
1561
1562
    [% SET url_biblio_params = "biblionumber=" _ biblionumbers.join("&amp;biblionumber=") %]
1563
    [% IF multi_hold %]
1564
        [% SET url_biblio_params = url_biblio_params _ "&amp;multi_hold=1" %]
1565
    [% END %]
1566
1567
    [% PROCESS patron_search_js
1568
        table_id    => 'table_borrowers',
1569
        categories  => categories,
1570
        libraries   => libraries,
1571
        extended_attribute_types => attribute_type_codes,
1572
        columns     => columns,
1573
        open_on_row_click => 1,
1574
        on_click_url      => '/cgi-bin/koha/reserve/request.pl?' _ url_biblio_params,
1575
        redirect_if_one_result => 1,
1576
        redirect_url           => '/cgi-bin/koha/reserve/request.pl?' _ url_biblio_params
1577
    %]
1578
    <script>
1579
        $(document).ready(function() {
1580
            $("#holds_patronsearch").on("submit", filter);
1643
        });
1581
        });
1644
    </script>
1582
    </script>
1645
[% END %]
1583
[% END %]
(-)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 685-690 if ( ( $findborrower && $borrowernumber_hold || $findclub && $club_hold ) Link Here
685
}
685
}
686
$template->param( biblionumbers => \@biblionumbers );
686
$template->param( biblionumbers => \@biblionumbers );
687
687
688
$template->param(
689
    attribute_type_codes => ( C4::Context->preference('ExtendedPatronAttributes')
690
        ? [ Koha::Patron::Attribute::Types->search( { staff_searchable => 1 } )->get_column('code') ]
691
        : []
692
    ),
693
);
694
695
688
# pass the userenv branch if no pickup location selected
696
# pass the userenv branch if no pickup location selected
689
$template->param( pickup => $pickup || C4::Context->userenv->{branch} );
697
$template->param( pickup => $pickup || C4::Context->userenv->{branch} );
690
698
691
- 

Return to bug 30093