Skip to content

Commit

Permalink
if a <select> is cleared, the underlying <select> needs an empty opti…
Browse files Browse the repository at this point in the history
…on . #98
  • Loading branch information
oyejorge committed May 20, 2021
1 parent 628e355 commit 505cc71
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 23 deletions.
35 changes: 32 additions & 3 deletions doc_src/pages/plugins/clear-button.njk
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,13 @@ tags: demo

{% set label %}
<label class="h2 mb-3">
Example
Select Multiple
</label>
{% endset %}



{% set html %}
<input type="text" id="clear-button" value="awesome,neat" autocomplete="off">
<input type="text" id="clear-button" value="awesome,neat" autocomplete="off" placeholder="How cool is this?" />
{% endset %}

<script>
Expand All @@ -39,6 +38,36 @@ new TomSelect('#clear-button',{
{{ demo( label, html, script) }}


{% set label %}
<label class="h2 mb-3">
Select Single
</label>
{% endset %}


{% set html %}
<select type="text" id="clear-button-single" autocomplete="off">
<option value="">How cool is this?</option>
<option selected>awesome</option>
<option>neat</option>
</select>
{% endset %}

<script>
{% set script %}
new TomSelect('#clear-button-single',{
maxItems:1,
plugins: ['clear_button'],
persist: false,
create: true,
});
{% endset %}
</script>


{{ demo( label, html, script) }}


<h2>Plugin Configuration</h2>

{{ config_table([
Expand Down
44 changes: 28 additions & 16 deletions src/tom-select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2011,32 +2011,44 @@ export default class TomSelect extends MicroPlugin(MicroEvent){
*
*/
updateOriginalInput( opts:TomArgObject = {} ){
var i, value, option, self = this;
const self = this;
var i, value, option, option_el, label;

if( self.is_select_tag ){

function AddSelected(option_el:HTMLOptionElement|null, value:string, label:string):HTMLOptionElement{

if( !option_el ){
option_el = getDom('<option value="' + escape_html(value) + '">' + escape_html(label) + '</option>');
}

option_el.selected = true;
setAttr(option_el,{selected:'true'});
self.input.prepend(option_el);

return option_el;
}

// remove selected attribute from options whose values are not in self.items
self.input.querySelectorAll('option[selected]').forEach((option:HTMLOptionElement) => {
if( self.items.indexOf(option.value) == -1 ){
option.selected = false;
option.removeAttribute('selected');
self.input.querySelectorAll('option[selected]').forEach((option_el:HTMLOptionElement) => {
if( self.items.indexOf(option_el.value) == -1 ){
option_el.removeAttribute('selected');
option_el.selected = false;
}
});

// order selected <option> tags for values in self.items
for( i = self.items.length - 1; i >= 0; i-- ){
value = self.items[i];

var option = self.options[value].$option;
if( !option ){
const label = self.options[value][self.settings.labelField] || '';
option = getDom('<option value="' + escape_html(value) + '">' + escape_html(label) + '</option>');
self.options[value].$option = option;
}
value = self.items[i];
option = self.options[value];
label = option[self.settings.labelField] || '';
option.$option = AddSelected(option.$option, value, label);
}

option.selected = true;
setAttr(option,{selected:'true'});
self.input.prepend(option);
// nothing selected?
if( self.items.length == 0 && self.settings.mode == 'single' && !self.isRequired ){
option_el = self.input.querySelector('option[value=""]');
AddSelected(option_el, "", "");
}

} else {
Expand Down
30 changes: 26 additions & 4 deletions test/tests/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -681,10 +681,9 @@
});

describe('clear()', function() {
var test;

beforeEach(function() {
test = setup_test('<select multiple>', {
function clearTest(){
return setup_test('<select multiple>', {
valueField: 'value',
labelField: 'value',
options: [
Expand All @@ -695,13 +694,16 @@
],
items: ['1','2','3']
});
});
}

it_n('should empty "activeItems" array', function() {
var test = clearTest();
test.instance.setActiveItem(test.instance.getItem('1'));
expect(test.instance.activeItems.length).to.be.equal(1);
test.instance.clear();
expect(test.instance.activeItems.length).to.be.equal(0);
});

it_n('should refresh option list (dropdown)', function(done) {
// test = setup_test('<select multiple>', {
// valueField: 'value',
Expand All @@ -715,6 +717,7 @@
// items: ['1','2','3']
// });

var test = clearTest();
test.instance.focus();
window.setTimeout(function() {
test.instance.clear();
Expand All @@ -727,17 +730,23 @@
}, 0);
}, 0);
});

it_n('should empty "items" array', function() {
var test = clearTest();
test.instance.clear();
expect(test.instance.items.length).to.be.equal(0);
});

it_n('should update DOM (3)', function() {
var test = clearTest();
test.instance.clear();
expect( test.instance.control.querySelectorAll('[data-value="1"]').length).to.be.equal(0);
expect( test.instance.control.querySelectorAll('[data-value="2"]').length).to.be.equal(0);
expect( test.instance.control.querySelectorAll('[data-value="3"]').length).to.be.equal(0);
});

it_n('should not fire "change" if silent is truthy', function(done) {
var test = clearTest();
var watcher = function(e) { throw new Error('Change fired'); };
test.instance.on('change', watcher);
test.instance.clear(true);
Expand All @@ -746,17 +755,30 @@
done();
}, 0);
});

it_n('should not give control focus', function(done) {
var test = clearTest();
test.instance.clear();
window.setTimeout(function() {
expect(test.instance.isFocused).to.be.equal(false);
done();
}, 0);
});

it_n('should empty "items" array', function() {
var test = clearTest();
test.instance.clear();
expect(test.instance.items.length).to.be.equal(0);
});

it_n('should create empty option and el.value should be empty after clear() on single', async function(){
var test = setup_test('<select><option>a</option></select>');
await asyncClick(test.instance.control);
test.instance.clear();
assert.isEmpty(test.$select[0].value);
assert.isOk(test.instance.input.querySelector('option[value=""]'));
});

});

describe('search()', function() {
Expand Down

0 comments on commit 505cc71

Please sign in to comment.