Selaa lähdekoodia

Working on searching results

Kevin Brown 10 vuotta sitten
vanhempi
commit
6375e2ee09

+ 9 - 0
dist/css/select2.css

@@ -41,6 +41,13 @@
   left: -100000px;
   width: 100%;
   z-index: 100; }
+  .select2-container .dropdown .search {
+    display: block;
+    padding: 4px; }
+    .select2-container .dropdown .search input {
+      outline: 0;
+      padding: 4px;
+      width: 100%; }
   .select2-container .dropdown .results {
     display: block; }
     .select2-container .dropdown .results .options {
@@ -85,6 +92,8 @@
 .select2-container.select2-theme-default.open .selection .single-select, .select2-container.select2-theme-default.open .selection .multiple-select {
   border-bottom-left-radius: 0;
   border-bottom-right-radius: 0; }
+.select2-container.select2-theme-default .dropdown .search input {
+  border: 1px solid #aaa; }
 .select2-container.select2-theme-default .dropdown .results {
   max-height: 200px;
   overflow-y: scroll; }

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/css/select2.min.css


+ 87 - 34
dist/js/select2.amd.full.js

@@ -193,7 +193,7 @@ define('select2/results',[
         var $option = $(this);
         var item = $option.data('data');
 
-        if (selectedIds.indexOf(item.id.toString()) > -1) {
+        if (item.id != null && selectedIds.indexOf(item.id.toString()) > -1) {
           $option.addClass('selected');
         }
       });
@@ -205,7 +205,7 @@ define('select2/results',[
       '<li class="option highlightable selectable"></li>'
     );
 
-    if (data.children && data.children.length > 0) {
+    if (data.children) {
       $option.addClass('group').removeClass('highlightable selectable');
 
       var $label = $('<strong class="group-label"></strong>');
@@ -235,6 +235,10 @@ define('select2/results',[
       $option.removeClass('selectable highlightable').addClass('disabled');
     }
 
+    if (data.id == null) {
+      $option.removeClass('selectable highlightable');
+    }
+
     $option.data('data', data);
 
     return $option;
@@ -292,28 +296,6 @@ define('select2/results',[
   return Results;
 });
 
-define('select2/dropdown',[
-  './utils'
-], function (Utils) {
-  function Dropdown ($element, options) {
-    this.$element = $element;
-  }
-
-  Utils.Extend(Dropdown, Utils.Observable);
-
-  Dropdown.prototype.render = function () {
-    var $dropdown = $(
-      '<span class="dropdown">' +
-        '<span class="results"></span>' +
-      '</span>'
-    );
-
-    return $dropdown;
-  };
-
-  return Dropdown;
-});
-
 define('select2/selection/single',[
   '../utils'
 ], function (Utils) {
@@ -605,7 +587,6 @@ define('select2/data/select',[
         };
       } else if ($option.is('optgroup')) {
         data = {
-          id: -1,
           text: $option.attr('label'),
           children: []
         };
@@ -654,7 +635,7 @@ define('select2/data/select',[
       return match;
     }
 
-    if (data.text.indexOf(params.term) > -1) {
+    if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) > -1) {
       return match;
     }
 
@@ -769,19 +750,83 @@ define('select2/data/ajax',[
   return AjaxAdapter;
 });
 
+define('select2/dropdown',[
+  './utils'
+], function (Utils) {
+  function Dropdown ($element, options) {
+    this.$element = $element;
+  }
+
+  Utils.Extend(Dropdown, Utils.Observable);
+
+  Dropdown.prototype.render = function () {
+    var $dropdown = $(
+      '<span class="dropdown">' +
+        '<span class="results"></span>' +
+      '</span>'
+    );
+
+    return $dropdown;
+  };
+
+  Dropdown.prototype.bind = function (container, $container) {
+    // Can be implemented in subclasses
+  };
+
+  return Dropdown;
+});
+
+define('select2/dropdown/search',[
+
+], function () {
+  function Search () { }
+
+  Search.prototype.render = function (decorated) {
+    var $rendered = decorated.call(this);
+
+    var $search = $(
+      '<span class="search">' +
+        '<input type="search" name="search" />' +
+      '</span>'
+    );
+
+    this.$search = $search.find('input');
+
+    $rendered.prepend($search);
+
+    return $rendered;
+  };
+
+  Search.prototype.bind = function (decorated, container, $container) {
+    decorated.call(this, container, $container);
+
+    this.$search.on('keyup', function () {
+      container.trigger('query', {
+        term: $(this).val()
+      });
+    });
+  };
+
+  return Search;
+});
+
 define('select2/options',[
   './results',
 
-  './dropdown',
-
   './selection/single',
   './selection/multiple',
 
+  './utils',
+
   './data/select',
   './data/array',
-  './data/ajax'
-], function (ResultsList, Dropdown, SingleSelection, MultipleSelection,
-             SelectData, ArrayData, AjaxData) {
+  './data/ajax',
+
+  './dropdown',
+  './dropdown/search'
+], function (ResultsList, SingleSelection, MultipleSelection, Utils,
+             SelectData, ArrayData, AjaxData,
+             Dropdown, Search) {
   function Options (options) {
     this.options = options;
 
@@ -793,8 +838,10 @@ define('select2/options',[
       this.dataAdapter = this.dataAdapter || SelectData;
     }
 
+    var SearchableDropdown = Utils.Decorate(Dropdown, Search);
+
     this.resultsAdapter = ResultsList;
-    this.dropdownAdapter = options.dropdownAdapter || Dropdown;
+    this.dropdownAdapter = options.dropdownAdapter || SearchableDropdown;
     this.selectionAdapter = options.selectionAdapter;
 
     if (this.selectionAdapter == null) {
@@ -864,6 +911,8 @@ define('select2/core',[
 
     this.data.bind(this, $container);
     this.selection.bind(this, $container);
+
+    this.dropdown.bind(this, $container);
     this.results.bind(this, $container);
 
     this.$element.on('change', function () {
@@ -906,10 +955,14 @@ define('select2/core',[
       });
     });
 
-    this.data.query({}, function (data) {
-      self.results.trigger('results:all', data);
+    this.on('query', function (params) {
+      this.data.query(params, function (data) {
+        self.results.trigger('results:all', data);
+      });
     });
 
+    this.trigger('query', {});
+
     // Hide the original select
 
     $element.hide();

+ 87 - 34
dist/js/select2.amd.js

@@ -193,7 +193,7 @@ define('select2/results',[
         var $option = $(this);
         var item = $option.data('data');
 
-        if (selectedIds.indexOf(item.id.toString()) > -1) {
+        if (item.id != null && selectedIds.indexOf(item.id.toString()) > -1) {
           $option.addClass('selected');
         }
       });
@@ -205,7 +205,7 @@ define('select2/results',[
       '<li class="option highlightable selectable"></li>'
     );
 
-    if (data.children && data.children.length > 0) {
+    if (data.children) {
       $option.addClass('group').removeClass('highlightable selectable');
 
       var $label = $('<strong class="group-label"></strong>');
@@ -235,6 +235,10 @@ define('select2/results',[
       $option.removeClass('selectable highlightable').addClass('disabled');
     }
 
+    if (data.id == null) {
+      $option.removeClass('selectable highlightable');
+    }
+
     $option.data('data', data);
 
     return $option;
@@ -292,28 +296,6 @@ define('select2/results',[
   return Results;
 });
 
-define('select2/dropdown',[
-  './utils'
-], function (Utils) {
-  function Dropdown ($element, options) {
-    this.$element = $element;
-  }
-
-  Utils.Extend(Dropdown, Utils.Observable);
-
-  Dropdown.prototype.render = function () {
-    var $dropdown = $(
-      '<span class="dropdown">' +
-        '<span class="results"></span>' +
-      '</span>'
-    );
-
-    return $dropdown;
-  };
-
-  return Dropdown;
-});
-
 define('select2/selection/single',[
   '../utils'
 ], function (Utils) {
@@ -605,7 +587,6 @@ define('select2/data/select',[
         };
       } else if ($option.is('optgroup')) {
         data = {
-          id: -1,
           text: $option.attr('label'),
           children: []
         };
@@ -654,7 +635,7 @@ define('select2/data/select',[
       return match;
     }
 
-    if (data.text.indexOf(params.term) > -1) {
+    if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) > -1) {
       return match;
     }
 
@@ -769,19 +750,83 @@ define('select2/data/ajax',[
   return AjaxAdapter;
 });
 
+define('select2/dropdown',[
+  './utils'
+], function (Utils) {
+  function Dropdown ($element, options) {
+    this.$element = $element;
+  }
+
+  Utils.Extend(Dropdown, Utils.Observable);
+
+  Dropdown.prototype.render = function () {
+    var $dropdown = $(
+      '<span class="dropdown">' +
+        '<span class="results"></span>' +
+      '</span>'
+    );
+
+    return $dropdown;
+  };
+
+  Dropdown.prototype.bind = function (container, $container) {
+    // Can be implemented in subclasses
+  };
+
+  return Dropdown;
+});
+
+define('select2/dropdown/search',[
+
+], function () {
+  function Search () { }
+
+  Search.prototype.render = function (decorated) {
+    var $rendered = decorated.call(this);
+
+    var $search = $(
+      '<span class="search">' +
+        '<input type="search" name="search" />' +
+      '</span>'
+    );
+
+    this.$search = $search.find('input');
+
+    $rendered.prepend($search);
+
+    return $rendered;
+  };
+
+  Search.prototype.bind = function (decorated, container, $container) {
+    decorated.call(this, container, $container);
+
+    this.$search.on('keyup', function () {
+      container.trigger('query', {
+        term: $(this).val()
+      });
+    });
+  };
+
+  return Search;
+});
+
 define('select2/options',[
   './results',
 
-  './dropdown',
-
   './selection/single',
   './selection/multiple',
 
+  './utils',
+
   './data/select',
   './data/array',
-  './data/ajax'
-], function (ResultsList, Dropdown, SingleSelection, MultipleSelection,
-             SelectData, ArrayData, AjaxData) {
+  './data/ajax',
+
+  './dropdown',
+  './dropdown/search'
+], function (ResultsList, SingleSelection, MultipleSelection, Utils,
+             SelectData, ArrayData, AjaxData,
+             Dropdown, Search) {
   function Options (options) {
     this.options = options;
 
@@ -793,8 +838,10 @@ define('select2/options',[
       this.dataAdapter = this.dataAdapter || SelectData;
     }
 
+    var SearchableDropdown = Utils.Decorate(Dropdown, Search);
+
     this.resultsAdapter = ResultsList;
-    this.dropdownAdapter = options.dropdownAdapter || Dropdown;
+    this.dropdownAdapter = options.dropdownAdapter || SearchableDropdown;
     this.selectionAdapter = options.selectionAdapter;
 
     if (this.selectionAdapter == null) {
@@ -864,6 +911,8 @@ define('select2/core',[
 
     this.data.bind(this, $container);
     this.selection.bind(this, $container);
+
+    this.dropdown.bind(this, $container);
     this.results.bind(this, $container);
 
     this.$element.on('change', function () {
@@ -906,10 +955,14 @@ define('select2/core',[
       });
     });
 
-    this.data.query({}, function (data) {
-      self.results.trigger('results:all', data);
+    this.on('query', function (params) {
+      this.data.query(params, function (data) {
+        self.results.trigger('results:all', data);
+      });
     });
 
+    this.trigger('query', {});
+
     // Hide the original select
 
     $element.hide();

+ 87 - 34
dist/js/select2.full.js

@@ -9731,7 +9731,7 @@ define('select2/results',[
         var $option = $(this);
         var item = $option.data('data');
 
-        if (selectedIds.indexOf(item.id.toString()) > -1) {
+        if (item.id != null && selectedIds.indexOf(item.id.toString()) > -1) {
           $option.addClass('selected');
         }
       });
@@ -9743,7 +9743,7 @@ define('select2/results',[
       '<li class="option highlightable selectable"></li>'
     );
 
-    if (data.children && data.children.length > 0) {
+    if (data.children) {
       $option.addClass('group').removeClass('highlightable selectable');
 
       var $label = $('<strong class="group-label"></strong>');
@@ -9773,6 +9773,10 @@ define('select2/results',[
       $option.removeClass('selectable highlightable').addClass('disabled');
     }
 
+    if (data.id == null) {
+      $option.removeClass('selectable highlightable');
+    }
+
     $option.data('data', data);
 
     return $option;
@@ -9830,28 +9834,6 @@ define('select2/results',[
   return Results;
 });
 
-define('select2/dropdown',[
-  './utils'
-], function (Utils) {
-  function Dropdown ($element, options) {
-    this.$element = $element;
-  }
-
-  Utils.Extend(Dropdown, Utils.Observable);
-
-  Dropdown.prototype.render = function () {
-    var $dropdown = $(
-      '<span class="dropdown">' +
-        '<span class="results"></span>' +
-      '</span>'
-    );
-
-    return $dropdown;
-  };
-
-  return Dropdown;
-});
-
 define('select2/selection/single',[
   '../utils'
 ], function (Utils) {
@@ -10143,7 +10125,6 @@ define('select2/data/select',[
         };
       } else if ($option.is('optgroup')) {
         data = {
-          id: -1,
           text: $option.attr('label'),
           children: []
         };
@@ -10192,7 +10173,7 @@ define('select2/data/select',[
       return match;
     }
 
-    if (data.text.indexOf(params.term) > -1) {
+    if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) > -1) {
       return match;
     }
 
@@ -10307,19 +10288,83 @@ define('select2/data/ajax',[
   return AjaxAdapter;
 });
 
+define('select2/dropdown',[
+  './utils'
+], function (Utils) {
+  function Dropdown ($element, options) {
+    this.$element = $element;
+  }
+
+  Utils.Extend(Dropdown, Utils.Observable);
+
+  Dropdown.prototype.render = function () {
+    var $dropdown = $(
+      '<span class="dropdown">' +
+        '<span class="results"></span>' +
+      '</span>'
+    );
+
+    return $dropdown;
+  };
+
+  Dropdown.prototype.bind = function (container, $container) {
+    // Can be implemented in subclasses
+  };
+
+  return Dropdown;
+});
+
+define('select2/dropdown/search',[
+
+], function () {
+  function Search () { }
+
+  Search.prototype.render = function (decorated) {
+    var $rendered = decorated.call(this);
+
+    var $search = $(
+      '<span class="search">' +
+        '<input type="search" name="search" />' +
+      '</span>'
+    );
+
+    this.$search = $search.find('input');
+
+    $rendered.prepend($search);
+
+    return $rendered;
+  };
+
+  Search.prototype.bind = function (decorated, container, $container) {
+    decorated.call(this, container, $container);
+
+    this.$search.on('keyup', function () {
+      container.trigger('query', {
+        term: $(this).val()
+      });
+    });
+  };
+
+  return Search;
+});
+
 define('select2/options',[
   './results',
 
-  './dropdown',
-
   './selection/single',
   './selection/multiple',
 
+  './utils',
+
   './data/select',
   './data/array',
-  './data/ajax'
-], function (ResultsList, Dropdown, SingleSelection, MultipleSelection,
-             SelectData, ArrayData, AjaxData) {
+  './data/ajax',
+
+  './dropdown',
+  './dropdown/search'
+], function (ResultsList, SingleSelection, MultipleSelection, Utils,
+             SelectData, ArrayData, AjaxData,
+             Dropdown, Search) {
   function Options (options) {
     this.options = options;
 
@@ -10331,8 +10376,10 @@ define('select2/options',[
       this.dataAdapter = this.dataAdapter || SelectData;
     }
 
+    var SearchableDropdown = Utils.Decorate(Dropdown, Search);
+
     this.resultsAdapter = ResultsList;
-    this.dropdownAdapter = options.dropdownAdapter || Dropdown;
+    this.dropdownAdapter = options.dropdownAdapter || SearchableDropdown;
     this.selectionAdapter = options.selectionAdapter;
 
     if (this.selectionAdapter == null) {
@@ -10402,6 +10449,8 @@ define('select2/core',[
 
     this.data.bind(this, $container);
     this.selection.bind(this, $container);
+
+    this.dropdown.bind(this, $container);
     this.results.bind(this, $container);
 
     this.$element.on('change', function () {
@@ -10444,10 +10493,14 @@ define('select2/core',[
       });
     });
 
-    this.data.query({}, function (data) {
-      self.results.trigger('results:all', data);
+    this.on('query', function (params) {
+      this.data.query(params, function (data) {
+        self.results.trigger('results:all', data);
+      });
     });
 
+    this.trigger('query', {});
+
     // Hide the original select
 
     $element.hide();

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/js/select2.full.min.js


+ 87 - 34
dist/js/select2.js

@@ -622,7 +622,7 @@ define('select2/results',[
         var $option = $(this);
         var item = $option.data('data');
 
-        if (selectedIds.indexOf(item.id.toString()) > -1) {
+        if (item.id != null && selectedIds.indexOf(item.id.toString()) > -1) {
           $option.addClass('selected');
         }
       });
@@ -634,7 +634,7 @@ define('select2/results',[
       '<li class="option highlightable selectable"></li>'
     );
 
-    if (data.children && data.children.length > 0) {
+    if (data.children) {
       $option.addClass('group').removeClass('highlightable selectable');
 
       var $label = $('<strong class="group-label"></strong>');
@@ -664,6 +664,10 @@ define('select2/results',[
       $option.removeClass('selectable highlightable').addClass('disabled');
     }
 
+    if (data.id == null) {
+      $option.removeClass('selectable highlightable');
+    }
+
     $option.data('data', data);
 
     return $option;
@@ -721,28 +725,6 @@ define('select2/results',[
   return Results;
 });
 
-define('select2/dropdown',[
-  './utils'
-], function (Utils) {
-  function Dropdown ($element, options) {
-    this.$element = $element;
-  }
-
-  Utils.Extend(Dropdown, Utils.Observable);
-
-  Dropdown.prototype.render = function () {
-    var $dropdown = $(
-      '<span class="dropdown">' +
-        '<span class="results"></span>' +
-      '</span>'
-    );
-
-    return $dropdown;
-  };
-
-  return Dropdown;
-});
-
 define('select2/selection/single',[
   '../utils'
 ], function (Utils) {
@@ -1034,7 +1016,6 @@ define('select2/data/select',[
         };
       } else if ($option.is('optgroup')) {
         data = {
-          id: -1,
           text: $option.attr('label'),
           children: []
         };
@@ -1083,7 +1064,7 @@ define('select2/data/select',[
       return match;
     }
 
-    if (data.text.indexOf(params.term) > -1) {
+    if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) > -1) {
       return match;
     }
 
@@ -1198,19 +1179,83 @@ define('select2/data/ajax',[
   return AjaxAdapter;
 });
 
+define('select2/dropdown',[
+  './utils'
+], function (Utils) {
+  function Dropdown ($element, options) {
+    this.$element = $element;
+  }
+
+  Utils.Extend(Dropdown, Utils.Observable);
+
+  Dropdown.prototype.render = function () {
+    var $dropdown = $(
+      '<span class="dropdown">' +
+        '<span class="results"></span>' +
+      '</span>'
+    );
+
+    return $dropdown;
+  };
+
+  Dropdown.prototype.bind = function (container, $container) {
+    // Can be implemented in subclasses
+  };
+
+  return Dropdown;
+});
+
+define('select2/dropdown/search',[
+
+], function () {
+  function Search () { }
+
+  Search.prototype.render = function (decorated) {
+    var $rendered = decorated.call(this);
+
+    var $search = $(
+      '<span class="search">' +
+        '<input type="search" name="search" />' +
+      '</span>'
+    );
+
+    this.$search = $search.find('input');
+
+    $rendered.prepend($search);
+
+    return $rendered;
+  };
+
+  Search.prototype.bind = function (decorated, container, $container) {
+    decorated.call(this, container, $container);
+
+    this.$search.on('keyup', function () {
+      container.trigger('query', {
+        term: $(this).val()
+      });
+    });
+  };
+
+  return Search;
+});
+
 define('select2/options',[
   './results',
 
-  './dropdown',
-
   './selection/single',
   './selection/multiple',
 
+  './utils',
+
   './data/select',
   './data/array',
-  './data/ajax'
-], function (ResultsList, Dropdown, SingleSelection, MultipleSelection,
-             SelectData, ArrayData, AjaxData) {
+  './data/ajax',
+
+  './dropdown',
+  './dropdown/search'
+], function (ResultsList, SingleSelection, MultipleSelection, Utils,
+             SelectData, ArrayData, AjaxData,
+             Dropdown, Search) {
   function Options (options) {
     this.options = options;
 
@@ -1222,8 +1267,10 @@ define('select2/options',[
       this.dataAdapter = this.dataAdapter || SelectData;
     }
 
+    var SearchableDropdown = Utils.Decorate(Dropdown, Search);
+
     this.resultsAdapter = ResultsList;
-    this.dropdownAdapter = options.dropdownAdapter || Dropdown;
+    this.dropdownAdapter = options.dropdownAdapter || SearchableDropdown;
     this.selectionAdapter = options.selectionAdapter;
 
     if (this.selectionAdapter == null) {
@@ -1293,6 +1340,8 @@ define('select2/core',[
 
     this.data.bind(this, $container);
     this.selection.bind(this, $container);
+
+    this.dropdown.bind(this, $container);
     this.results.bind(this, $container);
 
     this.$element.on('change', function () {
@@ -1335,10 +1384,14 @@ define('select2/core',[
       });
     });
 
-    this.data.query({}, function (data) {
-      self.results.trigger('results:all', data);
+    this.on('query', function (params) {
+      this.data.query(params, function (data) {
+        self.results.trigger('results:all', data);
+      });
     });
 
+    this.trigger('query', {});
+
     // Hide the original select
 
     $element.hide();

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/js/select2.min.js


+ 1 - 1
docs/examples.html

@@ -289,7 +289,7 @@ $("[data-fill-from]").each(function () {
 
 prettyPrint();
 
-require(["select2/core", "select2/dropdown", "select2/utils"], function (Select2, Dropdown, Utils) {
+require(["select2/core", "select2/utils"], function (Select2, Utils) {
   var $basicSingle = $(".js-example-basic-single");
   var $basicMultiple = $(".js-example-basic-multiple");
 

+ 8 - 2
src/js/select2/core.js

@@ -53,6 +53,8 @@ define([
 
     this.data.bind(this, $container);
     this.selection.bind(this, $container);
+
+    this.dropdown.bind(this, $container);
     this.results.bind(this, $container);
 
     this.$element.on('change', function () {
@@ -95,10 +97,14 @@ define([
       });
     });
 
-    this.data.query({}, function (data) {
-      self.results.trigger('results:all', data);
+    this.on('query', function (params) {
+      this.data.query(params, function (data) {
+        self.results.trigger('results:all', data);
+      });
     });
 
+    this.trigger('query', {});
+
     // Hide the original select
 
     $element.hide();

+ 1 - 2
src/js/select2/data/select.js

@@ -128,7 +128,6 @@ define([
         };
       } else if ($option.is('optgroup')) {
         data = {
-          id: -1,
           text: $option.attr('label'),
           children: []
         };
@@ -177,7 +176,7 @@ define([
       return match;
     }
 
-    if (data.text.indexOf(params.term) > -1) {
+    if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) > -1) {
       return match;
     }
 

+ 4 - 0
src/js/select2/dropdown.js

@@ -17,5 +17,9 @@ define([
     return $dropdown;
   };
 
+  Dropdown.prototype.bind = function (container, $container) {
+    // Can be implemented in subclasses
+  };
+
   return Dropdown;
 });

+ 26 - 8
src/js/select2/dropdown/search.js

@@ -1,14 +1,32 @@
 define([
-  '../utils'
-], function (Utils) {
-  function Search (decorated, args) {
-    decorated.call(this, args);
-  }
 
-  Utils.Extend(Search, Utils.Observable);
+], function () {
+  function Search () { }
 
-  Search.prototype.bind = function (decorated, args) {
-    this.$container = $container;
+  Search.prototype.render = function (decorated) {
+    var $rendered = decorated.call(this);
+
+    var $search = $(
+      '<span class="search">' +
+        '<input type="search" name="search" />' +
+      '</span>'
+    );
+
+    this.$search = $search.find('input');
+
+    $rendered.prepend($search);
+
+    return $rendered;
+  };
+
+  Search.prototype.bind = function (decorated, container, $container) {
+    decorated.call(this, container, $container);
+
+    this.$search.on('keyup', function () {
+      container.trigger('query', {
+        term: $(this).val()
+      });
+    });
   };
 
   return Search;

+ 12 - 6
src/js/select2/options.js

@@ -1,16 +1,20 @@
 define([
   './results',
 
-  './dropdown',
-
   './selection/single',
   './selection/multiple',
 
+  './utils',
+
   './data/select',
   './data/array',
-  './data/ajax'
-], function (ResultsList, Dropdown, SingleSelection, MultipleSelection,
-             SelectData, ArrayData, AjaxData) {
+  './data/ajax',
+
+  './dropdown',
+  './dropdown/search'
+], function (ResultsList, SingleSelection, MultipleSelection, Utils,
+             SelectData, ArrayData, AjaxData,
+             Dropdown, Search) {
   function Options (options) {
     this.options = options;
 
@@ -22,8 +26,10 @@ define([
       this.dataAdapter = this.dataAdapter || SelectData;
     }
 
+    var SearchableDropdown = Utils.Decorate(Dropdown, Search);
+
     this.resultsAdapter = ResultsList;
-    this.dropdownAdapter = options.dropdownAdapter || Dropdown;
+    this.dropdownAdapter = options.dropdownAdapter || SearchableDropdown;
     this.selectionAdapter = options.selectionAdapter;
 
     if (this.selectionAdapter == null) {

+ 6 - 2
src/js/select2/results.js

@@ -54,7 +54,7 @@ define([
         var $option = $(this);
         var item = $option.data('data');
 
-        if (selectedIds.indexOf(item.id.toString()) > -1) {
+        if (item.id != null && selectedIds.indexOf(item.id.toString()) > -1) {
           $option.addClass('selected');
         }
       });
@@ -66,7 +66,7 @@ define([
       '<li class="option highlightable selectable"></li>'
     );
 
-    if (data.children && data.children.length > 0) {
+    if (data.children) {
       $option.addClass('group').removeClass('highlightable selectable');
 
       var $label = $('<strong class="group-label"></strong>');
@@ -96,6 +96,10 @@ define([
       $option.removeClass('selectable highlightable').addClass('disabled');
     }
 
+    if (data.id == null) {
+      $option.removeClass('selectable highlightable');
+    }
+
     $option.data('data', data);
 
     return $option;

+ 11 - 0
src/scss/_dropdown.scss

@@ -16,6 +16,17 @@
 
     z-index: 100;
 
+    .search {
+      display: block;
+      padding: 4px;
+
+      input {
+        outline: 0;
+        padding: 4px;
+        width: 100%;
+      }
+    }
+
     .results {
       display: block;
 

+ 6 - 0
src/scss/theme/default/layout.scss

@@ -49,6 +49,12 @@
   }
 
   .dropdown {
+    .search {
+      input {
+        border: 1px solid #aaa;
+      }
+    }
+
     .results {
       max-height: 200px;
       overflow-y: scroll;

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä