فهرست منبع

Convert array data to options immediately

This converts individual objects passed in through the `array`
parameter to `<option>` tags when Select2 is initialized. This
removes a lot of duplicate code from the `ArrayAdapter`, and keeps
everything closer to the native `<select>` element.

This introduces a breaking change from previous versions of Select2,
where the initial value for array data was blank, even if a blank
option was not present in the original array of objects. Now the
first object passed in will be selected by default, following the
behavior of a standard `<select>` element.

This breaking change does not affect `<select multiple="multiple">`
elements, which by default have no selection.
Kevin Brown 10 سال پیش
والد
کامیت
8ea23610f1

+ 36 - 22
dist/js/select2.amd.full.js

@@ -1089,6 +1089,7 @@ define('select2/data/select',[
     $option.text(data.text);
     $option.val(data.id);
     $option.prop('disabled', data.disabled || false);
+    $option.prop('selected', data.selected || false);
 
     // Get any automatically generated data values
     var detectedData = this.item($option);
@@ -1137,6 +1138,8 @@ define('select2/data/select',[
         data._resultId = this.generateResultId(this.container, data);
       }
 
+      data.selected = $option.prop('selected');
+
       $option.data('data', data);
     }
 
@@ -1158,45 +1161,56 @@ define('select2/data/array',[
   'jquery'
 ], function (SelectAdapter, Utils, $) {
   function ArrayAdapter ($element, options) {
-    this.data = options.get('data');
+    var data = options.get('data');
 
     ArrayAdapter.__super__.constructor.call(this, $element, options);
+
+    this.convertToOptions(data);
   }
 
   Utils.Extend(ArrayAdapter, SelectAdapter);
 
-  ArrayAdapter.prototype.select = function (data) {
+  ArrayAdapter.prototype.convertToOptions = function (data) {
     var self = this;
 
-    this.$element.find('option').each(function () {
-      var $option = $(this);
-      var option = self.item($option);
+    var $existing = this.$element.find('option');
+    var existingIds = $existing.map(function () {
+      return self.item($(this)).id;
+    }).get();
 
-      if (option.id == data.id.toString()) {
-        $option.remove();
-      }
-    });
+    // Filter out all items except for the one passed in the argument
+    function onlyItem (item) {
+      return function () {
+        return $(this).val() == item.id;
+      };
+    }
+
+    for (var d = 0; d < data.length; d++) {
+      var item = data[d];
+      item.id = item.id.toString();
 
-    var $option = this.option(data);
+      console.log(existingIds, item.id, existingIds.indexOf(item.id));
 
-    this.$element.append($option);
+      // Skip items which were pre-loaded, only merge the data
+      if (existingIds.indexOf(item.id) >= 0) {
+        console.log(item.id);
 
-    ArrayAdapter.__super__.select.call(this, data);
-  };
+        var $existingOption = $existing.filter(onlyItem(item));
 
-  ArrayAdapter.prototype.query = function (params, callback) {
-    var matches = [];
-    var self = this;
+        var existingData = this.item($existingOption);
+        var newData = $.extend(true, {}, existingData, item);
 
-    $.each(this.data, function () {
-      var option = this;
+        var $newOption = this.option(existingData);
 
-      if (self.matches(params, option)) {
-        matches.push(option);
+        $existingOption.replaceWith($newOption);
+
+        continue;
       }
-    });
 
-    callback(matches);
+      var option = this.option(item);
+
+      this.$element.append(option);
+    }
   };
 
   return ArrayAdapter;

+ 36 - 22
dist/js/select2.amd.js

@@ -1089,6 +1089,7 @@ define('select2/data/select',[
     $option.text(data.text);
     $option.val(data.id);
     $option.prop('disabled', data.disabled || false);
+    $option.prop('selected', data.selected || false);
 
     // Get any automatically generated data values
     var detectedData = this.item($option);
@@ -1137,6 +1138,8 @@ define('select2/data/select',[
         data._resultId = this.generateResultId(this.container, data);
       }
 
+      data.selected = $option.prop('selected');
+
       $option.data('data', data);
     }
 
@@ -1158,45 +1161,56 @@ define('select2/data/array',[
   'jquery'
 ], function (SelectAdapter, Utils, $) {
   function ArrayAdapter ($element, options) {
-    this.data = options.get('data');
+    var data = options.get('data');
 
     ArrayAdapter.__super__.constructor.call(this, $element, options);
+
+    this.convertToOptions(data);
   }
 
   Utils.Extend(ArrayAdapter, SelectAdapter);
 
-  ArrayAdapter.prototype.select = function (data) {
+  ArrayAdapter.prototype.convertToOptions = function (data) {
     var self = this;
 
-    this.$element.find('option').each(function () {
-      var $option = $(this);
-      var option = self.item($option);
+    var $existing = this.$element.find('option');
+    var existingIds = $existing.map(function () {
+      return self.item($(this)).id;
+    }).get();
 
-      if (option.id == data.id.toString()) {
-        $option.remove();
-      }
-    });
+    // Filter out all items except for the one passed in the argument
+    function onlyItem (item) {
+      return function () {
+        return $(this).val() == item.id;
+      };
+    }
+
+    for (var d = 0; d < data.length; d++) {
+      var item = data[d];
+      item.id = item.id.toString();
 
-    var $option = this.option(data);
+      console.log(existingIds, item.id, existingIds.indexOf(item.id));
 
-    this.$element.append($option);
+      // Skip items which were pre-loaded, only merge the data
+      if (existingIds.indexOf(item.id) >= 0) {
+        console.log(item.id);
 
-    ArrayAdapter.__super__.select.call(this, data);
-  };
+        var $existingOption = $existing.filter(onlyItem(item));
 
-  ArrayAdapter.prototype.query = function (params, callback) {
-    var matches = [];
-    var self = this;
+        var existingData = this.item($existingOption);
+        var newData = $.extend(true, {}, existingData, item);
 
-    $.each(this.data, function () {
-      var option = this;
+        var $newOption = this.option(existingData);
 
-      if (self.matches(params, option)) {
-        matches.push(option);
+        $existingOption.replaceWith($newOption);
+
+        continue;
       }
-    });
 
-    callback(matches);
+      var option = this.option(item);
+
+      this.$element.append(option);
+    }
   };
 
   return ArrayAdapter;

+ 36 - 22
dist/js/select2.full.js

@@ -10624,6 +10624,7 @@ define('select2/data/select',[
     $option.text(data.text);
     $option.val(data.id);
     $option.prop('disabled', data.disabled || false);
+    $option.prop('selected', data.selected || false);
 
     // Get any automatically generated data values
     var detectedData = this.item($option);
@@ -10672,6 +10673,8 @@ define('select2/data/select',[
         data._resultId = this.generateResultId(this.container, data);
       }
 
+      data.selected = $option.prop('selected');
+
       $option.data('data', data);
     }
 
@@ -10693,45 +10696,56 @@ define('select2/data/array',[
   'jquery'
 ], function (SelectAdapter, Utils, $) {
   function ArrayAdapter ($element, options) {
-    this.data = options.get('data');
+    var data = options.get('data');
 
     ArrayAdapter.__super__.constructor.call(this, $element, options);
+
+    this.convertToOptions(data);
   }
 
   Utils.Extend(ArrayAdapter, SelectAdapter);
 
-  ArrayAdapter.prototype.select = function (data) {
+  ArrayAdapter.prototype.convertToOptions = function (data) {
     var self = this;
 
-    this.$element.find('option').each(function () {
-      var $option = $(this);
-      var option = self.item($option);
+    var $existing = this.$element.find('option');
+    var existingIds = $existing.map(function () {
+      return self.item($(this)).id;
+    }).get();
 
-      if (option.id == data.id.toString()) {
-        $option.remove();
-      }
-    });
+    // Filter out all items except for the one passed in the argument
+    function onlyItem (item) {
+      return function () {
+        return $(this).val() == item.id;
+      };
+    }
+
+    for (var d = 0; d < data.length; d++) {
+      var item = data[d];
+      item.id = item.id.toString();
 
-    var $option = this.option(data);
+      console.log(existingIds, item.id, existingIds.indexOf(item.id));
 
-    this.$element.append($option);
+      // Skip items which were pre-loaded, only merge the data
+      if (existingIds.indexOf(item.id) >= 0) {
+        console.log(item.id);
 
-    ArrayAdapter.__super__.select.call(this, data);
-  };
+        var $existingOption = $existing.filter(onlyItem(item));
 
-  ArrayAdapter.prototype.query = function (params, callback) {
-    var matches = [];
-    var self = this;
+        var existingData = this.item($existingOption);
+        var newData = $.extend(true, {}, existingData, item);
 
-    $.each(this.data, function () {
-      var option = this;
+        var $newOption = this.option(existingData);
 
-      if (self.matches(params, option)) {
-        matches.push(option);
+        $existingOption.replaceWith($newOption);
+
+        continue;
       }
-    });
 
-    callback(matches);
+      var option = this.option(item);
+
+      this.$element.append(option);
+    }
   };
 
   return ArrayAdapter;

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
dist/js/select2.full.min.js


+ 36 - 22
dist/js/select2.js

@@ -1517,6 +1517,7 @@ define('select2/data/select',[
     $option.text(data.text);
     $option.val(data.id);
     $option.prop('disabled', data.disabled || false);
+    $option.prop('selected', data.selected || false);
 
     // Get any automatically generated data values
     var detectedData = this.item($option);
@@ -1565,6 +1566,8 @@ define('select2/data/select',[
         data._resultId = this.generateResultId(this.container, data);
       }
 
+      data.selected = $option.prop('selected');
+
       $option.data('data', data);
     }
 
@@ -1586,45 +1589,56 @@ define('select2/data/array',[
   'jquery'
 ], function (SelectAdapter, Utils, $) {
   function ArrayAdapter ($element, options) {
-    this.data = options.get('data');
+    var data = options.get('data');
 
     ArrayAdapter.__super__.constructor.call(this, $element, options);
+
+    this.convertToOptions(data);
   }
 
   Utils.Extend(ArrayAdapter, SelectAdapter);
 
-  ArrayAdapter.prototype.select = function (data) {
+  ArrayAdapter.prototype.convertToOptions = function (data) {
     var self = this;
 
-    this.$element.find('option').each(function () {
-      var $option = $(this);
-      var option = self.item($option);
+    var $existing = this.$element.find('option');
+    var existingIds = $existing.map(function () {
+      return self.item($(this)).id;
+    }).get();
 
-      if (option.id == data.id.toString()) {
-        $option.remove();
-      }
-    });
+    // Filter out all items except for the one passed in the argument
+    function onlyItem (item) {
+      return function () {
+        return $(this).val() == item.id;
+      };
+    }
+
+    for (var d = 0; d < data.length; d++) {
+      var item = data[d];
+      item.id = item.id.toString();
 
-    var $option = this.option(data);
+      console.log(existingIds, item.id, existingIds.indexOf(item.id));
 
-    this.$element.append($option);
+      // Skip items which were pre-loaded, only merge the data
+      if (existingIds.indexOf(item.id) >= 0) {
+        console.log(item.id);
 
-    ArrayAdapter.__super__.select.call(this, data);
-  };
+        var $existingOption = $existing.filter(onlyItem(item));
 
-  ArrayAdapter.prototype.query = function (params, callback) {
-    var matches = [];
-    var self = this;
+        var existingData = this.item($existingOption);
+        var newData = $.extend(true, {}, existingData, item);
 
-    $.each(this.data, function () {
-      var option = this;
+        var $newOption = this.option(existingData);
 
-      if (self.matches(params, option)) {
-        matches.push(option);
+        $existingOption.replaceWith($newOption);
+
+        continue;
       }
-    });
 
-    callback(matches);
+      var option = this.option(item);
+
+      this.$element.append(option);
+    }
   };
 
   return ArrayAdapter;

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
dist/js/select2.min.js


+ 33 - 22
src/js/select2/data/array.js

@@ -4,45 +4,56 @@ define([
   'jquery'
 ], function (SelectAdapter, Utils, $) {
   function ArrayAdapter ($element, options) {
-    this.data = options.get('data');
+    var data = options.get('data');
 
     ArrayAdapter.__super__.constructor.call(this, $element, options);
+
+    this.convertToOptions(data);
   }
 
   Utils.Extend(ArrayAdapter, SelectAdapter);
 
-  ArrayAdapter.prototype.select = function (data) {
+  ArrayAdapter.prototype.convertToOptions = function (data) {
     var self = this;
 
-    this.$element.find('option').each(function () {
-      var $option = $(this);
-      var option = self.item($option);
+    var $existing = this.$element.find('option');
+    var existingIds = $existing.map(function () {
+      return self.item($(this)).id;
+    }).get();
 
-      if (option.id == data.id.toString()) {
-        $option.remove();
-      }
-    });
+    // Filter out all items except for the one passed in the argument
+    function onlyItem (item) {
+      return function () {
+        return $(this).val() == item.id;
+      };
+    }
 
-    var $option = this.option(data);
+    for (var d = 0; d < data.length; d++) {
+      var item = data[d];
+      item.id = item.id.toString();
 
-    this.$element.append($option);
+      console.log(existingIds, item.id, existingIds.indexOf(item.id));
 
-    ArrayAdapter.__super__.select.call(this, data);
-  };
+      // Skip items which were pre-loaded, only merge the data
+      if (existingIds.indexOf(item.id) >= 0) {
+        console.log(item.id);
 
-  ArrayAdapter.prototype.query = function (params, callback) {
-    var matches = [];
-    var self = this;
+        var $existingOption = $existing.filter(onlyItem(item));
 
-    $.each(this.data, function () {
-      var option = this;
+        var existingData = this.item($existingOption);
+        var newData = $.extend(true, {}, existingData, item);
 
-      if (self.matches(params, option)) {
-        matches.push(option);
+        var $newOption = this.option(existingData);
+
+        $existingOption.replaceWith($newOption);
+
+        continue;
       }
-    });
 
-    callback(matches);
+      var option = this.option(item);
+
+      this.$element.append(option);
+    }
   };
 
   return ArrayAdapter;

+ 3 - 0
src/js/select2/data/select.js

@@ -126,6 +126,7 @@ define([
     $option.text(data.text);
     $option.val(data.id);
     $option.prop('disabled', data.disabled || false);
+    $option.prop('selected', data.selected || false);
 
     // Get any automatically generated data values
     var detectedData = this.item($option);
@@ -174,6 +175,8 @@ define([
         data._resultId = this.generateResultId(this.container, data);
       }
 
+      data.selected = $option.prop('selected');
+
       $option.data('data', data);
     }
 

+ 20 - 4
tests/data/array-tests.js

@@ -29,8 +29,16 @@ test('current gets default for single', function (assert) {
   data.current(function (val) {
     assert.equal(
       val.length,
-      0,
-      'There should be no default selection.'
+      1,
+      'There should always be a selected item for array data.'
+    );
+
+    var item = val[0];
+
+    assert.equal(
+      item.id,
+      'default',
+      'The first item should be selected'
     );
   });
 });
@@ -117,14 +125,22 @@ test('select works for single', function (assert) {
 
   var data = new ArrayData($select, options);
 
-  assert.equal($select.val(), null);
+  assert.equal(
+    $select.val(),
+    'default',
+    'There should already be a selection'
+  );
 
   data.select({
     id: '1',
     text: 'One'
   });
 
-  assert.equal($select.val(), '1');
+  assert.equal(
+    $select.val(),
+    '1',
+    'The selected value should be the same as the selected id'
+  );
 });
 
 test('multiple sets the value', function (assert) {

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است