Bug 20168: Update of the OPAC bootstrap template to bootstrap v4
[koha.git] / koha-tmpl / opac-tmpl / bootstrap / js / global.js
1 (function( w ){
2     // if the class is already set, the font has already been loaded
3     if( w.document.documentElement.className.indexOf( "fonts-loaded" ) > -1 ){
4         return;
5     }
6     var PrimaryFont = new w.FontFaceObserver( "NotoSans", {
7         weight: 400
8     });
9
10     PrimaryFont.load(null, 5000).then(function(){
11         w.document.documentElement.className += " fonts-loaded";
12     }, function(){
13         console.log("Failed");
14     });
15 }( this ));
16
17 // http://stackoverflow.com/questions/1038746/equivalent-of-string-format-in-jquery/5341855#5341855
18 String.prototype.format = function() { return formatstr(this, arguments) }
19 function formatstr(str, col) {
20     col = typeof col === 'object' ? col : Array.prototype.slice.call(arguments, 1);
21     var idx = 0;
22     return str.replace(/%%|%s|%(\d+)\$s/g, function (m, n) {
23         if (m == "%%") { return "%"; }
24         if (m == "%s") { return col[idx++]; }
25         return col[n];
26     });
27 };
28
29 function confirmDelete(message) {
30     return (confirm(message) ? true : false);
31 }
32
33 function Dopop(link) {
34     newin=window.open(link,'popup','width=500,height=400,toolbar=false,scrollbars=yes,resizable=yes');
35 }
36
37 jQuery.fn.preventDoubleFormSubmit = function() {
38     jQuery(this).submit(function() {
39         if (this.beenSubmitted)
40             return false;
41         else
42             this.beenSubmitted = true;
43     });
44 };
45
46 function prefixOf (s, tok) {
47     var index = s.indexOf(tok);
48     return s.substring(0, index);
49 }
50 function suffixOf (s, tok) {
51     var index = s.indexOf(tok);
52     return s.substring(index + 1);
53 }
54
55 $("body").on("keypress", ".noEnterSubmit", function(e){
56     return checkEnter(e);
57 });
58
59 // http://jennifermadden.com/javascript/stringEnterKeyDetector.html
60 function checkEnter(e){ //e is event object passed from function invocation
61     var characterCode; // literal character code will be stored in this variable
62     if(e && e.which){ //if which property of event object is supported (NN4)
63         characterCode = e.which; //character code is contained in NN4's which property
64     } else {
65         characterCode = e.keyCode; //character code is contained in IE's keyCode property
66     }
67     if( characterCode == 13 //if generated character code is equal to ascii 13 (if enter key)
68         && e.target.nodeName == "INPUT"
69         && e.target.type != "submit" // Allow enter to submit using the submit button
70     ){
71         return false;
72     } else {
73         return true;
74     }
75 }
76
77 // Adapted from https://gist.github.com/jnormore/7418776
78 function confirmModal(message, title, yes_label, no_label, callback) {
79     $("#bootstrap-confirm-box-modal").data('confirm-yes', false);
80     if($("#bootstrap-confirm-box-modal").length == 0) {
81         $("body").append('<div id="bootstrap-confirm-box-modal" tabindex="-1" role="dialog" aria-hidden="true" class="modal">\
82             <div class="modal-dialog">\
83                 <div class="modal-content">\
84                     <div class="modal-header" style="min-height:40px;">\
85                         <h4 class="modal-title"></h4>\
86                         <button type="button" class="closebtn" data-dismiss="modal" aria-label="Close">\
87                         <span aria-hidden="true">×</span>\
88                     </button>\
89                     </div>\
90                     <div class="modal-body"><p></p></div>\
91                     <div class="modal-footer">\
92                         <a href="#" id="bootstrap-confirm-box-modal-submit" class="btn btn-danger"><i class="fa fa-check" aria-hidden="true"></i></a>\
93                         <a href="#" id="bootstrap-confirm-box-modal-cancel" data-dismiss="modal" class="btn btn-default"><i class="fa fa-remove" aria-hidden="true"></i></a>\
94                     </div>\
95                 </div>\
96             </div>\
97         </div>');
98         $("#bootstrap-confirm-box-modal-submit").on('click', function () {
99             $("#bootstrap-confirm-box-modal").data('confirm-yes', true);
100             $("#bootstrap-confirm-box-modal").modal('hide');
101             return false;
102         });
103         $("#bootstrap-confirm-box-modal").on('hide.bs.modal', function () {
104             if(callback) callback($("#bootstrap-confirm-box-modal").data('confirm-yes'));
105         });
106     }
107
108     $("#bootstrap-confirm-box-modal .modal-header h4").text( title || "" );
109     if( message && message != "" ){
110         $("#bootstrap-confirm-box-modal .modal-body").html( message || "" );
111     } else {
112         $("#bootstrap-confirm-box-modal .modal-body").remove();
113     }
114     $("#bootstrap-confirm-box-modal-submit").text( yes_label || 'Confirm' );
115     $("#bootstrap-confirm-box-modal-cancel").text( no_label || 'Cancel' );
116     $("#bootstrap-confirm-box-modal").modal('show');
117 }
118
119 //Add jQuery :focusable selector
120 (function($) {
121     function visible(element) {
122         return $.expr.filters.visible(element) && !$(element).parents().addBack().filter(function() {
123             return $.css(this, 'visibility') === 'hidden';
124         }).length;
125     }
126
127     function focusable(element, isTabIndexNotNaN) {
128         var map, mapName, img, nodeName = element.nodeName.toLowerCase();
129         if ('area' === nodeName) {
130             map = element.parentNode;
131             mapName = map.name;
132             if (!element.href || !mapName || map.nodeName.toLowerCase() !== 'map') {
133                 return false;
134             }
135             img = $('img[usemap=#' + mapName + ']')[0];
136             return !!img && visible(img);
137         }
138         return (/input|select|textarea|button|object/.test(nodeName) ?
139                 !element.disabled :
140                 'a' === nodeName ?
141                 element.href || isTabIndexNotNaN :
142                 isTabIndexNotNaN) &&
143             // the element and all of its ancestors must be visible
144             visible(element);
145     }
146
147     $.extend($.expr[':'], {
148         focusable: function(element) {
149             return focusable(element, !isNaN($.attr(element, 'tabindex')));
150         }
151     });
152 })(jQuery);
153
154 $("#scrolltocontent").click(function() {
155     var content = $(".maincontent");
156     if (content.length > 0) {
157         $('html,body').animate({
158                 scrollTop: content.first().offset().top
159             },
160         'slow');
161         content.first().find(':focusable').eq(0).focus();
162     }
163 });