Browse Source

Added array adapter

This should add support for dynamically generated array data that
still works with a basic `<select>` element.
Kevin Brown 10 years ago
parent
commit
315b1b3c12

+ 68 - 1
dist/js/select2.amd.full.js

@@ -449,6 +449,11 @@ define('select2/selection/single',[
     var self = this;
 
     this.$selection.on('mousedown', function (evt) {
+      // Only respond to left clicks
+      if (evt.which !== 1) {
+        return;
+      }
+
       self.trigger("toggle", {
         originalEvent: evt
       });
@@ -557,12 +562,74 @@ define('select2/selection/multiple',[
   return MultipleSelection;
 });
 
+define('select2/data/array',[
+  "./select",
+  "../utils"
+], function (SelectAdapter, Utils) {
+  function ArrayAdapter ($element, options) {
+    this.data = options.options.data;
+    this.selection = [];
+
+    ArrayAdapter.__super__.constructor.call(this, $element, options);
+  }
+
+  Utils.Extend(ArrayAdapter, SelectAdapter);
+
+  ArrayAdapter.prototype.select = function (data) {
+    var self = this;
+
+    this.$element.find("option").each(function () {
+      var $option = $(this);
+      var option = self.item($option);
+
+      if (option.id == data.id) {
+        $option.remove();
+      }
+    });
+
+    var $option = this.option(data);
+
+    this.$element.append($option);
+
+    ArrayAdapter.__super__.select.call(this, data);
+  }
+
+  ArrayAdapter.prototype.option = function (data) {
+    var $option = $("<option></option>");
+
+    $option.text(data.text);
+    $option.val(data.id);
+    $option.data("data", data);
+
+    return $option;
+  }
+
+  ArrayAdapter.prototype.query = function (params, callback) {
+    var matches = [];
+    var self = this;
+
+    $.each(this.data, function () {
+      var option = this;
+
+      if (self.matches(params, option)) {
+        matches.push(option);
+      }
+    });
+
+    callback(matches);
+  }
+
+  return ArrayAdapter;
+});
+
 define('select2/options',[
   './data/select',
   './results',
   './dropdown',
   './selection/single',
-  './selection/multiple'
+  './selection/multiple',
+
+  './data/array'
 ], function (SelectData, ResultsList, Dropdown, SingleSelection,
              MultipleSelection) {
   function Options (options) {

+ 68 - 1
dist/js/select2.amd.js

@@ -449,6 +449,11 @@ define('select2/selection/single',[
     var self = this;
 
     this.$selection.on('mousedown', function (evt) {
+      // Only respond to left clicks
+      if (evt.which !== 1) {
+        return;
+      }
+
       self.trigger("toggle", {
         originalEvent: evt
       });
@@ -557,12 +562,74 @@ define('select2/selection/multiple',[
   return MultipleSelection;
 });
 
+define('select2/data/array',[
+  "./select",
+  "../utils"
+], function (SelectAdapter, Utils) {
+  function ArrayAdapter ($element, options) {
+    this.data = options.options.data;
+    this.selection = [];
+
+    ArrayAdapter.__super__.constructor.call(this, $element, options);
+  }
+
+  Utils.Extend(ArrayAdapter, SelectAdapter);
+
+  ArrayAdapter.prototype.select = function (data) {
+    var self = this;
+
+    this.$element.find("option").each(function () {
+      var $option = $(this);
+      var option = self.item($option);
+
+      if (option.id == data.id) {
+        $option.remove();
+      }
+    });
+
+    var $option = this.option(data);
+
+    this.$element.append($option);
+
+    ArrayAdapter.__super__.select.call(this, data);
+  }
+
+  ArrayAdapter.prototype.option = function (data) {
+    var $option = $("<option></option>");
+
+    $option.text(data.text);
+    $option.val(data.id);
+    $option.data("data", data);
+
+    return $option;
+  }
+
+  ArrayAdapter.prototype.query = function (params, callback) {
+    var matches = [];
+    var self = this;
+
+    $.each(this.data, function () {
+      var option = this;
+
+      if (self.matches(params, option)) {
+        matches.push(option);
+      }
+    });
+
+    callback(matches);
+  }
+
+  return ArrayAdapter;
+});
+
 define('select2/options',[
   './data/select',
   './results',
   './dropdown',
   './selection/single',
-  './selection/multiple'
+  './selection/multiple',
+
+  './data/array'
 ], function (SelectData, ResultsList, Dropdown, SingleSelection,
              MultipleSelection) {
   function Options (options) {

+ 68 - 1
dist/js/select2.full.js

@@ -9986,6 +9986,11 @@ define('select2/selection/single',[
     var self = this;
 
     this.$selection.on('mousedown', function (evt) {
+      // Only respond to left clicks
+      if (evt.which !== 1) {
+        return;
+      }
+
       self.trigger("toggle", {
         originalEvent: evt
       });
@@ -10094,12 +10099,74 @@ define('select2/selection/multiple',[
   return MultipleSelection;
 });
 
+define('select2/data/array',[
+  "./select",
+  "../utils"
+], function (SelectAdapter, Utils) {
+  function ArrayAdapter ($element, options) {
+    this.data = options.options.data;
+    this.selection = [];
+
+    ArrayAdapter.__super__.constructor.call(this, $element, options);
+  }
+
+  Utils.Extend(ArrayAdapter, SelectAdapter);
+
+  ArrayAdapter.prototype.select = function (data) {
+    var self = this;
+
+    this.$element.find("option").each(function () {
+      var $option = $(this);
+      var option = self.item($option);
+
+      if (option.id == data.id) {
+        $option.remove();
+      }
+    });
+
+    var $option = this.option(data);
+
+    this.$element.append($option);
+
+    ArrayAdapter.__super__.select.call(this, data);
+  }
+
+  ArrayAdapter.prototype.option = function (data) {
+    var $option = $("<option></option>");
+
+    $option.text(data.text);
+    $option.val(data.id);
+    $option.data("data", data);
+
+    return $option;
+  }
+
+  ArrayAdapter.prototype.query = function (params, callback) {
+    var matches = [];
+    var self = this;
+
+    $.each(this.data, function () {
+      var option = this;
+
+      if (self.matches(params, option)) {
+        matches.push(option);
+      }
+    });
+
+    callback(matches);
+  }
+
+  return ArrayAdapter;
+});
+
 define('select2/options',[
   './data/select',
   './results',
   './dropdown',
   './selection/single',
-  './selection/multiple'
+  './selection/multiple',
+
+  './data/array'
 ], function (SelectData, ResultsList, Dropdown, SingleSelection,
              MultipleSelection) {
   function Options (options) {

+ 68 - 1
dist/js/select2.js

@@ -877,6 +877,11 @@ define('select2/selection/single',[
     var self = this;
 
     this.$selection.on('mousedown', function (evt) {
+      // Only respond to left clicks
+      if (evt.which !== 1) {
+        return;
+      }
+
       self.trigger("toggle", {
         originalEvent: evt
       });
@@ -985,12 +990,74 @@ define('select2/selection/multiple',[
   return MultipleSelection;
 });
 
+define('select2/data/array',[
+  "./select",
+  "../utils"
+], function (SelectAdapter, Utils) {
+  function ArrayAdapter ($element, options) {
+    this.data = options.options.data;
+    this.selection = [];
+
+    ArrayAdapter.__super__.constructor.call(this, $element, options);
+  }
+
+  Utils.Extend(ArrayAdapter, SelectAdapter);
+
+  ArrayAdapter.prototype.select = function (data) {
+    var self = this;
+
+    this.$element.find("option").each(function () {
+      var $option = $(this);
+      var option = self.item($option);
+
+      if (option.id == data.id) {
+        $option.remove();
+      }
+    });
+
+    var $option = this.option(data);
+
+    this.$element.append($option);
+
+    ArrayAdapter.__super__.select.call(this, data);
+  }
+
+  ArrayAdapter.prototype.option = function (data) {
+    var $option = $("<option></option>");
+
+    $option.text(data.text);
+    $option.val(data.id);
+    $option.data("data", data);
+
+    return $option;
+  }
+
+  ArrayAdapter.prototype.query = function (params, callback) {
+    var matches = [];
+    var self = this;
+
+    $.each(this.data, function () {
+      var option = this;
+
+      if (self.matches(params, option)) {
+        matches.push(option);
+      }
+    });
+
+    callback(matches);
+  }
+
+  return ArrayAdapter;
+});
+
 define('select2/options',[
   './data/select',
   './results',
   './dropdown',
   './selection/single',
-  './selection/multiple'
+  './selection/multiple',
+
+  './data/array'
 ], function (SelectData, ResultsList, Dropdown, SingleSelection,
              MultipleSelection) {
   function Options (options) {

+ 114 - 0
playground/basic/adapters.html

@@ -0,0 +1,114 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>QUnit Example</title>
+    <link href="../../dist/css/select2.css" rel="stylesheet"/>
+
+    <script src="../../vendor/almond-0.2.9.js" type="text/javascript"></script>
+    <script src="../../vendor/jquery-2.1.0.js" type="text/javascript"></script>
+
+    <script src="../../dist/js/select2.js"></script>
+</head>
+<body>
+
+<select style="width:300px" id="array-single"></select>
+
+<br />
+
+<select style="width:300px" id="array-multiple" multiple="multiple"></select>
+
+<br />
+
+<select style="width:300px" id="single-multiple">
+    <option value="AK">Alaska</option>
+    <option value="HI">Hawaii</option>
+    <option value="CA">California</option>
+    <option value="NV">Nevada</option>
+    <option value="OR">Oregon</option>
+    <option value="WA">Washington</option>
+    <option value="AZ">Arizona</option>
+    <option value="CO">Colorado</option>
+    <option value="ID">Idaho</option>
+    <option value="MT">Montana</option>
+    <option value="NE">Nebraska</option>
+    <option value="NM">New Mexico</option>
+    <option value="ND">North Dakota</option>
+    <option value="UT">Utah</option>
+    <option value="WY">Wyoming</option>
+    <option value="AL">Alabama</option>
+    <option value="AR">Arkansas</option>
+    <option value="IL">Illinois</option>
+    <option value="IA">Iowa</option>
+    <option value="KS">Kansas</option>
+    <option value="KY">Kentucky</option>
+    <option value="LA">Louisiana</option>
+    <option value="MN">Minnesota</option>
+    <option value="MS">Mississippi</option>
+    <option value="MO">Missouri</option>
+    <option value="OK">Oklahoma</option>
+    <option value="SD">South Dakota</option>
+    <option value="TX">Texas</option>
+    <option value="TN">Tennessee</option>
+    <option value="WI">Wisconsin</option>
+    <option value="CT">Connecticut</option>
+    <option value="DE">Delaware</option>
+    <option value="FL">Florida</option>
+    <option value="GA">Georgia</option>
+    <option value="IN">Indiana</option>
+    <option value="ME">Maine</option>
+    <option value="MD">Maryland</option>
+    <option value="MA">Massachusetts</option>
+    <option value="MI">Michigan</option>
+    <option value="NH">New Hampshire</option>
+    <option value="NJ">New Jersey</option>
+    <option value="NY">New York</option>
+    <option value="NC">North Carolina</option>
+    <option value="OH">Ohio</option>
+    <option value="PA">Pennsylvania</option>
+    <option value="RI">Rhode Island</option>
+    <option value="SC">South Carolina</option>
+    <option value="VT">Vermont</option>
+    <option value="VA">Virginia</option>
+    <option value="WV">West Virginia</option>
+</select>
+
+<script>
+require(["select2/core", "select2/data/array"], function (Select2, ArrayAdapter) {
+    var arrayData = [
+        {
+            id: 0,
+            text: 'enhancement'
+        },
+        {
+            id: 1,
+            text: 'bug'
+        },
+        {
+            id: 2,
+            text: 'duplicate'
+        },
+        {
+            id: 3,
+            text: 'invalid'
+        },
+        {
+            id: 4,
+            text: 'wontfix'
+        }
+    ];
+
+    var arraySingle = new Select2($("#array-single"), {
+        dataAdapter: ArrayAdapter,
+        data: arrayData
+    });
+
+    var arrayMultiple = new Select2($("#array-multiple"), {
+        dataAdapter: ArrayAdapter,
+        data: arrayData
+    });
+});
+</script>
+
+</body>
+</html>

+ 2 - 2
playground/basic/decorators.html

@@ -178,11 +178,11 @@ require(["select2/core", "select2/utils", "select2/selection/single",
 
         this.$container = $container;
 
-        this.$clear.on("click", function (evt) {
+        this.$clear.on("mousedown", function (evt) {
             evt.stopPropagation();
 
             var $first = $container.find("li").first();
-            $first.click();
+            $first.mouseup();
         });
     };
 

+ 59 - 0
src/js/select2/data/array.js

@@ -0,0 +1,59 @@
+define([
+  "./select",
+  "../utils"
+], function (SelectAdapter, Utils) {
+  function ArrayAdapter ($element, options) {
+    this.data = options.options.data;
+    this.selection = [];
+
+    ArrayAdapter.__super__.constructor.call(this, $element, options);
+  }
+
+  Utils.Extend(ArrayAdapter, SelectAdapter);
+
+  ArrayAdapter.prototype.select = function (data) {
+    var self = this;
+
+    this.$element.find("option").each(function () {
+      var $option = $(this);
+      var option = self.item($option);
+
+      if (option.id == data.id) {
+        $option.remove();
+      }
+    });
+
+    var $option = this.option(data);
+
+    this.$element.append($option);
+
+    ArrayAdapter.__super__.select.call(this, data);
+  }
+
+  ArrayAdapter.prototype.option = function (data) {
+    var $option = $("<option></option>");
+
+    $option.text(data.text);
+    $option.val(data.id);
+    $option.data("data", data);
+
+    return $option;
+  }
+
+  ArrayAdapter.prototype.query = function (params, callback) {
+    var matches = [];
+    var self = this;
+
+    $.each(this.data, function () {
+      var option = this;
+
+      if (self.matches(params, option)) {
+        matches.push(option);
+      }
+    });
+
+    callback(matches);
+  }
+
+  return ArrayAdapter;
+});

+ 3 - 1
src/js/select2/options.js

@@ -3,7 +3,9 @@ define([
   './results',
   './dropdown',
   './selection/single',
-  './selection/multiple'
+  './selection/multiple',
+
+  './data/array'
 ], function (SelectData, ResultsList, Dropdown, SingleSelection,
              MultipleSelection) {
   function Options (options) {

+ 5 - 0
src/js/select2/selection/single.js

@@ -26,6 +26,11 @@ define([
     var self = this;
 
     this.$selection.on('mousedown', function (evt) {
+      // Only respond to left clicks
+      if (evt.which !== 1) {
+        return;
+      }
+
       self.trigger("toggle", {
         originalEvent: evt
       });