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

(-)a/koha-tmpl/intranet-tmpl/prog/js/staff-global.js (-304 / +399 lines)
Lines 1-108 Link Here
1
/* global shortcut delBasket Sticky AUDIO_ALERT_PATH Cookies */
1
/* global shortcut delBasket Sticky AUDIO_ALERT_PATH Cookies */
2
/* exported addBibToContext delBibToContext escape_str escape_price openWindow _ removeFocus toUC confirmDelete confirmClone playSound */
2
/* exported addBibToContext delBibToContext escape_str escape_price openWindow _ removeFocus toUC confirmDelete confirmClone playSound */
3
if ( KOHA === undefined ) var KOHA = {};
3
if (KOHA === undefined) var KOHA = {};
4
4
5
function _(s) { return s; } // dummy function for gettext
5
function _(s) {
6
    return s;
7
} // dummy function for gettext
6
8
7
// http://stackoverflow.com/questions/1038746/equivalent-of-string-format-in-jquery/5341855#5341855
9
// http://stackoverflow.com/questions/1038746/equivalent-of-string-format-in-jquery/5341855#5341855
8
String.prototype.format = function() { return formatstr(this, arguments); };
10
String.prototype.format = function () {
11
    return formatstr(this, arguments);
12
};
9
function formatstr(str, col) {
13
function formatstr(str, col) {
10
    col = typeof col === 'object' ? col : Array.prototype.slice.call(arguments, 1);
14
    col =
15
        typeof col === "object"
16
            ? col
17
            : Array.prototype.slice.call(arguments, 1);
11
    var idx = 0;
18
    var idx = 0;
12
    return str.replace(/%%|%s|%(\d+)\$s/g, function (m, n) {
19
    return str.replace(/%%|%s|%(\d+)\$s/g, function (m, n) {
13
        if (m == "%%") { return "%"; }
20
        if (m == "%%") {
14
        if (m == "%s") { return col[idx++]; }
21
            return "%";
22
        }
23
        if (m == "%s") {
24
            return col[idx++];
25
        }
15
        return col[n];
26
        return col[n];
16
    });
27
    });
17
}
28
}
18
29
19
var HtmlCharsToEscape = {
30
var HtmlCharsToEscape = {
20
    '&': '&',
31
    "&": "&",
21
    '<': '&lt;',
32
    "<": "&lt;",
22
    '>': '&gt;'
33
    ">": "&gt;",
23
};
34
};
24
String.prototype.escapeHtml = function() {
35
String.prototype.escapeHtml = function () {
25
    return this.replace(/[&<>]/g, function(c) {
36
    return this.replace(/[&<>]/g, function (c) {
26
        return HtmlCharsToEscape[c] || c;
37
        return HtmlCharsToEscape[c] || c;
27
    });
38
    });
28
};
39
};
29
function escape_str(s){
40
function escape_str(s) {
30
    return s != null ? s.escapeHtml() : "";
41
    return s != null ? s.escapeHtml() : "";
31
}
42
}
32
43
33
/*
44
/*
34
 * Void method for numbers, for consistency
45
 * Void method for numbers, for consistency
35
 */
46
 */
