From 6ec69d2c5ee331b36cf4e6253473d5ae502da461 Mon Sep 17 00:00:00 2001
From: Julian Maurice <julian.maurice@biblibre.com>
Date: Tue, 30 Dec 2014 14:40:44 +0100
Subject: [PATCH] Bug 13501: Add jQuery UI plugin combobox

It allows autocompletion on selects.

Based on http://jqueryui.com/autocomplete/#combobox

Note: This patch reset $.fn.button to the jQuery UI one (was overwritten
by Bootstrap)
---
 .../lib/jquery/plugins/jquery-ui-combobox.js       | 115 +++++++++++++++++++++
 .../intranet-tmpl/prog/en/css/staff-global.css     |  26 +++++
 .../prog/en/includes/doc-head-close.inc            |   5 +
 3 files changed, 146 insertions(+)
 create mode 100644 koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery-ui-combobox.js

diff --git a/koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery-ui-combobox.js b/koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery-ui-combobox.js
new file mode 100644
index 0000000..02840b3
--- /dev/null
+++ b/koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery-ui-combobox.js
@@ -0,0 +1,115 @@
+(function($) {
+  $.widget("custom.combobox", {
+    _create: function() {
+      this.wrapper = $("<span>")
+        .addClass("custom-combobox")
+        .insertAfter(this.element);
+      this.element.hide();
+      this._createAutocomplete();
+      this._createShowAllButton();
+    },
+
+    _createAutocomplete: function() {
+      var selected = this.element.children(":selected"),
+          value = selected.val() ? selected.text() : "";
+
+      this.input = $("<input>")
+        .appendTo(this.wrapper)
+        .val(value)
+        .attr("title", "")
+        .addClass("custom-combobox-input ui-widget ui-widget-content ui-state-default ui-corner-left")
+        .autocomplete({
+          delay: 0,
+          minLength: 0,
+          source: $.proxy(this, "_source")
+        });
+
+      this._on(this.input, {
+        autocompleteselect: function(event, ui) {
+          ui.item.option.selected = true;
+          this._trigger("select", event, {
+            item: ui.item.option
+          });
+        },
+        autocompletechange: "_removeIfInvalid"
+      });
+    },
+
+    _createShowAllButton: function() {
+      var input = this.input,
+        wasOpen = false;
+
+      $("<a>")
+        .append('&nbsp;')
+        .attr("tabIndex", -1)
+        .attr("title", "Show All Items")
+        .appendTo(this.wrapper)
+        .button({
+          icons: {
+            primary: "ui-icon-triangle-1-s"
+          },
+          text: false
+        })
+        .removeClass("ui-corner-all")
+        .addClass("custom-combobox-toggle ui-corner-right")
+        .mousedown(function() {
+          wasOpen = input.autocomplete("widget").is(":visible");
+        })
+        .click(function() {
+          input.focus();
+          // Close if already visible
+          if (wasOpen) {
+            return;
+          }
+          // Pass empty string as value to search for, displaying all results
+          input.autocomplete("search", "");
+        });
+    },
+
+    _source: function(request, response) {
+      var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
+      response(this.element.children("option").map(function() {
+        var text = $(this).text();
+        if (this.value && (!request.term || matcher.test(text)))
+          return {
+            label: text,
+            value: text,
+            option: this
+          };
+      }));
+    },
+
+    _removeIfInvalid: function(event, ui) {
+      // Selected an item, nothing to do
+      if (ui.item) {
+        return;
+      }
+
+      // Search for a match (case-insensitive)
+      var value = this.input.val(),
+          valueLowerCase = value.toLowerCase(),
+          valid = false;
+      this.element.children("option").each(function() {
+        if ($(this).text().toLowerCase() === valueLowerCase) {
+          this.selected = valid = true;
+          return false;
+        }
+      });
+
+      // Found a match, nothing to do
+      if (valid) {
+        return;
+      }
+
+      // Remove invalid value
+      this.input.val("");
+      this.element.val("");
+      this.input.autocomplete("instance").term = "";
+    },
+
+    _destroy: function() {
+      this.wrapper.remove();
+      this.element.show();
+    }
+  });
+})(jQuery);
diff --git a/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css b/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css
index 9d5b7ea..e313c73 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css
+++ b/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css
@@ -2023,6 +2023,8 @@ div#acqui_order_supplierlist > div.supplier > div.baskets {
     -webkit-box-shadow: 2px 2px 2px rgba(0,0,0,.3);
     -moz-box-shadow: 2px 2px 2px rgba(0,0,0,.3);
     box-shadow: 2px 2px 2px rgba(0,0,0,.3);
+    max-height: 300px;
+    overflow: auto;
 }
 .ui-autocomplete.ui-widget-content .ui-state-hover {
     border: 1px solid #B9D8D9;
@@ -2108,6 +2110,30 @@ ul.ui-tabs-nav li {
     color: #538200;
 }
 
+/* jQuery UI Combobox */
+.custom-combobox {
+  display: inline-block;
+}
+
+.custom-combobox > * {
+  vertical-align: middle;
+}
+
+.custom-combobox-toggle {
+  margin-left: -1px;
+}
+
+.custom-combobox-input,
+.custom-combobox-toggle .ui-button-text {
+  padding: 5px 10px;
+}
+
+.custom-combobox-input:focus {
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+}
+
+
 .statictabs ul {
     background: none repeat scroll 0 0 transparent;
     border: 0 none;
diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-close.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-close.inc
index f6269de..54725bc 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-close.inc
+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-close.inc
@@ -14,6 +14,11 @@
 <script type="text/javascript" src="[% interface %]/lib/jquery/plugins/jquery.cookie.min.js"></script>
 <script type="text/javascript" src="[% interface %]/lib/jquery/plugins/jquery.highlight-3.js"></script>
 <script type="text/javascript" src="[% interface %]/lib/bootstrap/bootstrap.min.js"></script>
+<script type="text/javascript">
+  /* Bootstrap overwrites jQuery UI button().
+   * This line reverts button() to jQuery UI. */
+  $.fn.button.noConflict();
+</script>
 <script type="text/javascript" src="[% interface %]/lib/jquery/plugins/jquery.validate.min.js"></script>
 
 [% IF ( login ) %]
-- 
1.9.1