Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ajax datasources: remove locally-cached 'option' HTML element during item unselection #6282

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
8 changes: 8 additions & 0 deletions src/js/select2/data/select.js
Expand Up @@ -70,6 +70,14 @@ define([
SelectAdapter.prototype.unselect = function (data) {
var self = this;

// Remote-origin (AJAX) items: remove matching option elements from the DOM
if (this.options.get('ajax')) {
var $option = this.$element.find('option').filter(function (i, elm) {
return elm.value == data.id.toString();
});
$option.remove();
}

if (!this.$element.prop('multiple')) {
return;
}
Expand Down
1 change: 1 addition & 0 deletions tests/integration-jq1.html
Expand Up @@ -10,6 +10,7 @@

<script src="vendor/qunit-1.23.1.js" type="text/javascript"></script>
<script src="vendor/jquery-1.12.4.js" type="text/javascript"></script>
<script src="vendor/jquery.mockjax-2.6.0.js" type="text/javascript"></script>
<script src="../dist/js/select2.full.js" type="text/javascript"></script>

<script src="helpers.js" type="text/javascript"></script>
Expand Down
1 change: 1 addition & 0 deletions tests/integration-jq2.html
Expand Up @@ -10,6 +10,7 @@

<script src="vendor/qunit-1.23.1.js" type="text/javascript"></script>
<script src="vendor/jquery-2.2.4.js" type="text/javascript"></script>
<script src="vendor/jquery.mockjax-2.6.0.js" type="text/javascript"></script>
<script src="../dist/js/select2.full.js" type="text/javascript"></script>

<script src="helpers.js" type="text/javascript"></script>
Expand Down
1 change: 1 addition & 0 deletions tests/integration-jq3.html
Expand Up @@ -10,6 +10,7 @@

<script src="vendor/qunit-1.23.1.js" type="text/javascript"></script>
<script src="vendor/jquery-3.4.1.js" type="text/javascript"></script>
<script src="vendor/jquery.mockjax-2.6.0.js" type="text/javascript"></script>
<script src="../dist/js/select2.full.js" type="text/javascript"></script>

<script src="helpers.js" type="text/javascript"></script>
Expand Down
84 changes: 84 additions & 0 deletions tests/integration/select2-methods.js
Expand Up @@ -137,3 +137,87 @@ test('multiple value matches the jquery value', function (assert) {
'The values should match the jquery values'
);
});

test('selection and clearing of data from ajax source', function (assert) {
jayaddison marked this conversation as resolved.
Show resolved Hide resolved
var asyncDone = assert.async();

var dataURL = 'http://127.0.0.1/test';
$.mockjax({
url: dataURL,
response: function (settings) {
this.responseText = {results: [{id: 6128, text: settings.data.term}]};
},
logging: 1
});

var $container = $('#qunit-fixture');
var $select = $('<select></select>');
$container.append($select);

var select = new Select2($select, {ajax: {url: dataURL}, multiple: true});

assert.equal(
$select.find(':selected').length,
0,
'No items should be selected'
);

var queryTerms = ['firstQuery', 'secondQuery', 'thirdQuery', 'fourthQuery'];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a really smelly way to achieve multiple visits and actions on the select2 control. My JavaScript-fu isn't great, so there's almost certainly a better way to do this.

var queryTerm = queryTerms.shift();

// Open the dropdown menu, to perform an AJAX request
select.selection.trigger('query', {term: 'firstResult'});

select.on('results:all', function() {

// First call: select a result from the dropdown menu
if (queryTerm == 'firstQuery') {

$('.select2-results__option').trigger('mouseup');
assert.equal(
$select.find('option').length,
1,
'An HTML option element should have been created for the item'
);

// Trigger a second call
select.selection.trigger('query', {term: 'secondResult'});

// Second call: unselect the previously-selected item
} else if (queryTerm == 'secondQuery') {

$('.select2-results__option[aria-selected=true]').trigger('mouseup');
assert.equal(
$select.find('option').length,
0,
'The previously-created HTML option element should have been removed'
);

// Trigger a third call
select.selection.trigger('query', {term: 'thirdResult'});

// Third call: (re)select the item, which has updated text 'thirdResult'
} else if (queryTerm == 'thirdQuery') {
$('.select2-results__option').trigger('mouseup');
assert.equal(
$select.find('option').length,
1,
'An HTML option element should have been created for the item'
);

// Trigger a fourth call
select.selection.trigger('query', {term: 'fourthResult'});

// Fourth call: assert that the updated text is in place
} else if (queryTerm == 'fourthQuery') {
assert.equal(
$select.find('option:selected').text(),
'thirdResult'
);

asyncDone();
}

queryTerm = queryTerms.shift();
});
});