Selaa lähdekoodia

Trigger the `unselect` event when clearing placeholder

In the past, Select2 triggered the `select2-clearing` event when
clearing the placeholder. This has been switched to the `unselect`
event which is now triggered whenever the placeholder is cleared.
The placeholder can also be prevented if the `unselecting` event
is prevented.

This will also trigger the event when deleting every option from
the multiple select, so it is possible for the `unselecting` event
to be triggered multiple times when clearing a multiple select.

This adds tests to ensure that the `allowClear` option always works.

This closes https://github.com/select2/select2/issues/2954.
Kevin Brown 10 vuotta sitten
vanhempi
commit
d81886e5de

+ 18 - 0
dist/js/select2.amd.full.js

@@ -1102,6 +1102,23 @@ define('select2/selection/allowClear',[
 
         evt.stopPropagation();
 
+        var data = $(this).data('data');
+
+        for (var d = 0; d < data.length; d++) {
+          var unselectData = {
+            data: data[d]
+          };
+
+          // Trigger the `unselect` event, so people can prevent it from being
+          // cleared.
+          self.trigger('unselect', unselectData);
+
+          // If the event was prevented, don't clear it out.
+          if (unselectData.prevented) {
+            return;
+          }
+        }
+
         self.$element.val(self.placeholder.id).trigger('change');
 
         self.trigger('toggle');
@@ -1121,6 +1138,7 @@ define('select2/selection/allowClear',[
         '&times;' +
       '</span>'
     );
+    $remove.data('data', data);
 
     this.$selection.find('.select2-selection__rendered').append($remove);
   };

+ 18 - 0
dist/js/select2.amd.js

@@ -1102,6 +1102,23 @@ define('select2/selection/allowClear',[
 
         evt.stopPropagation();
 
+        var data = $(this).data('data');
+
+        for (var d = 0; d < data.length; d++) {
+          var unselectData = {
+            data: data[d]
+          };
+
+          // Trigger the `unselect` event, so people can prevent it from being
+          // cleared.
+          self.trigger('unselect', unselectData);
+
+          // If the event was prevented, don't clear it out.
+          if (unselectData.prevented) {
+            return;
+          }
+        }
+
         self.$element.val(self.placeholder.id).trigger('change');
 
         self.trigger('toggle');
@@ -1121,6 +1138,7 @@ define('select2/selection/allowClear',[
         '&times;' +
       '</span>'
     );
+    $remove.data('data', data);
 
     this.$selection.find('.select2-selection__rendered').append($remove);
   };

+ 18 - 0
dist/js/select2.full.js

@@ -10637,6 +10637,23 @@ define('select2/selection/allowClear',[
 
         evt.stopPropagation();
 
+        var data = $(this).data('data');
+
+        for (var d = 0; d < data.length; d++) {
+          var unselectData = {
+            data: data[d]
+          };
+
+          // Trigger the `unselect` event, so people can prevent it from being
+          // cleared.
+          self.trigger('unselect', unselectData);
+
+          // If the event was prevented, don't clear it out.
+          if (unselectData.prevented) {
+            return;
+          }
+        }
+
         self.$element.val(self.placeholder.id).trigger('change');
 
         self.trigger('toggle');
@@ -10656,6 +10673,7 @@ define('select2/selection/allowClear',[
         '&times;' +
       '</span>'
     );
+    $remove.data('data', data);
 
     this.$selection.find('.select2-selection__rendered').append($remove);
   };

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


+ 18 - 0
dist/js/select2.js

@@ -1530,6 +1530,23 @@ define('select2/selection/allowClear',[
 
         evt.stopPropagation();
 
+        var data = $(this).data('data');
+
+        for (var d = 0; d < data.length; d++) {
+          var unselectData = {
+            data: data[d]
+          };
+
+          // Trigger the `unselect` event, so people can prevent it from being
+          // cleared.
+          self.trigger('unselect', unselectData);
+
+          // If the event was prevented, don't clear it out.
+          if (unselectData.prevented) {
+            return;
+          }
+        }
+
         self.$element.val(self.placeholder.id).trigger('change');
 
         self.trigger('toggle');
@@ -1549,6 +1566,7 @@ define('select2/selection/allowClear',[
         '&times;' +
       '</span>'
     );
+    $remove.data('data', data);
 
     this.$selection.find('.select2-selection__rendered').append($remove);
   };

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


+ 18 - 0
src/js/select2/selection/allowClear.js

@@ -17,6 +17,23 @@ define([
 
         evt.stopPropagation();
 
+        var data = $(this).data('data');
+
+        for (var d = 0; d < data.length; d++) {
+          var unselectData = {
+            data: data[d]
+          };
+
+          // Trigger the `unselect` event, so people can prevent it from being
+          // cleared.
+          self.trigger('unselect', unselectData);
+
+          // If the event was prevented, don't clear it out.
+          if (unselectData.prevented) {
+            return;
+          }
+        }
+
         self.$element.val(self.placeholder.id).trigger('change');
 
         self.trigger('toggle');
@@ -36,6 +53,7 @@ define([
         '&times;' +
       '</span>'
     );
+    $remove.data('data', data);
 
     this.$selection.find('.select2-selection__rendered').append($remove);
   };

+ 218 - 0
tests/selection/allowClear-tests.js

@@ -0,0 +1,218 @@
+module('Selection containers - Placeholders - Allow clear');
+
+var Placeholder = require('select2/selection/placeholder');
+var AllowClear = require('select2/selection/allowClear');
+
+var SingleSelection = require('select2/selection/single');
+
+var $ = require('jquery');
+var Options = require('select2/options');
+var Utils = require('select2/utils');
+
+var SinglePlaceholder = Utils.Decorate(
+  Utils.Decorate(SingleSelection, Placeholder),
+  AllowClear
+);
+
+var options = new Options({
+  placeholder: {
+    id: 'placeholder',
+    text: 'This is the placeholder'
+  },
+  allowClear: true
+});
+
+test('clear is not displayed for single placeholder', function (assert) {
+  var selection = new SinglePlaceholder(
+    $('#qunit-fixture .single'),
+    options
+  );
+
+  var $selection = selection.render();
+
+  selection.update([{
+    id: 'placeholder'
+  }]);
+
+  assert.equal(
+    $selection.find('.select2-selection__clear').length,
+    0,
+    'The clear icon should not be displayed'
+  );
+});
+
+test('clear is not displayed for multiple placeholder', function (assert) {
+  var selection = new SinglePlaceholder(
+    $('#qunit-fixture .single'),
+    options
+  );
+
+  var $selection = selection.render();
+
+  selection.update([]);
+
+  assert.equal(
+    $selection.find('.select2-selection__clear').length,
+    0,
+    'The clear icon should not be displayed'
+  );
+});
+
+
+test('clear is displayed for placeholder', function (assert) {
+  var selection = new SinglePlaceholder(
+    $('#qunit-fixture .single'),
+    options
+  );
+
+  var $selection = selection.render();
+
+  selection.update([{
+    id: 'one',
+    test: 'one'
+  }]);
+
+  assert.equal(
+    $selection.find('.select2-selection__clear').length,
+    1,
+    'The clear icon should be displayed'
+  );
+});
+
+test('clicking clear will set the placeholder value', function (assert) {
+  var $element = $('#qunit-fixture .single');
+
+  var selection = new SinglePlaceholder(
+    $element,
+    options
+  );
+  var container = new MockContainer();
+
+  var $selection = selection.render();
+
+  selection.bind(container, $('<div></div'));
+
+  $element.val('One');
+  selection.update([{
+    id: 'One',
+    text: 'One'
+  }]);
+
+  var $remove = $selection.find('.select2-selection__clear');
+  $remove.trigger('mousedown');
+
+  assert.equal(
+    $element.val(),
+    'placeholder',
+    'The value should have been reset to the placeholder'
+  );
+});
+
+test('clicking clear will trigger the unselect event', function (assert) {
+  expect(3);
+
+  var $element = $('#qunit-fixture .single');
+
+  var selection = new SinglePlaceholder(
+    $element,
+    options
+  );
+  var container = new MockContainer();
+
+  var $selection = selection.render();
+
+  selection.bind(container, $('<div></div'));
+
+  $element.val('One');
+  selection.update([{
+    id: 'One',
+    text: 'One'
+  }]);
+
+  selection.on('unselect', function (ev) {
+    assert.ok(
+      'data' in ev && ev.data,
+      'The event should have been triggered with the data property'
+    );
+
+    assert.ok(
+      $.isPlainObject(ev.data),
+      'The data should be an object'
+    );
+
+    assert.equal(
+      ev.data.id,
+      'One',
+      'The previous object should be unselected'
+    );
+  });
+
+  var $remove = $selection.find('.select2-selection__clear');
+  $remove.trigger('mousedown');
+});
+
+
+
+test('preventing the unselect event cancels the clearing', function (assert) {
+  var $element = $('#qunit-fixture .single');
+
+  var selection = new SinglePlaceholder(
+    $element,
+    options
+  );
+  var container = new MockContainer();
+
+  var $selection = selection.render();
+
+  selection.bind(container, $('<div></div'));
+
+  $element.val('One');
+  selection.update([{
+    id: 'One',
+    text: 'One'
+  }]);
+
+  selection.on('unselect', function (ev) {
+    ev.prevented = true;
+  });
+
+  var $remove = $selection.find('.select2-selection__clear');
+  $remove.trigger('mousedown');
+
+  assert.equal(
+    $element.val(),
+    'One',
+    'The placeholder should not have been set'
+  );
+});
+
+test('clear does not work when disabled', function (assert) {
+  var $element = $('#qunit-fixture .single');
+
+  var selection = new SinglePlaceholder(
+    $element,
+    options
+  );
+  var container = new MockContainer();
+
+  var $selection = selection.render();
+
+  selection.bind(container, $('<div></div'));
+
+  selection.update([{
+    id: 'One',
+    text: 'One'
+  }]);
+
+  $element.val('One');
+  selection.options.set('disabled', true);
+
+  var $remove = $selection.find('.select2-selection__clear');
+  $remove.trigger('mousedown');
+
+  assert.equal(
+    $element.val(),
+    'One',
+    'The placeholder should not have been set'
+  );
+});

+ 29 - 0
tests/selection/allowClear.html

@@ -0,0 +1,29 @@
+<!doctype html>
+<html>
+  <head>
+    <link rel="stylesheet" href="../vendor/qunit-1.14.0.css" type="text/css" />
+    <link rel="stylesheet" href="../../dist/css/select2.css" type="text/css" />
+  </head>
+  <body>
+    <div id="qunit"></div>
+    <div id="qunit-fixture">
+      <select class="single">
+        <option>placeholder</option>
+        <option>One</option>
+      </select>
+
+      <select class="multiple" multiple="multiple">
+        <option>One</option>
+      </select>
+    </div>
+
+    <script src="../vendor/qunit-1.14.0.js" type="text/javascript"></script>
+    <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.amd.js" type="text/javascript"></script>
+
+    <script src="../mock.js" type="text/javascript"></script>
+
+    <script src="allowClear-tests.js" type="text/javascript"></script>
+  </body>
+</html>

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