PageSourceSearch

https://katalog.knihovnaberoun.cz/themes/bootstrap3/js/lightbox.js?_=1461344400

js knihovnaberoun.cz collected 2026-10-05 01:28:24 UTC 15,823 bytes, 432 lines download raw bytes

1/*global checkSaveStatuses, console, deparam, path, Recaptcha, vufindString */
2
3var Lightbox = {
4  /**
5   * We save the URL and POST data every time we call getByUrl.
6   * If we don't have a target a form submission, we use these variables
7   * to replicate empty target behaviour by submitting to the current "page".
8   */
9  lastURL: false,
10  lastPOST: false,
11  openingURL: false,
12  shown: false,      // Is the lightbox deployed?
13  XHR: false,        // Used for current in-progress XHR lightbox request
14  openStack: [],     // Array of functions to be called after changeContent or the lightbox event 'shown'
15  closeStack: [],    // Array of functions to be called and cleared after the lightbox event 'hidden'
16  formHandlers: [],  // Full custom handlers for forms; by name
17  formCallbacks: [], // Custom functions for forms, called after .submit(); by name
18
19  /**********************************/
20  /* ======    INTERFACE     ====== */
21  /**********************************/
22  /**
23   * Register custom open event handlers
24   *
25   * Think of this as the $(document).ready() of the Lightbox
26   * There's actually an alias right below it.
27   *
28   * If your template has inline JS, $(document).ready() will not fire in the lightbox
29   * because it already fired before you opened the lightbox and won't fire again.
30   *
31   * You can use $.isReady to determine if ready() has already been called
32   * so you can trigger your function immediately in the inline JS.
33   */
34  addOpenAction: function(func) {
35    this.openStack.push(func);
36  },
37  // Alias for addOpenAction
38  ready: function(func) {
39    this.openStack.push(func);
40  },
41  /**
42   * Register custom close event handlers
43   */
44  addCloseAction: function(func) {
45    this.closeStack.push(func);
46  },
47  /**
48   * For when you want to handle that form all by yourself
49   *
50   * We recommend using the getLightbox action in the AJAX Controller
51   * to ensure you get a lightbox formatted page.
52   *
53   * If your handler doesn't return false, the form will submit the normal way,
54   * with all normal behavior that goes with: redirection, etc.
55   */
56  addFormHandler: function(formName, func) {
57    this.formHandlers[formName] = func;
58  },
59  /**
60   * Register a function to be called when a form submission succeeds
61   *
62   * We add error checking by default, you never know when error blocks will strike.
63   * Passing false to expectsError turns this off. Errors are inserted above *current* content.
64   */
65  addFormCallback: function(formName, func, expectsError) {
66    if(typeof expectsError === "undefined" || expectsError) {
67      this.formCallbacks[formName] = function(html) {
68        Lightbox.checkForError(html, func);
69      };
70    } else {
71      this.formCallbacks[formName] = func;
72    }
73  },
74  /**
75   * We store all the ajax calls in case we need to cancel.
76   * This function cancels the previous call and creates a new one.
77   */
78  ajax: function(obj) {
79    if(this.XHR) {
80      this.XHR.abort();
81    }
82    this.XHR = $.ajax(obj);
83  },
84  /**********************************/
85  /* ====== LIGHTBOX ACTIONS ====== */
86  /**********************************/
87  /**
88   * Change the content of the lightbox.
89   *
90   * Hide the header if it's empty to make more
91   * room for content and avoid double headers.
92   */
93  titleSet: false,
94  changeContent: function(html) {
95    var header = $('#modal .modal-header');
96    if(!Lightbox.titleSet) {
97      var h2 = html.match(/<h2>([^<]*)<\/h2>/);
98      if(h2) {
99        header.find('.modal-title').html(h2[1]);
100      } else {
101        var pLead = html.match(/<p class="lead[^>]*>([^<]*)<\/p>/);
102        if(pLead) {
103          header.find('.modal-title').html(pLead[1]);
104        }
105      }
106      Lightbox.titleSet = false;
107    }
108    if(header.find('.modal-title').html().length == 0) {
109      header.css('border-bottom-width', '0');
110    } else {
111      header.css('border-bottom-width', '1px');
112    }
113    $('#modal .modal-body').html(html).modal({'show':true,'backdrop':false});
114    Lightbox.openActions();
115  },
116
117  /**
118   * This is the function you call to manually close the lightbox
119   */
120  close: function(evt) {
121    $('#modal').modal('hide'); // This event calls closeActions
122  },
123  /**
124   * This function is attached to the lightbox close event,
125   * so it always runs when the lightbox is closed.
126   */
127  closeActions: function() {
128    Lightbox.shown = false;
129    Lightbox.openingURL = false;
130    // Clean out stack
131    while(Lightbox.closeStack.length > 0) {
132      var f = Lightbox.closeStack.pop();
133      f();
134    }
135    if(this.XHR) { this.XHR.abort(); }
136    // Reset content so we start fresh when we open a lightbox
137    $('#modal').removeData('modal');
138    $('#modal').find('.modal-title').html('&nbsp;');
139    $('#modal').find('.modal-body').html(vufindString.loading + "...");
140  },
141  /**
142   * Call all the functions we need for when the modal loads
143   *
144   * Called by the 'shown' event and at the end of changeContent
145   */
146  openActions: function() {
147    for(var i=0;i<Lightbox.openStack.length;i++) {
148      Lightbox.openStack[i]();
149    }
150  },
151  /**
152   * This function changes the content of the lightbox to a message with a close button
153   */
154  confirm: function(message) {
155    this.changeContent('<div class="alert alert-info">'+message+'</div><button class="btn btn-default" onClick="Lightbox.close()">'+vufindString['close']+'</button>');
156  },
157  success: function(message) {
158    this.changeContent('<div class="alert alert-success">'+message+'</div><button class="btn btn-default" onClick="Lightbox.close()">'+vufindString['close']+'</button>');
159  },
160  /**
161   * Regexes a piece of html to find an error alert
162   * If one is found, display it
163   *
164   * If one is not found, return html to a success callback function
165   */
166  checkForError: function(html, success, type) {
167    if(typeof type === "undefined") {
168      type = "danger";
169    }
170    var divPattern = '<div class="alert alert-'+type+'">';
171    var fi = html.indexOf(divPattern);
172    if(fi > -1) {
173      var li = html.indexOf('</div>', fi+divPattern.length);
174      Lightbox.displayError(html.substring(fi+divPattern.length, li).replace(/^[\s<>]+|[\s<>]+$/g, ''), type);
175    } else {
176      success(html);
177    }
178  },
179  /**
180   * Insert an error alert element at the top of the lightbox
181   */
182  displayError: function(message, type) {
183    if(typeof type === "undefined") {
184      type = "danger";
185    }
186    $('#modal .modal-body .alert').remove();
187    var html = $.parseHTML($('#modal .modal-body').html());
188     // Empty or alert only, change to message with button
189    if($('#modal .modal-body').html() == vufindString.loading+"..."
190      || (html.length == 1 && $(html).hasClass('alert-'+type))) {
191      Lightbox.changeContent('<div class="alert alert-'+type+'" role="alert">'+message+'</div><button class="btn btn-default" onClick="Lightbox.close()">'+vufindString['close']+'</button>');
192    // Page without alert
193    } else {
194      $('#modal .modal-body').prepend('<div class="alert alert-'+type+' alert-dismissible" role="alert"><button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button><p class="message">'+message+'</p></div>');
195    }
196    $('.fa-spinner').remove();
197    if (typeof Recaptcha !== "undefined" && Recaptcha.widget) {
198      Recaptcha.reload();
199    }
200    // If the lightbox isn't visible, fix that
201    if(this.shown == false) {
202      $('#modal').modal('show');
203      this.shown = true;
204    }
205  },
206
207  /***********************************/
208  /* ====== LIGHTBOX REQUESTS ====== */
209  /***********************************/
210  /**
211   * This function creates an XHR request to the URL
212   * and handles the response according to the callback.
213   *
214   * Default callback is changeContent
215   */
216  getByUrl: function(url, post, callback) {
217    if(typeof callback == "undefined") {
218      // No custom handler: display return in lightbox
219      callback = this.changeContent;
220    }
221    // If the lightbox isn't visible, fix that
222    if(this.shown == false) {
223      $('#modal').modal('show');
224      this.shown = true;
225    }
226    // Create our AJAX request, store it in case we need to cancel later
227    this.ajax({
228      type:'POST',
229      url:url,
230      data:post,
231      success:function(html) { // Success!
232        callback(html);
233      },
234      error:function(d,e) {
235        if (d.status == 200) {
236          try {
237            var data = JSON.parse(d.responseText);
238            Lightbox.changeContent('<p class="alert alert-danger">'+data.data+'</p>');
239          } catch(error) {
240            Lightbox.changeContent('<p class="alert alert-danger">'+d.responseText+'</p>');
241          }
242        } else if(d.status > 0) {
243          Lightbox.changeContent('<p class="alert alert-danger">'+d.statusText+' ('+d.status+')</p>');
244        }
245        console.log(e,d); // Error reporting
246        console.log(url,post);
247      }
248    });
249    // Store current "page" context for empty targets
250    if(this.openingURL === false) {
251      this.openingURL = url;
252    }
253    this.lastURL = url;
254    this.lastPOST = post;
255    //this.openActions();
256    return false;
257  },
258  /**
259   * This is the friendly face to the function above.
260   * It converts a Controller and Action into a URL through the AJAX handler
261   * with GET and pushes the data and callback to the getByUrl
262   */
263  get: function(controller, action, get, post, callback) {
264    // Build URL
265    var url = path+'/AJAX/JSON?method=getLightbox&submodule='+controller+'&subaction='+action;
266    if(typeof get !== "undefined" && get !== {}) {
267      url += '&'+$.param(get);
268    }
269    if(typeof post == "undefined") {
270      post = {};
271    }
272    return this.getByUrl(url, post, callback);
273  },
274
275  /**********************************/
276  /* ====== FORM SUBMISSIONS ====== */
277  /**********************************/
278  /**
279   * Returns all the input values from a form as an associated array
280   *
281   * This function takes a jQuery wrapped form
282   * $(event.target) for example
283   */
284  getFormData: function($form) {
285    // Gather all the data
286    var inputs = $form.find('*[name]');
287    var data = {};
288    for(var i=0;i<inputs.length;i++) {
289      var currentName = inputs[i].name;
290      var array = currentName.substring(currentName.length-2) == '[]';
291      if(array && !data[currentName.substring(0,currentName.length-2)]) {
292        data[currentName.substring(0,currentName.length-2)] = [];
293      }
294      // Submit buttons
295      if(inputs[i].type == 'submit') {
296        if($(inputs[i]).attr('clicked') == 'true') {
297          data[currentName] = inputs[i].value;
298        }
299      // Radio buttons
300      } else if(inputs[i].type == 'radio') {
301        if(inputs[i].checked) {
302          if(array) {
303            var n = currentName.substring(0,currentName.length-2);
304            data[n].push(inputs[i].value);
305          } else {
306            data[currentName] = inputs[i].value;
307          }
308        }
309      // Checkboxes
310      } else if($(inputs[i]).attr('type') != 'checkbox' || inputs[i].checked) {
311        if(array) {
312          var f = currentName.substring(0,currentName.length-2);
313          data[f].push(inputs[i].value);
314        } else {
315          data[currentName] = inputs[i].value;
316        }
317      }
318    }
319    return data;
320  },
321  /**
322   * This function adds submission events to forms loaded inside the lightbox
323   *
324   * First, it will check for custom handlers, for those who want to handle everything.
325   *
326   * Then, it will check for custom form callbacks. These will be added to an anonymous
327   * function that will call Lightbox.submit with the form and the callback.
328   *
329   * Finally, if nothing custom is setup, it will add the default function which
330   * calls Lightbox.submit with a callback to close if there are no errors to display.
331   *
332   * This is a default open action, so it runs every time changeContent
333   * is called and the 'shown' lightbox event is triggered
334   */
335  registerForms: function() {
336    var $form = $("#modal").find('form');
337    $form.validator();
338    var name = $form.attr('name');
339    // Assign form handler based on name
340    if(typeof name !== "undefined" && typeof Lightbox.formHandlers[name] !== "undefined") {
341      $form.submit(Lightbox.formHandlers[name]);
342    // Default action, with custom callback
343    } else if(typeof Lightbox.formCallbacks[name] !== "undefined") {
344      $form.submit(function(evt){
345        if(evt.isDefaultPrevented()) {
346          $('.fa.fa-spinner', evt.target).remove();
347          return false;
348        }
349        Lightbox.submit($(evt.target), Lightbox.formCallbacks[name]);
350        return false;
351      });
352    // Default
353    } else {
354      $form.unbind('submit').submit(function(evt){
355        if(evt.isDefaultPrevented()) {
356          $('.fa.fa-spinner', evt.target).remove();
357          return false;
358        }
359        Lightbox.submit($(evt.target), function(html){
360          Lightbox.checkForError(html, Lightbox.close);
361        });
362        return false;
363      });
364    }
365  },
366  /**
367   * The default, automatic form submission
368   *
369   * This function gleans all the information in a form from the function above
370   * Then it uses the action="..." attribute of the form to figure out where to send the data
371   * and the method="" attribute to send it the proper way
372   *
373   * Forms without an action="..." are submitted to the current URL.
374   * In the case where we have a form with no action in the lightbox,
375   * we emulate that behaviour by submitting the last URL loaded through
376   * .getByUrl, stored in lastURL in the Lightbox object.
377   */
378  submit: function($form, callback) {
379    // Default callback is to close
380    if(typeof callback == "undefined") {
381      callback = this.close;
382    }
383    var data = this.getFormData($form);
384    // If we have an action: parse
385    var POST = $form.attr('method') && $form.attr('method').toUpperCase() == 'POST';
386    if($form.attr('action')) {
387      // Parse action location
388      var action = $form.attr('action').substring($form.attr('action').indexOf(path)+path.length+1);
389      var params = action.split('?');
390      action = action.split('/');
391      var get = params.length > 1 ? deparam(params[1]) : data['id'] ? {id:data['id']} : {};
392      if(POST) {
393        this.get(action[0], action[action.length-1], get, data, callback);
394      } else {
395        this.get(action[0], action[action.length-1], data, {}, callback);
396      }
397    // If not: fake context by using the previous action
398    } else if(POST) {
399      this.getByUrl(this.lastURL, data, callback);
400    } else {
401      this.getByUrl(this.lastURL, {}, callback);
402    }
403    $(this).find('.modal-body').html(vufindString.loading + "...");
404  }
405};
406
407/**
408 * This is where you add click events to open the lightbox.
409 * We do it here so that non-JS users still have a good time.
410 */
411$(document).ready(function() {
412  // Add handlers to the forms
413  Lightbox.addOpenAction(Lightbox.registerForms);
414  /**
415   * Hook into the Bootstrap close event
416   *
417   * Yes, the secret's out, our beloved Lightbox is a modal
418   */
419  $('#modal').on('hidden.bs.modal', Lightbox.closeActions);
420  /**
421   * If a link with the class .modal-link triggers the lightbox,
422   * look for a title attribute to use as our lightbox title.
423   */
424  $('.modal-link,.help-link').click(function() {
425    var title = $(this).attr('title');
426    if(typeof title === "undefined") {
427      title = $(this).html();
428    }
429    $('#modal .modal-title').html(title);
430    Lightbox.titleSet = true;
431  });
432});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.