diff --git a/themes/bootstrap3/js/lightbox.js b/themes/bootstrap3/js/lightbox.js
index 4037500959fa6ca39dc020e0e9cfe77db9e489b0..b71b23ee9d2232f85909e2dde2c14f4912176dcc 100644
--- a/themes/bootstrap3/js/lightbox.js
+++ b/themes/bootstrap3/js/lightbox.js
@@ -1,411 +1,411 @@
-/*global checkSaveStatuses, console, deparam, path, Recaptcha, vufindString */
-
-var Lightbox = {
-  /**
-   * We save the URL and POST data every time we call getByUrl.
-   * If we don't have a target a form submission, we use these variables
-   * to replicate empty target behaviour by submitting to the current "page".
-   */
-  lastURL: false,
-  lastPOST: false,
-  openingURL: false,
-  shown: false,      // Is the lightbox deployed?
-  XHR: false,        // Used for current in-progress XHR lightbox request
-  openStack: [],     // Array of functions to be called after changeContent or the lightbox event 'shown'
-  closeStack: [],    // Array of functions to be called and cleared after the lightbox event 'hidden'
-  formHandlers: [],  // Full custom handlers for forms; by name
-  formCallbacks: [], // Custom functions for forms, called after .submit(); by name
-
-  /**********************************/
-  /* ======    INTERFACE     ====== */
-  /**********************************/
-  /**
-   * Register custom open event handlers
-   *
-   * Think of this as the $(document).ready() of the Lightbox
-   * There's actually an alias right below it.
-   *
-   * If your template has inline JS, $(document).ready() will not fire in the lightbox
-   * because it already fired before you opened the lightbox and won't fire again.
-   *
-   * You can use $.isReady to determine if ready() has already been called
-   * so you can trigger your function immediately in the inline JS.
-   */
-  addOpenAction: function(func) {
-    this.openStack.push(func);
-  },
-  // Alias for addOpenAction
-  ready: function(func) {
-    this.openStack.push(func);
-  },
-  /**
-   * Register custom close event handlers
-   */
-  addCloseAction: function(func) {
-    this.closeStack.push(func);
-  },
-  /**
-   * For when you want to handle that form all by yourself
-   *
-   * We recommend using the getLightbox action in the AJAX Controller
-   * to ensure you get a lightbox formatted page.
-   *
-   * If your handler doesn't return false, the form will submit the normal way,
-   * with all normal behavior that goes with: redirection, etc.
-   */
-  addFormHandler: function(formName, func) {
-    this.formHandlers[formName] = func;
-  },
-  /**
-   * Register a function to be called when a form submission succeeds
-   *
-   * We add error checking by default, you never know when error blocks will strike.
-   * Passing false to expectsError turns this off. Errors are inserted above *current* content.
-   */
-  addFormCallback: function(formName, func, expectsError) {
-    if(typeof expectsError === "undefined" || expectsError) {
-      this.formCallbacks[formName] = function(html) {
-        Lightbox.checkForError(html, func);
-      };
-    } else {
-      this.formCallbacks[formName] = func;
-    }
-  },
-  /**
-   * We store all the ajax calls in case we need to cancel.
-   * This function cancels the previous call and creates a new one.
-   */
-  ajax: function(obj) {
-    if(this.XHR) {
-      this.XHR.abort();
-    }
-    this.XHR = $.ajax(obj);
-  },
-  /**********************************/
-  /* ====== LIGHTBOX ACTIONS ====== */
-  /**********************************/
-  /**
-   * Change the content of the lightbox.
-   *
-   * Hide the header if it's empty to make more
-   * room for content and avoid double headers.
-   */
-  titleSet: false,
-  changeContent: function(html) {
-    var header = $('#modal .modal-header');
-    if(!Lightbox.titleSet) {
-      var h2 = html.match(/<h2>([^<]*)<\/h2>/);
-      if(h2) {
-        header.find('.modal-title').html(h2[1]);
-      } else {
-        var pLead = html.match(/<p class="lead[^>]*>([^<]*)<\/p>/);
-        if(pLead) {
-          header.find('.modal-title').html(pLead[1]);
-        }
-      }
-      Lightbox.titleSet = false;
-    }
-    if(header.find('.modal-title').html().length == 0) {
-      header.css('border-bottom-width', '0');
-    } else {
-      header.css('border-bottom-width', '1px');
-    }
-    $('#modal .modal-body').html(html).modal({'show':true,'backdrop':false});
-    Lightbox.openActions();
-  },
-
-  /**
-   * This is the function you call to manually close the lightbox
-   */
-  close: function(evt) {
-    $('#modal').modal('hide'); // This event calls closeActions
-  },
-  /**
-   * This function is attached to the lightbox close event,
-   * so it always runs when the lightbox is closed.
-   */
-  closeActions: function() {
-    Lightbox.shown = false;
-    Lightbox.openingURL = false;
-    // Clean out stack
-    while(Lightbox.closeStack.length > 0) {
-      var f = Lightbox.closeStack.pop();
-      f();
-    }
-    if(this.XHR) { this.XHR.abort(); }
-    // Reset content so we start fresh when we open a lightbox
-    $('#modal').removeData('modal');
-    $('#modal').find('.modal-title').html('');
-    $('#modal').find('.modal-body').html(vufindString.loading + "...");
-  },
-  /**
-   * Call all the functions we need for when the modal loads
-   *
-   * Called by the 'shown' event and at the end of changeContent
-   */
-  openActions: function() {
-    for(var i=0;i<Lightbox.openStack.length;i++) {
-      Lightbox.openStack[i]();
-    }
-  },
-  /**
-   * This function changes the content of the lightbox to a message with a close button
-   */
-  confirm: function(message) {
-    this.changeContent('<div class="alert alert-info">'+message+'</div><button class="btn btn-default" onClick="Lightbox.close()">'+vufindString['close']+'</button>');
-  },
-  /**
-   * Regexes a piece of html to find an error alert
-   * If one is found, display it
-   *
-   * If one is not found, return html to a success callback function
-   */
-  checkForError: function(html, success) {
-    var fi = html.indexOf('<div class="alert alert-danger">');
-    if(fi > -1) {
-      var li = html.indexOf('</div>', fi+31);
-      Lightbox.displayError(html.substring(fi+31, li).replace(/^[\s<>]+|[\s<>]+$/g, ''));
-    } else {
-      success(html);
-    }
-  },
-  /**
-   * Insert an error alert element at the top of the lightbox
-   */
-  displayError: function(message) {
-    var alert = $('#modal .modal-body .alert');
-    var html = $.parseHTML($('#modal .modal-body').html());
-    // Page with alert already present
-    if(alert.length > 0 && html.length > 1) {
-      $(alert).html(message);
-    // Empty or alert only, change to message with button
-    } else if($('#modal .modal-body').html() == vufindString.loading+"..."
-    || (html.length == 1 && $(html).hasClass('alert-danger'))) {
-      Lightbox.changeContent('<div class="alert alert-danger">'+message+'</div><button class="btn btn-default" onClick="Lightbox.close()">'+vufindString['close']+'</button>');
-    // Page without alert
-    } else {
-      $('#modal .modal-body').prepend('<div class="alert alert-danger">'+message+'</div>');
-    }
-    $('.fa-spinner').remove();
-    if (typeof Recaptcha !== "undefined" && Recaptcha.widget) {
-      Recaptcha.reload();
-    }
-  },
-
-  /***********************************/
-  /* ====== LIGHTBOX REQUESTS ====== */
-  /***********************************/
-  /**
-   * This function creates an XHR request to the URL
-   * and handles the response according to the callback.
-   *
-   * Default callback is changeContent
-   */
-  getByUrl: function(url, post, callback) {
-    if(typeof callback == "undefined") {
-      // No custom handler: display return in lightbox
-      callback = this.changeContent;
-    }
-    // If the lightbox isn't visible, fix that
-    if(this.shown == false) {
-      $('#modal').modal('show');
-      this.shown = true;
-    }
-    // Create our AJAX request, store it in case we need to cancel later
-    this.ajax({
-      type:'POST',
-      url:url,
-      data:post,
-      success:function(html) { // Success!
-        callback(html);
-      },
-      error:function(d,e) {
-        if (d.status == 200) {
-          try {
-            var data = JSON.parse(d.responseText);
-            Lightbox.changeContent('<p class="alert alert-danger">'+data.data+'</p>');
-          } catch(error) {
-            Lightbox.changeContent('<p class="alert alert-danger">'+d.responseText+'</p>');
-          }
-        } else if(d.status > 0) {
-          Lightbox.changeContent('<p class="alert alert-danger">'+d.statusText+' ('+d.status+')</p>');
-        }
-        console.log(e,d); // Error reporting
-        console.log(url,post);
-      }
-    });
-    // Store current "page" context for empty targets
-    if(this.openingURL === false) {
-      this.openingURL = url;
-    }
-    this.lastURL = url;
-    this.lastPOST = post;
-    //this.openActions();
-    return false;
-  },
-  /**
-   * This is the friendly face to the function above.
-   * It converts a Controller and Action into a URL through the AJAX handler
-   * with GET and pushes the data and callback to the getByUrl
-   */
-  get: function(controller, action, get, post, callback) {
-    // Build URL
-    var url = path+'/AJAX/JSON?method=getLightbox&submodule='+controller+'&subaction='+action;
-    if(typeof get !== "undefined" && get !== {}) {
-      url += '&'+$.param(get);
-    }
-    if(typeof post == "undefined") {
-      post = {};
-    }
-    return this.getByUrl(url, post, callback);
-  },
-
-  /**********************************/
-  /* ====== FORM SUBMISSIONS ====== */
-  /**********************************/
-  /**
-   * Returns all the input values from a form as an associated array
-   *
-   * This function takes a jQuery wrapped form
-   * $(event.target) for example
-   */
-  getFormData: function($form) {
-    // Gather all the data
-    var inputs = $form.find('*[name]');
-    var data = {};
-    for(var i=0;i<inputs.length;i++) {
-      var currentName = inputs[i].name;
-      var array = currentName.substring(currentName.length-2) == '[]';
-      if(array && !data[currentName.substring(0,currentName.length-2)]) {
-        data[currentName.substring(0,currentName.length-2)] = [];
-      }
-      // Submit buttons
-      if(inputs[i].type == 'submit') {
-        if($(inputs[i]).attr('clicked') == 'true') {
-          data[currentName] = inputs[i].value;
-        }
-      // Radio buttons
-      } else if(inputs[i].type == 'radio') {
-        if(inputs[i].checked) {
-          if(array) {
-            var n = currentName.substring(0,currentName.length-2);
-            data[n].push(inputs[i].value);
-          } else {
-            data[currentName] = inputs[i].value;
-          }
-        }
-      // Checkboxes
-      } else if($(inputs[i]).attr('type') != 'checkbox' || inputs[i].checked) {
-        if(array) {
-          var f = currentName.substring(0,currentName.length-2);
-          data[f].push(inputs[i].value);
-        } else {
-          data[currentName] = inputs[i].value;
-        }
-      }
-    }
-    return data;
-  },
-  /**
-   * This function adds submission events to forms loaded inside the lightbox
-   *
-   * First, it will check for custom handlers, for those who want to handle everything.
-   *
-   * Then, it will check for custom form callbacks. These will be added to an anonymous
-   * function that will call Lightbox.submit with the form and the callback.
-   *
-   * Finally, if nothing custom is setup, it will add the default function which
-   * calls Lightbox.submit with a callback to close if there are no errors to display.
-   *
-   * This is a default open action, so it runs every time changeContent
-   * is called and the 'shown' lightbox event is triggered
-   */
-  registerForms: function() {
-    var form = $("#modal").find('form');
-    var name = $(form).attr('name');
-    // Assign form handler based on name
-    if(typeof name !== "undefined" && typeof Lightbox.formHandlers[name] !== "undefined") {
-      $(form).unbind('submit').submit(Lightbox.formHandlers[name]);
-    // Default action, with custom callback
-    } else if(typeof Lightbox.formCallbacks[name] !== "undefined") {
-      $(form).unbind('submit').submit(function(evt){
-        Lightbox.submit($(evt.target), Lightbox.formCallbacks[name]);
-        return false;
-      });
-    // Default
-    } else {
-      $(form).unbind('submit').submit(function(evt){
-        Lightbox.submit($(evt.target), function(html){
-          Lightbox.checkForError(html, Lightbox.close);
-        });
-        return false;
-      });
-    }
-  },
-  /**
-   * The default, automatic form submission
-   *
-   * This function gleans all the information in a form from the function above
-   * Then it uses the action="" attribute of the form to figure out where to send the data
-   * and the method="" attribute to send it the proper way
-   *
-   * In the wild, forms without an action="" are submitted to the current URL.
-   * In the case where we have a form with no action in the lightbox,
-   * we emulate that behaviour by submitting the last URL loaded through
-   * .getByUrl, stored in lastURL in the Lightbox object.
-   */
-  submit: function($form, callback) {
-    // Default callback is to close
-    if(typeof callback == "undefined") {
-      callback = this.close;
-    }
-    var data = this.getFormData($form);
-    // If we have an action: parse
-    var POST = $form.attr('method') && $form.attr('method').toUpperCase() == 'POST';
-    if($form.attr('action')) {
-      // Parse action location
-      var action = $form.attr('action').substring($form.attr('action').indexOf(path)+path.length+1);
-      var params = action.split('?');
-      action = action.split('/');
-      var get = params.length > 1 ? deparam(params[1]) : data['id'] ? {id:data['id']} : {};
-      if(POST) {
-        this.get(action[0], action[action.length-1], get, data, callback);
-      } else {
-        this.get(action[0], action[action.length-1], data, {}, callback);
-      }
-    // If not: fake context by using the previous action
-    } else if(POST) {
-      this.getByUrl(this.lastURL, data, callback);
-    } else {
-      this.getByUrl(this.lastURL, {}, callback);
-    }
-    $(this).find('.modal-body').html(vufindString.loading + "...");
-  }
-};
-
-/**
- * This is where you add click events to open the lightbox.
- * We do it here so that non-JS users still have a good time.
- */
-$(document).ready(function() {
-  // Add handlers to the forms
-  Lightbox.addOpenAction(Lightbox.registerForms);
-  /**
-   * Hook into the Bootstrap close event
-   *
-   * Yes, the secret's out, our beloved Lightbox is a modal
-   */
-  $('#modal').on('hidden.bs.modal', Lightbox.closeActions);
-  /**
-   * If a link with the class .modal-link triggers the lightbox,
-   * look for a title="" to use as our lightbox title.
-   */
-  $('.modal-link,.help-link').click(function() {
-    var title = $(this).attr('title');
-    if(typeof title === "undefined") {
-      title = $(this).html();
-    }
-    $('#modal .modal-title').html(title);
-    Lightbox.titleSet = true;
-  });
+/*global checkSaveStatuses, console, deparam, path, Recaptcha, vufindString */
+
+var Lightbox = {
+  /**
+   * We save the URL and POST data every time we call getByUrl.
+   * If we don't have a target a form submission, we use these variables
+   * to replicate empty target behaviour by submitting to the current "page".
+   */
+  lastURL: false,
+  lastPOST: false,
+  openingURL: false,
+  shown: false,      // Is the lightbox deployed?
+  XHR: false,        // Used for current in-progress XHR lightbox request
+  openStack: [],     // Array of functions to be called after changeContent or the lightbox event 'shown'
+  closeStack: [],    // Array of functions to be called and cleared after the lightbox event 'hidden'
+  formHandlers: [],  // Full custom handlers for forms; by name
+  formCallbacks: [], // Custom functions for forms, called after .submit(); by name
+
+  /**********************************/
+  /* ======    INTERFACE     ====== */
+  /**********************************/
+  /**
+   * Register custom open event handlers
+   *
+   * Think of this as the $(document).ready() of the Lightbox
+   * There's actually an alias right below it.
+   *
+   * If your template has inline JS, $(document).ready() will not fire in the lightbox
+   * because it already fired before you opened the lightbox and won't fire again.
+   *
+   * You can use $.isReady to determine if ready() has already been called
+   * so you can trigger your function immediately in the inline JS.
+   */
+  addOpenAction: function(func) {
+    this.openStack.push(func);
+  },
+  // Alias for addOpenAction
+  ready: function(func) {
+    this.openStack.push(func);
+  },
+  /**
+   * Register custom close event handlers
+   */
+  addCloseAction: function(func) {
+    this.closeStack.push(func);
+  },
+  /**
+   * For when you want to handle that form all by yourself
+   *
+   * We recommend using the getLightbox action in the AJAX Controller
+   * to ensure you get a lightbox formatted page.
+   *
+   * If your handler doesn't return false, the form will submit the normal way,
+   * with all normal behavior that goes with: redirection, etc.
+   */
+  addFormHandler: function(formName, func) {
+    this.formHandlers[formName] = func;
+  },
+  /**
+   * Register a function to be called when a form submission succeeds
+   *
+   * We add error checking by default, you never know when error blocks will strike.
+   * Passing false to expectsError turns this off. Errors are inserted above *current* content.
+   */
+  addFormCallback: function(formName, func, expectsError) {
+    if(typeof expectsError === "undefined" || expectsError) {
+      this.formCallbacks[formName] = function(html) {
+        Lightbox.checkForError(html, func);
+      };
+    } else {
+      this.formCallbacks[formName] = func;
+    }
+  },
+  /**
+   * We store all the ajax calls in case we need to cancel.
+   * This function cancels the previous call and creates a new one.
+   */
+  ajax: function(obj) {
+    if(this.XHR) {
+      this.XHR.abort();
+    }
+    this.XHR = $.ajax(obj);
+  },
+  /**********************************/
+  /* ====== LIGHTBOX ACTIONS ====== */
+  /**********************************/
+  /**
+   * Change the content of the lightbox.
+   *
+   * Hide the header if it's empty to make more
+   * room for content and avoid double headers.
+   */
+  titleSet: false,
+  changeContent: function(html) {
+    var header = $('#modal .modal-header');
+    if(!Lightbox.titleSet) {
+      var h2 = html.match(/<h2>([^<]*)<\/h2>/);
+      if(h2) {
+        header.find('.modal-title').html(h2[1]);
+      } else {
+        var pLead = html.match(/<p class="lead[^>]*>([^<]*)<\/p>/);
+        if(pLead) {
+          header.find('.modal-title').html(pLead[1]);
+        }
+      }
+      Lightbox.titleSet = false;
+    }
+    if(header.find('.modal-title').html().length == 0) {
+      header.css('border-bottom-width', '0');
+    } else {
+      header.css('border-bottom-width', '1px');
+    }
+    $('#modal .modal-body').html(html).modal({'show':true,'backdrop':false});
+    Lightbox.openActions();
+  },
+
+  /**
+   * This is the function you call to manually close the lightbox
+   */
+  close: function(evt) {
+    $('#modal').modal('hide'); // This event calls closeActions
+  },
+  /**
+   * This function is attached to the lightbox close event,
+   * so it always runs when the lightbox is closed.
+   */
+  closeActions: function() {
+    Lightbox.shown = false;
+    Lightbox.openingURL = false;
+    // Clean out stack
+    while(Lightbox.closeStack.length > 0) {
+      var f = Lightbox.closeStack.pop();
+      f();
+    }
+    if(this.XHR) { this.XHR.abort(); }
+    // Reset content so we start fresh when we open a lightbox
+    $('#modal').removeData('modal');
+    $('#modal').find('.modal-title').html('');
+    $('#modal').find('.modal-body').html(vufindString.loading + "...");
+  },
+  /**
+   * Call all the functions we need for when the modal loads
+   *
+   * Called by the 'shown' event and at the end of changeContent
+   */
+  openActions: function() {
+    for(var i=0;i<Lightbox.openStack.length;i++) {
+      Lightbox.openStack[i]();
+    }
+  },
+  /**
+   * This function changes the content of the lightbox to a message with a close button
+   */
+  confirm: function(message) {
+    this.changeContent('<div class="alert alert-info">'+message+'</div><button class="btn btn-default" onClick="Lightbox.close()">'+vufindString['close']+'</button>');
+  },
+  /**
+   * Regexes a piece of html to find an error alert
+   * If one is found, display it
+   *
+   * If one is not found, return html to a success callback function
+   */
+  checkForError: function(html, success) {
+    var fi = html.indexOf('<div class="alert alert-danger">');
+    if(fi > -1) {
+      var li = html.indexOf('</div>', fi+31);
+      Lightbox.displayError(html.substring(fi+31, li).replace(/^[\s<>]+|[\s<>]+$/g, ''));
+    } else {
+      success(html);
+    }
+  },
+  /**
+   * Insert an error alert element at the top of the lightbox
+   */
+  displayError: function(message) {
+    var alert = $('#modal .modal-body .alert');
+    var html = $.parseHTML($('#modal .modal-body').html());
+    // Page with alert already present
+    if(alert.length > 0 && html.length > 1) {
+      $(alert).html(message);
+    // Empty or alert only, change to message with button
+    } else if($('#modal .modal-body').html() == vufindString.loading+"..."
+    || (html.length == 1 && $(html).hasClass('alert-danger'))) {
+      Lightbox.changeContent('<div class="alert alert-danger" role="alert">'+message+'</div><button class="btn btn-default" onClick="Lightbox.close()">'+vufindString['close']+'</button>');
+    // Page without alert
+    } else {
+      $('#modal .modal-body').prepend('<div class="alert alert-danger 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>'+message+'</div>');
+    }
+    $('.fa-spinner').remove();
+    if (typeof Recaptcha !== "undefined" && Recaptcha.widget) {
+      Recaptcha.reload();
+    }
+  },
+
+  /***********************************/
+  /* ====== LIGHTBOX REQUESTS ====== */
+  /***********************************/
+  /**
+   * This function creates an XHR request to the URL
+   * and handles the response according to the callback.
+   *
+   * Default callback is changeContent
+   */
+  getByUrl: function(url, post, callback) {
+    if(typeof callback == "undefined") {
+      // No custom handler: display return in lightbox
+      callback = this.changeContent;
+    }
+    // If the lightbox isn't visible, fix that
+    if(this.shown == false) {
+      $('#modal').modal('show');
+      this.shown = true;
+    }
+    // Create our AJAX request, store it in case we need to cancel later
+    this.ajax({
+      type:'POST',
+      url:url,
+      data:post,
+      success:function(html) { // Success!
+        callback(html);
+      },
+      error:function(d,e) {
+        if (d.status == 200) {
+          try {
+            var data = JSON.parse(d.responseText);
+            Lightbox.changeContent('<p class="alert alert-danger">'+data.data+'</p>');
+          } catch(error) {
+            Lightbox.changeContent('<p class="alert alert-danger">'+d.responseText+'</p>');
+          }
+        } else if(d.status > 0) {
+          Lightbox.changeContent('<p class="alert alert-danger">'+d.statusText+' ('+d.status+')</p>');
+        }
+        console.log(e,d); // Error reporting
+        console.log(url,post);
+      }
+    });
+    // Store current "page" context for empty targets
+    if(this.openingURL === false) {
+      this.openingURL = url;
+    }
+    this.lastURL = url;
+    this.lastPOST = post;
+    //this.openActions();
+    return false;
+  },
+  /**
+   * This is the friendly face to the function above.
+   * It converts a Controller and Action into a URL through the AJAX handler
+   * with GET and pushes the data and callback to the getByUrl
+   */
+  get: function(controller, action, get, post, callback) {
+    // Build URL
+    var url = path+'/AJAX/JSON?method=getLightbox&submodule='+controller+'&subaction='+action;
+    if(typeof get !== "undefined" && get !== {}) {
+      url += '&'+$.param(get);
+    }
+    if(typeof post == "undefined") {
+      post = {};
+    }
+    return this.getByUrl(url, post, callback);
+  },
+
+  /**********************************/
+  /* ====== FORM SUBMISSIONS ====== */
+  /**********************************/
+  /**
+   * Returns all the input values from a form as an associated array
+   *
+   * This function takes a jQuery wrapped form
+   * $(event.target) for example
+   */
+  getFormData: function($form) {
+    // Gather all the data
+    var inputs = $form.find('*[name]');
+    var data = {};
+    for(var i=0;i<inputs.length;i++) {
+      var currentName = inputs[i].name;
+      var array = currentName.substring(currentName.length-2) == '[]';
+      if(array && !data[currentName.substring(0,currentName.length-2)]) {
+        data[currentName.substring(0,currentName.length-2)] = [];
+      }
+      // Submit buttons
+      if(inputs[i].type == 'submit') {
+        if($(inputs[i]).attr('clicked') == 'true') {
+          data[currentName] = inputs[i].value;
+        }
+      // Radio buttons
+      } else if(inputs[i].type == 'radio') {
+        if(inputs[i].checked) {
+          if(array) {
+            var n = currentName.substring(0,currentName.length-2);
+            data[n].push(inputs[i].value);
+          } else {
+            data[currentName] = inputs[i].value;
+          }
+        }
+      // Checkboxes
+      } else if($(inputs[i]).attr('type') != 'checkbox' || inputs[i].checked) {
+        if(array) {
+          var f = currentName.substring(0,currentName.length-2);
+          data[f].push(inputs[i].value);
+        } else {
+          data[currentName] = inputs[i].value;
+        }
+      }
+    }
+    return data;
+  },
+  /**
+   * This function adds submission events to forms loaded inside the lightbox
+   *
+   * First, it will check for custom handlers, for those who want to handle everything.
+   *
+   * Then, it will check for custom form callbacks. These will be added to an anonymous
+   * function that will call Lightbox.submit with the form and the callback.
+   *
+   * Finally, if nothing custom is setup, it will add the default function which
+   * calls Lightbox.submit with a callback to close if there are no errors to display.
+   *
+   * This is a default open action, so it runs every time changeContent
+   * is called and the 'shown' lightbox event is triggered
+   */
+  registerForms: function() {
+    var form = $("#modal").find('form');
+    var name = $(form).attr('name');
+    // Assign form handler based on name
+    if(typeof name !== "undefined" && typeof Lightbox.formHandlers[name] !== "undefined") {
+      $(form).unbind('submit').submit(Lightbox.formHandlers[name]);
+    // Default action, with custom callback
+    } else if(typeof Lightbox.formCallbacks[name] !== "undefined") {
+      $(form).unbind('submit').submit(function(evt){
+        Lightbox.submit($(evt.target), Lightbox.formCallbacks[name]);
+        return false;
+      });
+    // Default
+    } else {
+      $(form).unbind('submit').submit(function(evt){
+        Lightbox.submit($(evt.target), function(html){
+          Lightbox.checkForError(html, Lightbox.close);
+        });
+        return false;
+      });
+    }
+  },
+  /**
+   * The default, automatic form submission
+   *
+   * This function gleans all the information in a form from the function above
+   * Then it uses the action="" attribute of the form to figure out where to send the data
+   * and the method="" attribute to send it the proper way
+   *
+   * In the wild, forms without an action="" are submitted to the current URL.
+   * In the case where we have a form with no action in the lightbox,
+   * we emulate that behaviour by submitting the last URL loaded through
+   * .getByUrl, stored in lastURL in the Lightbox object.
+   */
+  submit: function($form, callback) {
+    // Default callback is to close
+    if(typeof callback == "undefined") {
+      callback = this.close;
+    }
+    var data = this.getFormData($form);
+    // If we have an action: parse
+    var POST = $form.attr('method') && $form.attr('method').toUpperCase() == 'POST';
+    if($form.attr('action')) {
+      // Parse action location
+      var action = $form.attr('action').substring($form.attr('action').indexOf(path)+path.length+1);
+      var params = action.split('?');
+      action = action.split('/');
+      var get = params.length > 1 ? deparam(params[1]) : data['id'] ? {id:data['id']} : {};
+      if(POST) {
+        this.get(action[0], action[action.length-1], get, data, callback);
+      } else {
+        this.get(action[0], action[action.length-1], data, {}, callback);
+      }
+    // If not: fake context by using the previous action
+    } else if(POST) {
+      this.getByUrl(this.lastURL, data, callback);
+    } else {
+      this.getByUrl(this.lastURL, {}, callback);
+    }
+    $(this).find('.modal-body').html(vufindString.loading + "...");
+  }
+};
+
+/**
+ * This is where you add click events to open the lightbox.
+ * We do it here so that non-JS users still have a good time.
+ */
+$(document).ready(function() {
+  // Add handlers to the forms
+  Lightbox.addOpenAction(Lightbox.registerForms);
+  /**
+   * Hook into the Bootstrap close event
+   *
+   * Yes, the secret's out, our beloved Lightbox is a modal
+   */
+  $('#modal').on('hidden.bs.modal', Lightbox.closeActions);
+  /**
+   * If a link with the class .modal-link triggers the lightbox,
+   * look for a title="" to use as our lightbox title.
+   */
+  $('.modal-link,.help-link').click(function() {
+    var title = $(this).attr('title');
+    if(typeof title === "undefined") {
+      title = $(this).html();
+    }
+    $('#modal .modal-title').html(title);
+    Lightbox.titleSet = true;
+  });
 });
\ No newline at end of file
diff --git a/themes/bootstrap3/templates/cart/email.phtml b/themes/bootstrap3/templates/cart/email.phtml
index 56a62ab00a6d22e28a8c5899989d44f589595363..d279a9202b4f88ce65d1a3dd2f998df76cd34e77 100644
--- a/themes/bootstrap3/templates/cart/email.phtml
+++ b/themes/bootstrap3/templates/cart/email.phtml
@@ -1,66 +1,66 @@
-<?
-  // Set page title.
-  $this->headTitle($this->translate('email_selected_favorites'));
-
-  // Set up breadcrumbs:
-  $this->layout()->breadcrumbs = '<li>' . $this->getLastSearchLink($this->transEsc('Search'), '', '</li> ')
-    . '<li><a href="' .$this->url('cart-home'). '">' .$this->transEsc('Cart'). '</a></li> '
-    . '<li class="active">' . $this->transEsc('email_selected_favorites') . '</li>';
-?>
-<?=$this->flashmessages()?>
-<form class="form-horizontal" action="<?=$this->url('cart-email')?>" method="post"  name="bulkEmail">
-  <? foreach ($this->records as $current): ?>
-    <input type="hidden" name="ids[]" value="<?=$this->escapeHtmlAttr($current->getResourceSource() . '|' . $current->getUniqueId())?>" />
-  <? endforeach; ?>
-  <div class="form-group">
-    <label class="col-sm-3 control-label"><?=$this->transEsc('Title')?></label>
-    <div class="col-sm-9">
-    <? if(count($this->records) > 1): ?>
-        <button type="button" class="btn btn-default hidden" data-toggle="collapse" data-target="#itemhide">
-          <?=count($this->records).' '.$this->transEsc('items') ?>
-        </button>
-        <div id="itemhide" class="collapse in">
-          <ul>
-            <? foreach ($this->records as $current): ?>
-              <li><?=$this->escapeHtml($current->getBreadcrumb())?></li>
-            <? endforeach; ?>
-          </ul>
-        </div>
-    <? else: ?>
-      <span class="uneditable-input"><?=$this->records[0]->getBreadcrumb() ?></span>
-    <? endif; ?>
-    </div>
-  </div>
-  <div class="form-group">
-    <label class="col-sm-3 control-label" for="email_to"><?=$this->transEsc('To')?>:</label>
-    <div class="col-sm-9">
-      <input id="email_to" type="email" name="to" value="<?=isset($this->to) ? $this->to : ''?>" size="40" class="form-control" oninvalid="$('#modal .fa-spinner').remove()"/>
-    </div>
-  </div>
-  <? if (!$this->disableFrom): ?>
-    <div class="form-group">
-      <label class="col-sm-3 control-label" for="email_from"><?=$this->transEsc('From')?>:</label>
-      <div class="col-sm-9">
-        <input id="email_from" type="email" name="from" value="<?=isset($this->from) ? $this->from : ''?>" size="40" class="form-control" oninvalid="$('#modal .fa-spinner').remove()"/>
-      </div>
-    </div>
-  <? endif; ?>
-  <div class="form-group">
-    <label class="col-sm-3 control-label" for="email_message"><?=$this->transEsc('Message')?>:</label>
-    <div class="col-sm-9">
-      <textarea id="email_message" name="message" rows="3" cols="40" class="form-control"><?=isset($this->message) ? $this->message : ''?></textarea>
-    </div>
-  </div>
-  <div class="form-group">
-    <div class="col-sm-9 col-sm-offset-3">
-      <input class="btn btn-primary" type="submit" name="submit" value="<?=$this->transEsc('Send')?>"/>
-    </div>
-  </div>
-</form>
-<?
-  $script = <<<JS
-    $('button.btn.hidden').removeClass('hidden');
-    $('.collapse.in').removeClass('in');
-JS;
-?>
+<?
+  // Set page title.
+  $this->headTitle($this->translate('email_selected_favorites'));
+
+  // Set up breadcrumbs:
+  $this->layout()->breadcrumbs = '<li>' . $this->getLastSearchLink($this->transEsc('Search'), '', '</li> ')
+    . '<li><a href="' .$this->url('cart-home'). '">' .$this->transEsc('Cart'). '</a></li> '
+    . '<li class="active">' . $this->transEsc('email_selected_favorites') . '</li>';
+?>
+<?=$this->flashmessages()?>
+<form class="form-horizontal" action="<?=$this->url('cart-email')?>" method="post"  name="bulkEmail">
+  <? foreach ($this->records as $current): ?>
+    <input type="hidden" name="ids[]" value="<?=$this->escapeHtmlAttr($current->getResourceSource() . '|' . $current->getUniqueId())?>" />
+  <? endforeach; ?>
+  <div class="form-group">
+    <label class="col-sm-3 control-label"><?=$this->transEsc('Title')?></label>
+    <div class="col-sm-9">
+    <? if(count($this->records) > 1): ?>
+        <button type="button" class="btn btn-default hidden" data-toggle="collapse" data-target="#itemhide">
+          <?=count($this->records).' '.$this->transEsc('items') ?>
+        </button>
+        <div id="itemhide" class="collapse in">
+          <ul>
+            <? foreach ($this->records as $current): ?>
+              <li><?=$this->escapeHtml($current->getBreadcrumb())?></li>
+            <? endforeach; ?>
+          </ul>
+        </div>
+    <? else: ?>
+      <p class="form-control-static"><?=$this->records[0]->getBreadcrumb() ?></p>
+    <? endif; ?>
+    </div>
+  </div>
+  <div class="form-group">
+    <label class="col-sm-3 control-label" for="email_to"><?=$this->transEsc('To')?>:</label>
+    <div class="col-sm-9">
+      <input id="email_to" type="email" name="to" value="<?=isset($this->to) ? $this->to : ''?>" size="40" class="form-control" oninvalid="$('#modal .fa-spinner').remove()"/>
+    </div>
+  </div>
+  <? if (!$this->disableFrom): ?>
+    <div class="form-group">
+      <label class="col-sm-3 control-label" for="email_from"><?=$this->transEsc('From')?>:</label>
+      <div class="col-sm-9">
+        <input id="email_from" type="email" name="from" value="<?=isset($this->from) ? $this->from : ''?>" size="40" class="form-control" oninvalid="$('#modal .fa-spinner').remove()"/>
+      </div>
+    </div>
+  <? endif; ?>
+  <div class="form-group">
+    <label class="col-sm-3 control-label" for="email_message"><?=$this->transEsc('Message')?>:</label>
+    <div class="col-sm-9">
+      <textarea id="email_message" name="message" rows="3" cols="40" class="form-control"><?=isset($this->message) ? $this->message : ''?></textarea>
+    </div>
+  </div>
+  <div class="form-group">
+    <div class="col-sm-9 col-sm-offset-3">
+      <input class="btn btn-primary" type="submit" name="submit" value="<?=$this->transEsc('Send')?>"/>
+    </div>
+  </div>
+</form>
+<?
+  $script = <<<JS
+    $('button.btn.hidden').removeClass('hidden');
+    $('.collapse.in').removeClass('in');
+JS;
+?>
 <?=$this->inlineScript(\Zend\View\Helper\HeadScript::SCRIPT, $script, 'SET') ?>
\ No newline at end of file