Browse Source

Add scrollAfterSelect as a configurable option for multiselect dropdowns to allow toggling of highlightFirstItem() behaviour (#5150)

* Add scrollOnSelect as a configurable option

* default scrollOnSelect to true to avoid modifying existing behaviour

* added tests and default option for scrollAfterSelect
Bowei Han 6 years ago
parent
commit
2b049c08ab
3 changed files with 112 additions and 2 deletions
  1. 1 0
      src/js/select2/defaults.js
  2. 8 2
      src/js/select2/results.js
  3. 103 0
      tests/results/focusing-tests.js

+ 1 - 0
src/js/select2/defaults.js

@@ -365,6 +365,7 @@ define([
       maximumSelectionLength: 0,
       minimumResultsForSearch: 0,
       selectOnClose: false,
+      scrollAfterSelect: true,
       sorter: function (data) {
         return data;
       },

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

@@ -276,7 +276,10 @@ define([
       }
 
       self.setClasses();
-      self.highlightFirstItem();
+
+      if (self.options.get('scrollAfterSelect')) {
+        self.highlightFirstItem();
+      }
     });
 
     container.on('unselect', function () {
@@ -285,7 +288,10 @@ define([
       }
 
       self.setClasses();
-      self.highlightFirstItem();
+
+      if (self.options.get('scrollAfterSelect')) {
+        self.highlightFirstItem();
+      }
     });
 
     container.on('open', function () {

+ 103 - 0
tests/results/focusing-tests.js

@@ -135,4 +135,107 @@ test('results:append does not trigger results:focus', function (assert) {
       ]
     }
   });
+});
+
+test('scrollAfterSelect triggers results:focus by default', function (assert) {
+  assert.expect(3);
+
+  var $ = require('jquery');
+
+  var $select = $('<select></select>');
+  var $parent = $('<div></div>');
+
+  var $container = $('<span></span>');
+  var container = new MockContainer();
+
+  $parent.appendTo($('#qunit-fixture'));
+  $select.appendTo($parent);
+
+  var Utils = require('select2/utils');
+  var Options = require('select2/options');
+
+  var Results = require('select2/results');
+
+  var options = new Options({});
+  var results = new Results($select, options);
+
+  // Fake the data adapter for the `setClasses` method
+  results.data = {};
+  results.data.current = function (callback) {
+    callback([{ id: 'test' }]);
+  };
+
+  results.render();
+
+  results.bind(container, $container);
+
+  // check that default for scrollAfterSelect is true
+  assert.equal(options.get('scrollAfterSelect'), true);
+
+  results.append({
+    results: [
+      {
+        id: 'test',
+        text: 'Test'
+      }
+    ]
+  });
+
+  results.on('results:focus', function (params) {
+    assert.equal(params.data.id, 'test');
+    assert.equal(params.data.text, 'Test');
+  });
+
+  container.trigger('select', {});
+});
+
+test('!scrollAfterSelect does not trigger results:focus', function (assert) {
+  assert.expect(1);
+
+  var $ = require('jquery');
+
+  var $select = $('<select></select>');
+  var $parent = $('<div></div>');
+
+  var $container = $('<span></span>');
+  var container = new MockContainer();
+
+  $parent.appendTo($('#qunit-fixture'));
+  $select.appendTo($parent);
+
+  var Utils = require('select2/utils');
+  var Options = require('select2/options');
+
+  var Results = require('select2/results');
+
+  var options = new Options({ scrollAfterSelect: false });
+  var results = new Results($select, options);
+
+  // Fake the data adapter for the `setClasses` method
+  results.data = {};
+  results.data.current = function (callback) {
+    callback([{ id: 'test' }]);
+  };
+
+  results.render();
+
+  results.bind(container, $container);
+
+  // check that default for scrollAfterSelect is false
+  assert.equal(options.get('scrollAfterSelect'), false);
+
+  results.append({
+    results: [
+      {
+        id: 'test',
+        text: 'Test'
+      }
+    ]
+  });
+
+  results.on('results:focus', function () {
+    assert.ok(false, 'The results:focus event was triggered');
+  });
+
+  container.trigger('select', {});
 });