36
Number.prototype.escapeHtml = function() {
47
Number.prototype.escapeHtml = function () {
37
    return this;
48
    return this;
38
};
49
};
39
function escape_price(p){
50
function escape_price(p) {
40
    return p != null ? p.escapeHtml().format_price() : "";
51
    return p != null ? p.escapeHtml().format_price() : "";
41
}
52
}
42
53
43
// http://stackoverflow.com/questions/14859281/select-tab-by-name-in-jquery-ui-1-10-0/16550804#16550804
54
// http://stackoverflow.com/questions/14859281/select-tab-by-name-in-jquery-ui-1-10-0/16550804#16550804
44
$.fn.tabIndex = function () {
55
$.fn.tabIndex = function () {
45
    return $(this).parent().children('div').index(this);
56
    return $(this).parent().children("div").index(this);
46
};
57
};
47
$.fn.selectTabByID = function (tabID) {
58
$.fn.selectTabByID = function (tabID) {
48
    $("a[href='" + tabID + "']", $(this) ).tab("show");
59
    $("a[href='" + tabID + "']", $(this)).tab("show");
49
};
60
};
50
61
51
$(document).ready(function() {
62
$(document).ready(function () {
52
53
    //check for a hash before setting focus
63
    //check for a hash before setting focus
54
    let hash = window.location.hash;
64
    let hash = window.location.hash;
55
    if ( ! hash ) {
65
    if (!hash) {
56
        $(".tab-pane.active input:text:first").focus();
66
        $(".tab-pane.active input:text:first").focus();
57
    }
67
    }
58
    $("#header_search a[data-toggle='tab']").on("shown.bs.tab", function (e) {
68
    $("#header_search a[data-toggle='tab']").on("shown.bs.tab", function (e) {
59
        $( e.target.hash ).find("input:text:first").focus();
69
        $(e.target.hash).find("input:text:first").focus();
60
    });
70
    });
61
71
62
    $(".close, .close_window").on("click", function(e){
72
    $(".close, .close_window").on("click", function (e) {
63
        e.preventDefault();
73
        e.preventDefault();
64
        window.close();
74
        window.close();
65
    });
75
    });
66
76
67
    $("#checkin_search form").preventDoubleFormSubmit();
77
    $("#checkin_search_panel form").preventDoubleFormSubmit();
68
78
69
    if($("#header_search #checkin_search").length > 0){
79
    if ($("#header_search #checkin_search_panel").length > 0) {
70
        shortcut.add('Alt+r',function (){
80
        shortcut.add("Alt+r", function () {
71
            $("#header_search").selectTabByID("#checkin_search");
81
            $("#header_search").selectTabByID("#checkin_search_panel");
72
            $("#ret_barcode").focus();
82
            $("#ret_barcode").focus();
73
        });
83
        });
74
    } else {
84
    } else {
75
        shortcut.add('Alt+r',function (){
85
        shortcut.add("Alt+r", function () {
76
            location.href="/cgi-bin/koha/circ/returns.pl"; });
86
            location.href = "/cgi-bin/koha/circ/returns.pl";
87
        });
77
    }
88
    }
78
    if($("#header_search #circ_search").length > 0){
89
    if ($("#header_search #circ_search_panel").length > 0) {
79
        shortcut.add('Alt+u',function (){
90
        shortcut.add("Alt+u", function () {
80
            $("#header_search").selectTabByID("#circ_search");
91
            $("#header_search").selectTabByID("#circ_search_panel");
81
            $("#findborrower").focus();
92
            $("#findborrower").focus();
82
        });
93
        });
83
    } else {
94
    } else {
84
        shortcut.add('Alt+u',function(){ location.href="/cgi-bin/koha/circ/circulation.pl"; });
95
        shortcut.add("Alt+u", function () {
96
            location.href = "/cgi-bin/koha/circ/circulation.pl";
97
        });
85
    }
98
    }
86
    if($("#header_search #catalog_search").length > 0){
99
    if ($("#header_search #catalog_search_panel").length > 0) {
87
        shortcut.add('Alt+q',function (){
100
        shortcut.add("Alt+q", function () {
88
            $("#header_search").selectTabByID("#catalog_search");
101
            $("#header_search").selectTabByID("#catalog_search_panel");
89
            $("#search-form").focus();
102
            $("#search-form").focus();
90
        });
103
        });
91
    } else {
104
    } else {
92
        shortcut.add('Alt+q',function(){ location.href="/cgi-bin/koha/catalogue/search.pl"; });
105
        shortcut.add("Alt+q", function () {
106
            location.href = "/cgi-bin/koha/catalogue/search.pl";
107
        });
93
    }
108
    }
94
    if($("#header_search #renew_search").length > 0){
109
    if ($("#header_search #renew_search_panel").length > 0) {
95
        shortcut.add('Alt+w',function (){
110
        shortcut.add("Alt+w", function () {
96
            $("#header_search").selectTabByID("#renew_search");
111
            $("#header_search").selectTabByID("#renew_search_panel");
97
            $("#ren_barcode").focus();
112
            $("#ren_barcode").focus();
98
        });
113
        });
99
    } else {
114
    } else {
100
        shortcut.add('Alt+w',function(){ location.href="/cgi-bin/koha/circ/renew.pl"; });
115
        shortcut.add("Alt+w", function () {
116
            location.href = "/cgi-bin/koha/circ/renew.pl";
117
        });
101
    }
118
    }
102
119
103
    $('#header_search .form-extra-content-toggle').on('click', function () {
120
    $("#header_search .form-extra-content-toggle").on("click", function () {
104
        const extraContent = $(this).closest('form').find('.form-extra-content');
121
        const extraContent = $(this)
105
        if (extraContent.is(':visible')) {
122
            .closest("form")
123
            .find(".form-extra-content");
124
        if (extraContent.is(":visible")) {
106
            extraContent.hide();
125
            extraContent.hide();
107
            $(this).removeClass("extra-content-open");
126
            $(this).removeClass("extra-content-open");
108
        } else {
127
        } else {
Lines 112-201 $(document).ready(function() { Link Here
112
    });
131
    });
113
132
114
    $(".focus").focus();
133
    $(".focus").focus();
115
    $(".validated").each(function() {
134
    $(".validated").each(function () {
116
        $(this).validate();
135
        $(this).validate();
117
    });
136
    });
118
    jQuery.validator.addClassRules("decimal", {
137
    jQuery.validator.addClassRules("decimal", {
119
        number: true
138
        number: true,
120
    });
139
    });
121
140
122
    $("#logout").on("click",function(){
141
    $("#logout").on("click", function () {
123
        logOut();
142
        logOut();
124
    });
143
    });
125
    $("#helper").on("click",function(){
144
    $("#helper").on("click", function () {
126
        openHelp();
145
        openHelp();
127
        return false;
146
        return false;
128
    });
147
    });
129
148
130
    $("body").on("keypress", ".noEnterSubmit", function(e){
149
    $("body").on("keypress", ".noEnterSubmit", function (e) {
131
        return checkEnter(e);
150
        return checkEnter(e);
132
    });
151
    });
133
152
134
    $("#header_search .nav-tabs a").on("click",function(){
153
    $("#header_search .nav-tabs a").on("click", function () {
135
        var field_index = $(this).parent().index();
154
        var field_index = $(this).parent().index();
136
        keep_text( field_index );
155
        keep_text(field_index);
137
    });
156
    });
138
157
139
    $(".toggle_element").on("click",function(e){
158
    $(".toggle_element").on("click", function (e) {
140
        e.preventDefault();
159
        e.preventDefault();
141
        $( $(this).data("element") ).toggle();
160
        $($(this).data("element")).toggle();
142
        if (typeof Sticky !== "undefined" && typeof hcSticky === "function") {
161
        if (typeof Sticky !== "undefined" && typeof hcSticky === "function") {
143
            Sticky.hcSticky('update');
162
            Sticky.hcSticky("update");
144
        }
163
        }
145
    });
164
    });
146
165
147
    var navmenulist = $("#navmenulist");
166
    var navmenulist = $("#navmenulist");
148
    if( navmenulist.length > 0 ){
167
    if (navmenulist.length > 0) {
149
        var path = location.pathname.substring(1);
168
        var path = location.pathname.substring(1);
150
        var url = window.location.toString();
169
        var url = window.location.toString();
151
        var params = '';
170
        var params = "";
152
        if ( url.match(/\?(.+)$/) ) {
171
        if (url.match(/\?(.+)$/)) {
153
            params = "?" + RegExp.$1;
172
            params = "?" + RegExp.$1;
154
        }
173
        }
155
        if ($("a[href$=\"/" + path + params + "\"]", navmenulist).length == 0){
174
        if ($('a[href$="/' + path + params + '"]', navmenulist).length == 0) {
156
            $("a[href$=\"/" + path + "\"]", navmenulist).addClass("current");
175
            $('a[href$="/' + path + '"]', navmenulist).addClass("current");
157
        } else {
176
        } else {
158
            $("a[href$=\"/" + path + params + "\"]", navmenulist).addClass("current");
177
            $('a[href$="/' + path + params + '"]', navmenulist).addClass(
178
                "current"
179
            );
159
        }
180
        }
160
    }
181
    }
161
182
162
    $("#catalog-search-link a").on("mouseenter mouseleave", function(){
183
    $("#catalog-search-link a").on("mouseenter mouseleave", function () {
163
        $("#catalog-search-dropdown a").toggleClass("catalog-search-dropdown-hover");
184
        $("#catalog-search-dropdown a").toggleClass(
185
            "catalog-search-dropdown-hover"
186
        );
164
    });
187
    });
165
188
166
    if ( localStorage.getItem("previousPatrons") || $("#hiddenborrowernumber").val() ){
189
    if (
190
        localStorage.getItem("previousPatrons") ||
191
        $("#hiddenborrowernumber").val()
192
    ) {
167
        var previous_patrons = [];
193
        var previous_patrons = [];
168
        if ( localStorage.getItem("previousPatrons") ) {
194
        if (localStorage.getItem("previousPatrons")) {
169
            previous_patrons = JSON.parse(localStorage.getItem("previousPatrons"));
195
            previous_patrons = JSON.parse(
196
                localStorage.getItem("previousPatrons")
197
            );
170
        }
198
        }
171
199
172
        if ( $("#hiddenborrowernumber").val() ) {
200
        if ($("#hiddenborrowernumber").val()) {
173
            // Remove this patron from the list if they are already there
201
            // Remove this patron from the list if they are already there
174
            previous_patrons = previous_patrons.filter(function (p) {
202
            previous_patrons = previous_patrons.filter(function (p) {
175
                return p["borrowernumber"] != $("#hiddenborrowernumber").val();
203
                return p["borrowernumber"] != $("#hiddenborrowernumber").val();
176
            });
204
            });
177
205
178
            const previous_patron = {
206
            const previous_patron = {
179
                "borrowernumber": $("#hiddenborrowernumber").val(),
207
                borrowernumber: $("#hiddenborrowernumber").val(),
180
                "name": $("#hiddenborrowername").val(),
208
                name: $("#hiddenborrowername").val(),
181
                "card": $("#hiddenborrowercard").val()
209
                card: $("#hiddenborrowercard").val(),
182
            };
210
            };
183
211
184
            previous_patrons.unshift( previous_patron );
212
            previous_patrons.unshift(previous_patron);
185
            // Limit to number of patrons specified in showLastPatronCount
213
            // Limit to number of patrons specified in showLastPatronCount
186
            if ( previous_patrons.length > showLastPatronCount ) previous_patrons.pop();
214
            if (previous_patrons.length > showLastPatronCount)
187
            localStorage.setItem("previousPatrons", JSON.stringify(previous_patrons));
215
                previous_patrons.pop();
216
            localStorage.setItem(
217
                "previousPatrons",
218
                JSON.stringify(previous_patrons)
219
            );
188
        }
220
        }
189
221
190
        if ( previous_patrons.length ) {
222
        if (previous_patrons.length) {
191
            let p = previous_patrons[0];
223
            let p = previous_patrons[0];
192
            $("#lastborrowerlink").show();
224
            $("#lastborrowerlink").show();
193
            $("#lastborrowerlink").prop("title", `${p["name"]} (${p["card"]})`);
225
            $("#lastborrowerlink").prop("title", `${p["name"]} (${p["card"]})`);
194
            $("#lastborrowerlink").prop("href", `/cgi-bin/koha/circ/circulation.pl?borrowernumber=${p["borrowernumber"]}`);
226
            $("#lastborrowerlink").prop(
227
                "href",
228
                `/cgi-bin/koha/circ/circulation.pl?borrowernumber=${p["borrowernumber"]}`
229
            );
195
            $("#lastborrower-window").css("display", "inline-flex");
230
            $("#lastborrower-window").css("display", "inline-flex");
196
231
197
            previous_patrons.reverse();
232
            previous_patrons.reverse();
198
            for ( i in previous_patrons ) {
233
            for (i in previous_patrons) {
199
                p = previous_patrons[i];
234
                p = previous_patrons[i];
200
                const el = `<li><a href="/cgi-bin/koha/circ/circulation.pl?borrowernumber=${p["borrowernumber"]}">${p["name"]} (${p["card"]})</a></li>`;
235
                const el = `<li><a href="/cgi-bin/koha/circ/circulation.pl?borrowernumber=${p["borrowernumber"]}">${p["name"]} (${p["card"]})</a></li>`;
201
                $("#lastBorrowerList").prepend(el);
236
                $("#lastBorrowerList").prepend(el);
Lines 203-234 $(document).ready(function() { Link Here
203
        }
238
        }
204
    }
239
    }
205
240
206
    if( $("#hiddenborrowernumber").val() ){
241
    if ($("#hiddenborrowernumber").val()) {
207
        localStorage.setItem("currentborrowernumber", $("#hiddenborrowernumber").val() );
242
        localStorage.setItem(
243
            "currentborrowernumber",
244
            $("#hiddenborrowernumber").val()
245
        );
208
    }
246
    }
209
247
210
    $("#lastborrower-remove").click(function() {
248
    $("#lastborrower-remove").click(function () {
211
        removeLastBorrower();
249
        removeLastBorrower();
212
        $("#lastborrower-window").hide();
250
        $("#lastborrower-window").hide();
213
    });
251
    });
214
252
215
    /* Search results browsing */
253
    /* Search results browsing */
216
    /* forms with action leading to search */
254
    /* forms with action leading to search */
217
    $("form[action*='search.pl']").submit(function(){
255
    $("form[action*='search.pl']").submit(function () {
218
        $('[name^="limit"]').each(function(){
256
        $('[name^="limit"]').each(function () {
219
            if( $(this).val() == '' ){
257
            if ($(this).val() == "") {
220
                $(this).prop("disabled","disabled");
258
                $(this).prop("disabled", "disabled");
221
            }
259
            }
222
        });
260
        });
223
        var disabledPrior = false;
261
        var disabledPrior = false;
224
        $(".search-term-row").each(function(){
262
        $(".search-term-row").each(function () {
225
            if( disabledPrior ){
263
            if (disabledPrior) {
226
                $(this).find('select[name="op"]').prop("disabled","disabled");
264
                $(this).find('select[name="op"]').prop("disabled", "disabled");
227
                disabledPrior = false;
265
                disabledPrior = false;
228
            }
266
            }
229
            if( $(this).find('input[name="q"]').val() == "" ){
267
            if ($(this).find('input[name="q"]').val() == "") {
230
                $(this).find('input').prop("disabled","disabled");
268
                $(this).find("input").prop("disabled", "disabled");
231
                $(this).find('select').prop("disabled","disabled");
269
                $(this).find("select").prop("disabled", "disabled");
232
                disabledPrior = true;
270
                disabledPrior = true;
233
            }
271
            }
234
        });
272
        });
Lines 236-246 $(document).ready(function() { Link Here
236
        saveOrClearSimpleSearchParams();
274
        saveOrClearSimpleSearchParams();
237
    });
275
    });
238
    /* any link to launch a search except navigation links */
276
    /* any link to launch a search except navigation links */
239
    $("[href*='search.pl?']").not(".nav").not('.searchwithcontext').click(function(){
277
    $("[href*='search.pl?']")
240
        resetSearchContext();
278
        .not(".nav")
241
    });
279
        .not(".searchwithcontext")
280
        .click(function () {
281
            resetSearchContext();
282
        });
242
    /* any link to a detail page from the results page. */
283
    /* any link to a detail page from the results page. */
243
    $("#bookbag_form a[href*='detail.pl?']").click(function(){
284
    $("#bookbag_form a[href*='detail.pl?']").click(function () {
244
        resetSearchContext();
285
        resetSearchContext();
245
    });
286
    });
246
    // add back to top button on each staff page
287
    // add back to top button on each staff page
Lines 259-293 $(document).ready(function() { Link Here
259
    });
300
    });
260
});
301
});
261
302
262
function removeLastBorrower(){
303
function removeLastBorrower() {
263
    localStorage.removeItem("previousPatrons");
304
    localStorage.removeItem("previousPatrons");
264
}
305
}
265
306
266
// http://jennifermadden.com/javascript/stringEnterKeyDetector.html
307
// http://jennifermadden.com/javascript/stringEnterKeyDetector.html
267
function checkEnter(e){ //e is event object passed from function invocation
308
function checkEnter(e) {
309
    //e is event object passed from function invocation
268
    var characterCode; // literal character code will be stored in this variable
310
    var characterCode; // literal character code will be stored in this variable
269
    if(e && e.which){ //if which property of event object is supported (NN4)
311
    if (e && e.which) {
312
        //if which property of event object is supported (NN4)
270
        characterCode = e.which; //character code is contained in NN4's which property
313
        characterCode = e.which; //character code is contained in NN4's which property
271
    } else {
314
    } else {
272
        characterCode = e.keyCode; //character code is contained in IE's keyCode property
315
        characterCode = e.keyCode; //character code is contained in IE's keyCode property
273
    }
316
    }
274
    if( characterCode == 13 //if generated character code is equal to ascii 13 (if enter key)
317
    if (
275
        && e.target.nodeName == "INPUT"
318
        characterCode == 13 && //if generated character code is equal to ascii 13 (if enter key)
276
        && e.target.type != "submit" // Allow enter to submit using the submit button
319
        e.target.nodeName == "INPUT" &&
277
    ){
320
        e.target.type != "submit" // Allow enter to submit using the submit button
321
    ) {
278
        return false;
322
        return false;
279
    } else {
323
    } else {
280
        return true;
324
        return true;
281
    }
325
    }
282
}
326
}
283
327
284
function clearHoldFor(){
328
function clearHoldFor() {
285
    Cookies.remove("holdfor", { path: '/', SameSite: 'Lax' });
329
    Cookies.remove("holdfor", { path: "/", SameSite: "Lax" });
286
}
330
}
287
331
288
function logOut(){
332
function logOut() {
289
    if( typeof delBasket == 'function' ){
333
    if (typeof delBasket == "function") {
290
        delBasket('main', true);
334
        delBasket("main", true);
291
    }
335
    }
292
    clearHoldFor();
336
    clearHoldFor();
293
    removeLastBorrower();
337
    removeLastBorrower();
Lines 298-326 function logOut(){ Link Here
298
    localStorage.removeItem("item_search_selections");
342
    localStorage.removeItem("item_search_selections");
299
}
343
}
300
344
301
function openHelp(){
345
function openHelp() {
302
    window.open( "/cgi-bin/koha/help.pl", "_blank");
346
    window.open("/cgi-bin/koha/help.pl", "_blank");
303
}
347
}
304
348
305
jQuery.fn.preventDoubleFormSubmit = function() {
349
jQuery.fn.preventDoubleFormSubmit = function () {
306
    jQuery(this).submit(function() {
350
    jQuery(this).submit(function () {
307
        $("body, form input[type='submit'], form button[type='submit'], form a").addClass('waiting');
351
        $(
308
        if (this.beenSubmitted)
352
            "body, form input[type='submit'], form button[type='submit'], form a"
309
            return false;
353
        ).addClass("waiting");
310
        else
354
        if (this.beenSubmitted) return false;
311
            this.beenSubmitted = true;
355
        else this.beenSubmitted = true;
312
    });
356
    });
313
};
357
};
314
358
315
function openWindow(link,name,width,height) {
359
function openWindow(link, name, width, height) {
316
    name = (typeof name == "undefined")?'popup':name;
360
    name = typeof name == "undefined" ? "popup" : name;
317
    width = (typeof width == "undefined")?'600':width;
361
    width = typeof width == "undefined" ? "600" : width;
318
    height = (typeof height == "undefined")?'400':height;
362
    height = typeof height == "undefined" ? "400" : height;
319
    //IE <= 9 can't handle a "name" with whitespace
363
    //IE <= 9 can't handle a "name" with whitespace
320
    try {
364
    try {
321
        window.open(link,name,'width='+width+',height='+height+',resizable=yes,toolbar=false,scrollbars=yes,top');
365
        window.open(
322
    } catch(e) {
366
            link,
323
        window.open(link,null,'width='+width+',height='+height+',resizable=yes,toolbar=false,scrollbars=yes,top');
367
            name,
368
            "width=" +
369
                width +
370
                ",height=" +
371
                height +
372
                ",resizable=yes,toolbar=false,scrollbars=yes,top"
373
        );
374
    } catch (e) {
375
        window.open(
376
            link,
377
            null,
378
            "width=" +
379
                width +
380
                ",height=" +
381
                height +
382
                ",resizable=yes,toolbar=false,scrollbars=yes,top"
383
        );
324
    }
384
    }
325
}
385
}
326
386
Lines 328-355 function openWindow(link,name,width,height) { Link Here
328
// repeated scanning actions on errors so the librarian doesn't
388
// repeated scanning actions on errors so the librarian doesn't
329
// continue scanning and miss the error.
389
// continue scanning and miss the error.
330
function removeFocus() {
390
function removeFocus() {
331
    $(':focus').blur();
391
    $(":focus").blur();
332
}
392
}
333
393
334
function toUC(f) {
394
function toUC(f) {
335
    var x=f.value.toUpperCase();
395
    var x = f.value.toUpperCase();
336
    f.value=x;
396
    f.value = x;
337
    return true;
397
    return true;
338
}
398
}
339
399
340
function confirmDelete(message) {
400
function confirmDelete(message) {
341
    return (confirm(message) ? true : false);
401
    return confirm(message) ? true : false;
342
}
402
}
343
403
344
function confirmClone(message) {
404
function confirmClone(message) {
345
    return (confirm(message) ? true : false);
405
    return confirm(message) ? true : false;
346
}
406
}
347
407
348
function playSound( sound ) {
408
function playSound(sound) {
349
    if ( ! ( sound.indexOf('http://') === 0 || sound.indexOf('https://') === 0  ) ) {
409
    if (!(sound.indexOf("http://") === 0 || sound.indexOf("https://") === 0)) {
350
        sound = AUDIO_ALERT_PATH + sound;
410
        sound = AUDIO_ALERT_PATH + sound;
351
    }
411
    }
352
    document.getElementById("audio-alert").innerHTML = '<audio src="' + sound + '" autoplay="autoplay" autobuffer="autobuffer"></audio>';
412
    document.getElementById("audio-alert").innerHTML =
413
        '<audio src="' +
414
        sound +
415
        '" autoplay="autoplay" autobuffer="autobuffer"></audio>';
353
}
416
}
354
417
355
// For keeping the text when navigating the search tabs
418
// For keeping the text when navigating the search tabs
Lines 358-365 function keep_text(clicked_index) { Link Here
358
    var persist = searchboxes[0].value;
421
    var persist = searchboxes[0].value;
359
422
360
    for (var i = 0; i < searchboxes.length - 1; i++) {
423
    for (var i = 0; i < searchboxes.length - 1; i++) {
361
        if (searchboxes[i].value != searchboxes[i+1].value) {
424
        if (searchboxes[i].value != searchboxes[i + 1].value) {
362
            if (i === searchboxes.length-2) {
425
            if (i === searchboxes.length - 2) {
363
                if (searchboxes[i].value != searchboxes[0].value) {
426
                if (searchboxes[i].value != searchboxes[0].value) {
364
                    persist = searchboxes[i].value;
427
                    persist = searchboxes[i].value;
365
                } else if (searchboxes.length === 2) {
428
                } else if (searchboxes.length === 2) {
Lines 367-376 function keep_text(clicked_index) { Link Here
367
                        persist = searchboxes[1].value;
430
                        persist = searchboxes[1].value;
368
                    }
431
                    }
369
                } else {
432
                } else {
370
                    persist = searchboxes[i+1].value;
433
                    persist = searchboxes[i + 1].value;
371
                }
434
                }
372
            } else if (searchboxes[i+1].value != searchboxes[i+2].value) {
435
            } else if (searchboxes[i + 1].value != searchboxes[i + 2].value) {
373
                persist = searchboxes[i+1].value;
436
                persist = searchboxes[i + 1].value;
374
            }
437
            }
375
        }
438
        }
376
    }
439
    }
Lines 381-422 function keep_text(clicked_index) { Link Here
381
}
444
}
382
445
383
// Extends jQuery API
446
// Extends jQuery API
384
jQuery.extend({uniqueArray:function(array){
447
jQuery.extend({
385
    return $.grep(array, function(el, index) {
448
    uniqueArray: function (array) {
386
        return index === $.inArray(el, array);
449
        return $.grep(array, function (el, index) {
387
    });
450
            return index === $.inArray(el, array);
388
}});
451
        });
452
    },
453
});
389
454
390
function removeByValue(arr, val) {
455
function removeByValue(arr, val) {
391
    for(var i=0; i<arr.length; i++) {
456
    for (var i = 0; i < arr.length; i++) {
392
        if(arr[i] == val) {
457
        if (arr[i] == val) {
393
            arr.splice(i, 1);
458
            arr.splice(i, 1);
394
            break;
459
            break;
395
        }
460
        }
396
    }
461
    }
397
}
462
}
398
463
399
function addBibToContext( bibnum ) {
464
function addBibToContext(bibnum) {
400
    bibnum = parseInt(bibnum, 10);
465
    bibnum = parseInt(bibnum, 10);
401
    var bibnums = getContextBiblioNumbers();
466
    var bibnums = getContextBiblioNumbers();
402
    bibnums.push(bibnum);
467
    bibnums.push(bibnum);
403
    setContextBiblioNumbers( bibnums );
468
    setContextBiblioNumbers(bibnums);
404
    setContextBiblioNumbers( $.uniqueArray( bibnums ) );
469
    setContextBiblioNumbers($.uniqueArray(bibnums));
405
}
470
}
406
471
407
function delBibToContext( bibnum ) {
472
function delBibToContext(bibnum) {
408
    var bibnums = getContextBiblioNumbers();
473
    var bibnums = getContextBiblioNumbers();
409
    removeByValue( bibnums, bibnum );
474
    removeByValue(bibnums, bibnum);
410
    setContextBiblioNumbers( $.uniqueArray( bibnums ) );
475
    setContextBiblioNumbers($.uniqueArray(bibnums));
411
}
476
}
412
477
413
function setContextBiblioNumbers( bibnums ) {
478
function setContextBiblioNumbers(bibnums) {
414
    localStorage.setItem('bibs_selected', JSON.stringify( bibnums ) );
479
    localStorage.setItem("bibs_selected", JSON.stringify(bibnums));
415
}
480
}
416
481
417
function getContextBiblioNumbers() {
482
function getContextBiblioNumbers() {
418
    var r = localStorage.getItem('bibs_selected');
483
    var r = localStorage.getItem("bibs_selected");
419
    if ( r ) {
484
    if (r) {
420
        return JSON.parse(r);
485
        return JSON.parse(r);
421
    }
486
    }
422
    r = new Array();
487
    r = new Array();
Lines 424-448 function getContextBiblioNumbers() { Link Here
424
}
489
}
425
490
426
function resetSearchContext() {
491
function resetSearchContext() {
427
    setContextBiblioNumbers( new Array() );
492
    setContextBiblioNumbers(new Array());
428
}
493
}
429
494
430
function saveOrClearSimpleSearchParams() {
495
function saveOrClearSimpleSearchParams() {
431
    // Simple masthead search - pass value for display on details page
496
    // Simple masthead search - pass value for display on details page
432
    var pulldown_selection;
497
    var pulldown_selection;
433
    var searchbox_value;
498
    var searchbox_value;
434
    if( $("#cat-search-block select.advsearch").length ){
499
    if ($("#cat-search-block select.advsearch").length) {
435
        pulldown_selection = $("#cat-search-block select.advsearch").val();
500
        pulldown_selection = $("#cat-search-block select.advsearch").val();
436
    } else {
501
    } else {
437
        pulldown_selection ="";
502
        pulldown_selection = "";
438
    }
503
    }
439
    if( $("#cat-search-block #search-form").length ){
504
    if ($("#cat-search-block #search-form").length) {
440
        searchbox_value = $("#cat-search-block #search-form").val();
505
        searchbox_value = $("#cat-search-block #search-form").val();
441
    } else {
506
    } else {
442
        searchbox_value ="";
507
        searchbox_value = "";
443
    }
508
    }
444
    localStorage.setItem('cat_search_pulldown_selection', pulldown_selection );
509
    localStorage.setItem("cat_search_pulldown_selection", pulldown_selection);
445
    localStorage.setItem('searchbox_value', searchbox_value );
510
    localStorage.setItem("searchbox_value", searchbox_value);
446
}
511
}
447
512
448
function patron_autocomplete(node, options) {
513
function patron_autocomplete(node, options) {
Lines 451-575 function patron_autocomplete(node, options) { Link Here
451
    let on_select_callback;
516
    let on_select_callback;
452
517
453
    if (options) {
518
    if (options) {
454
        if (options['link-to']) {
519
        if (options["link-to"]) {
455
            link_to = options['link-to'];
520
            link_to = options["link-to"];
456
        }
521
        }
457
        if (options['url-params']) {
522
        if (options["url-params"]) {
458
            url_params = options['url-params'];
523
            url_params = options["url-params"];
459
        }
524
        }
460
        if (options['on-select-callback']) {
525
        if (options["on-select-callback"]) {
461
            on_select_callback = options['on-select-callback'];
526
            on_select_callback = options["on-select-callback"];
462
        }
527
        }
463
    }
528
    }
464
    return node.autocomplete({
529
    return (node
465
        source: function (request, response) {
530
        .autocomplete({
466
            let q = buildPatronSearchQuery(request.term);
531
            source: function (request, response) {
467
532
                let q = buildPatronSearchQuery(request.term);
468
            let params = {
533
469
                '_page': 1,
534
                let params = {
470
                '_per_page': 10,
535
                    _page: 1,
471
                'q': JSON.stringify(q),
536
                    _per_page: 10,
472
                '_order_by': '+me.surname,+me.firstname',
537
                    q: JSON.stringify(q),
473
            };
538
                    _order_by: "+me.surname,+me.firstname",
474
            $.ajax({
539
                };
475
                data: params,
540
                $.ajax({
476
                type: 'GET',
541
                    data: params,
477
                url: '/api/v1/patrons',
542
                    type: "GET",
478
                headers: {
543
                    url: "/api/v1/patrons",
479
                    "x-koha-embed": "library"
544
                    headers: {
480
                },
545
                        "x-koha-embed": "library",
481
                success: function (data) {
546
                    },
482
                    return response(data);
547
                    success: function (data) {
483
                },
548
                        return response(data);
484
                error: function (e) {
549
                    },
485
                    if (e.state() != 'rejected') {
550
                    error: function (e) {
486
                        alert(__("An error occurred. Check the logs for details."));
551
                        if (e.state() != "rejected") {
487
                    }
552
                            alert(
488
                    return response();
553
                                __(
554
                                    "An error occurred. Check the logs for details."
555
                                )
556
                            );
557
                        }
558
                        return response();
559
                    },
560
                });
561
            },
562
            minLength: 3,
563
            select: function (event, ui) {
564
                if (ui.item.link) {
565
                    window.location.href = ui.item.link;
566
                } else if (on_select_callback) {
567
                    return on_select_callback(event, ui);
489
                }
568
                }
490
            });
569
            },
491
        },
570
            focus: function (event, ui) {
492
        minLength: 3,
571
                event.preventDefault(); // Don't replace the text field
493
        select: function (event, ui) {
572
            },
494
            if (ui.item.link) {
573
        })
495
                window.location.href = ui.item.link;
574
        .data("ui-autocomplete")._renderItem = function (ul, item) {
496
            } else if (on_select_callback) {
575
        if (link_to) {
497
                return on_select_callback(event, ui);
576
            item.link =
498
            }
577
                link_to == "circ"
499
        },
500
        focus: function (event, ui) {
501
            event.preventDefault(); // Don't replace the text field
502
        },
503
    })
504
        .data("ui-autocomplete")
505
        ._renderItem = function (ul, item) {
506
            if (link_to) {
507
                item.link = link_to == 'circ'
508
                    ? "/cgi-bin/koha/circ/circulation.pl"
578
                    ? "/cgi-bin/koha/circ/circulation.pl"
509
                    : link_to == 'reserve'
579
                    : link_to == "reserve"
510
                        ? "/cgi-bin/koha/reserve/request.pl"
580
                    ? "/cgi-bin/koha/reserve/request.pl"
511
                        : "/cgi-bin/koha/members/moremember.pl";
581
                    : "/cgi-bin/koha/members/moremember.pl";
512
                item.link += (url_params ? '?' + url_params + '&' : "?") + 'borrowernumber=' + item.patron_id;
582
            item.link +=
513
            } else {
583
                (url_params ? "?" + url_params + "&" : "?") +
514
                item.link = null;
584
                "borrowernumber=" +
515
            }
585
                item.patron_id;
586
        } else {
587
            item.link = null;
588
        }
516
589
517
            var cardnumber = "";
590
        var cardnumber = "";
518
            if (item.cardnumber != "") {
591
        if (item.cardnumber != "") {
519
                // Display card number in parentheses if it exists
592
            // Display card number in parentheses if it exists
520
                cardnumber = " (" + item.cardnumber + ") ";
593
            cardnumber = " (" + item.cardnumber + ") ";
521
            }
594
        }
522
            if (item.library_id == loggedInLibrary) {
595
        if (item.library_id == loggedInLibrary) {
523
                loggedInClass = "ac-currentlibrary";
596
            loggedInClass = "ac-currentlibrary";
524
            } else {
597
        } else {
525
                loggedInClass = "";
598
            loggedInClass = "";
526
            }
599
        }
527
            return $("<li></li>")
600
        return $("<li></li>")
528
                .addClass(loggedInClass)
601
            .addClass(loggedInClass)
529
                .data("ui-autocomplete-item", item)
602
            .data("ui-autocomplete-item", item)
530
                .append(
603
            .append(
531
                    ""
604
                "" +
532
                    + (item.link ? "<a href=\"" + item.link + "\">" : "<a>")
605
                    (item.link ? '<a href="' + item.link + '">' : "<a>") +
533
                    + (item.surname ? item.surname.escapeHtml() : "") + ", "
606
                    (item.surname ? item.surname.escapeHtml() : "") +
534
                    + (item.firstname ? item.firstname.escapeHtml() : "")
607
                    ", " +
535
                    + " " + (item.middle_name ? item.middle_name.escapeHtml() : "")
608
                    (item.firstname ? item.firstname.escapeHtml() : "") +
536
                    + cardnumber.escapeHtml()
609
                    " " +
537
                    + " <small>"
610
                    (item.middle_name ? item.middle_name.escapeHtml() : "") +
538
                    + (item.date_of_birth
611
                    cardnumber.escapeHtml() +
539
                        ? $date(item.date_of_birth)
612
                    " <small>" +
540
                        + "<span class=\"age_years\"> ("
613
                    (item.date_of_birth
541
                        + $get_age(item.date_of_birth)
614
                        ? $date(item.date_of_birth) +
542
                        + " "
615
                          '<span class="age_years"> (' +
543
                        + __("years")
616
                          $get_age(item.date_of_birth) +
544
                        + ")</span>,"
617
                          " " +
545
                        : ""
618
                          __("years") +
546
                    ) + " "
619
                          ")</span>,"
547
                    + $format_address(item, { no_line_break: true, include_li: false }) + " "
620
                        : "") +
548
                    + (!singleBranchMode
621
                    " " +
549
                        ?
622
                    $format_address(item, {
550
                        "<span class=\"ac-library\">"
623
                        no_line_break: true,
551
                        + item.library.name.escapeHtml()
624
                        include_li: false,
552
                        + "</span>"
625
                    }) +
553
                        : "")
626
                    " " +
554
                    + "</small>"
627
                    (!singleBranchMode
555
                    + "</a>")
628
                        ? '<span class="ac-library">' +
556
                .appendTo(ul);
629
                          item.library.name.escapeHtml() +
557
        };
630
                          "</span>"
631
                        : "") +
632
                    "</small>" +
633
                    "</a>"
634
            )
635
            .appendTo(ul);
636
    });
558
}
637
}
559
638
560
function expandPatronSearchFields(search_fields) {
639
function expandPatronSearchFields(search_fields) {
561
    switch(search_fields) {
640
    switch (search_fields) {
562
        case 'standard':
641
        case "standard":
563
            return defaultPatronSearchFields;
642
            return defaultPatronSearchFields;
564
            break;
643
            break;
565
        case 'full_address':
644
        case "full_address":
566
            return 'streetnumber|streettype|address|address2|city|state|zipcode|country';
645
            return "streetnumber|streettype|address|address2|city|state|zipcode|country";
567
            break;
646
            break;
568
        case 'all_emails':
647
        case "all_emails":
569
            return 'email|emailpro|B_email';
648
            return "email|emailpro|B_email";
570
            break;
649
            break;
571
        case 'all_phones':
650
        case "all_phones":
572
            return 'phone|phonepro|B_phone|altcontactphone|mobile';
651
            return "phone|phonepro|B_phone|altcontactphone|mobile";
573
            break;
652
            break;
574
        default:
653
        default:
575
            return search_fields;
654
            return search_fields;
Lines 586-597 function expandPatronSearchFields(search_fields) { Link Here
586
 * - table_prefix: (String) table name to prefix the fields with, defaults to 'me'
665
 * - table_prefix: (String) table name to prefix the fields with, defaults to 'me'
587
 */
666
 */
588
function buildPatronSearchQuery(term, options) {
667
function buildPatronSearchQuery(term, options) {
589
590
    let q = [];
668
    let q = [];
591
    let table_prefix;
669
    let table_prefix;
592
    let leading_wildcard;
670
    let leading_wildcard;
593
    let search_fields = [];
671
    let search_fields = [];
594
    let patterns = term.split(/[\s,]+/).filter(function (s) { return s.length });
672
    let patterns = term.split(/[\s,]+/).filter(function (s) {
673
        return s.length;
674
    });
595
675
596
    // Bail if no patterns
676
    // Bail if no patterns
597
    if (patterns.length == 0) {
677
    if (patterns.length == 0) {
Lines 599-676 function buildPatronSearchQuery(term, options) { Link Here
599
    }
679
    }
600
680
601
    // Table prefix: If table_prefix options exists, use that
681
    // Table prefix: If table_prefix options exists, use that
602
    if (typeof options !== 'undefined' && options.table_prefix) {
682
    if (typeof options !== "undefined" && options.table_prefix) {
603
        table_prefix = options.table_prefix;
683
        table_prefix = options.table_prefix;
604
    // If not, default to 'me'
684
        // If not, default to 'me'
605
    } else {
685
    } else {
606
        table_prefix = 'me';
686
        table_prefix = "me";
607
    }
687
    }
608
688
609
    // Leading wildcard: If search_type option exists, use that
689
    // Leading wildcard: If search_type option exists, use that
610
    if (typeof options !== 'undefined' && options.search_type) {
690
    if (typeof options !== "undefined" && options.search_type) {
611
        leading_wildcard = options.search_type === "contains" ? '%' : '';
691
        leading_wildcard = options.search_type === "contains" ? "%" : "";
612
    // If not, use DefaultPatronSearchMethod system preference instead
692
        // If not, use DefaultPatronSearchMethod system preference instead
613
    } else {
693
    } else {
614
        leading_wildcard = defaultPatronSearchMethod === 'contains' ? '%' : '';
694
        leading_wildcard = defaultPatronSearchMethod === "contains" ? "%" : "";
615
    }
695
    }
616
696
617
    let searched_attribute_fields = [];
697
    let searched_attribute_fields = [];
618
    // Search fields: If search_fields option exists, we use that
698
    // Search fields: If search_fields option exists, we use that
619
    if (typeof options !== 'undefined' && options.search_fields) {
699
    if (typeof options !== "undefined" && options.search_fields) {
620
        expand_fields = expandPatronSearchFields(options.search_fields);
700
        expand_fields = expandPatronSearchFields(options.search_fields);
621
        expand_fields.split('\|').forEach(function (field, i) {
701
        expand_fields.split("|").forEach(function (field, i) {
622
            if( field.startsWith('_ATTR_') ){
702
            if (field.startsWith("_ATTR_")) {
623
                let attr_field = field.replace("_ATTR_","");
703
                let attr_field = field.replace("_ATTR_", "");
624
                searched_attribute_fields.push( attr_field );
704
                searched_attribute_fields.push(attr_field);
625
            } else {
705
            } else {
626
                search_fields.push( field );
706
                search_fields.push(field);
627
            }
707
            }
628
        });
708
        });
629
    // If not, we use DefaultPatronSearchFields system preference instead
709
        // If not, we use DefaultPatronSearchFields system preference instead
630
    } else {
710
    } else {
631
        search_fields = defaultPatronSearchFields.split('\|');
711
        search_fields = defaultPatronSearchFields.split("|");
632
    }
712
    }
633
713
634
    // Add each pattern for each search field
714
    // Add each pattern for each search field
635
    let pattern_subquery_and = [];
715
    let pattern_subquery_and = [];
636
    patterns.forEach(function (pattern, i) {
716
    patterns.forEach(function (pattern, i) {
637
            let pattern_subquery_or = [];
717
        let pattern_subquery_or = [];
638
            search_fields.forEach(function (field, i) {
718
        search_fields.forEach(function (field, i) {
639
                pattern_subquery_or.push(
719
            pattern_subquery_or.push({
640
                    { [table_prefix + "." + field]: { 'like': leading_wildcard + pattern + '%' } }
720
                [table_prefix + "." + field]: {
641
                );
721
                    like: leading_wildcard + pattern + "%",
642
                if (field == 'dateofbirth') {
722
                },
643
                    try {
644
                        let d = $date_to_rfc3339(pattern);
645
                        pattern_subquery_or.push({ [table_prefix + "." + field]: d });
646
                    } catch {
647
                        // Hide the warning if the date is not correct
648
                    }
649
                }
650
            });
723
            });
651
            pattern_subquery_and.push(pattern_subquery_or);
724
            if (field == "dateofbirth") {
725
                try {
726
                    let d = $date_to_rfc3339(pattern);
727
                    pattern_subquery_or.push({
728
                        [table_prefix + "." + field]: d,
729
                    });
730
                } catch {
731
                    // Hide the warning if the date is not correct
732
                }
733
            }
652
        });
734
        });
735
        pattern_subquery_and.push(pattern_subquery_or);
736
    });
653
    q.push({ "-and": pattern_subquery_and });
737
    q.push({ "-and": pattern_subquery_and });
654
738
655
656
    // Add full search term for each search field
739
    // Add full search term for each search field
657
    let term_subquery_or = [];
740
    let term_subquery_or = [];
658
    search_fields.forEach(function (field, i) {
741
    search_fields.forEach(function (field, i) {
659
        term_subquery_or.push(
742
        term_subquery_or.push({
660
            { [table_prefix + "." + field]: { 'like': leading_wildcard + term + '%' } }
743
            [table_prefix + "." + field]: {
661
        );
744
                like: leading_wildcard + term + "%",
745
            },
746
        });
662
    });
747
    });
663
    q.push({ "-or": term_subquery_or });
748
    q.push({ "-or": term_subquery_or });
664
749
665
    // Add each pattern for each extended patron attributes
750
    // Add each pattern for each extended patron attributes
666
    if ( typeof options !== 'undefined' && ( (options.search_fields == 'standard' && options.extended_attribute_types) || ( searched_attribute_fields.length > 0 ) ) && extendedPatronAttributes) {
751
    if (
667
        extended_attribute_codes_to_search = (searched_attribute_fields.length > 0) ? searched_attribute_fields : options.extended_attribute_types;
752
        typeof options !== "undefined" &&
753
        ((options.search_fields == "standard" &&
754
            options.extended_attribute_types) ||
755
            searched_attribute_fields.length > 0) &&
756
        extendedPatronAttributes
757
    ) {
758
        extended_attribute_codes_to_search =
759
            searched_attribute_fields.length > 0
760
                ? searched_attribute_fields
761
                : options.extended_attribute_types;
668
        extended_attribute_subquery_and = [];
762
        extended_attribute_subquery_and = [];
669
        patterns.forEach(function (pattern, i) {
763
        patterns.forEach(function (pattern, i) {
670
            let extended_attribute_sub_or = [];
764
            let extended_attribute_sub_or = [];
671
            extended_attribute_sub_or.push({
765
            extended_attribute_sub_or.push({
672
                "extended_attributes.value": { "like": leading_wildcard + pattern + '%' },
766
                "extended_attributes.value": {
673
                "extended_attributes.code": extended_attribute_codes_to_search
767
                    like: leading_wildcard + pattern + "%",
768
                },
769
                "extended_attributes.code": extended_attribute_codes_to_search,
674
            });
770
            });
675
            extended_attribute_subquery_and.push(extended_attribute_sub_or);
771
            extended_attribute_subquery_and.push(extended_attribute_sub_or);
676
        });
772
        });
Lines 679-691 function buildPatronSearchQuery(term, options) { Link Here
679
    return q;
775
    return q;
680
}
776
}
681
777
682
function selectBsTabByHash( tabs_container_id ){
778
function selectBsTabByHash(tabs_container_id) {
683
    /* Check for location.hash in the page URL */
779
    /* Check for location.hash in the page URL */
684
    /* If present the location hash will be used to activate the correct tab */
780
    /* If present the location hash will be used to activate the correct tab */
685
    var hash = document.location.hash;
781
    var hash = document.location.hash;
686
    if( hash !== "" ){
782
    if (hash !== "") {
687
        $('#' + tabs_container_id + ' a[href="' + hash + '"]').tab('show');
783
        $("#" + tabs_container_id + ' a[href="' + hash + '"]').tab("show");
688
    } else {
784
    } else {
689
        $('#' + tabs_container_id + ' a:first').tab('show');
785
        $("#" + tabs_container_id + " a:first").tab("show");
690
    }
786
    }
691
}
787
}
692
- 

Return to bug 36490