placeholder in single select should be always first choice, regardless of sorting

This commit is contained in:
Adam Mockor 2017-04-05 17:11:09 +02:00
parent 055505e1e7
commit 8679871bfd
3 changed files with 47 additions and 9 deletions

View file

@ -312,12 +312,26 @@ class Choices {
const choicesFragment = fragment || document.createDocumentFragment();
const filter = this.isSearching ? sortByScore : this.config.sortFilter;
// Split array into placeholedrs and "normal" choices
const { placeholderChoices, normalChoices } = choices.reduce((acc, choice) => {
if (choice.placeholder) {
acc.placeholderChoices.push(choice);
} else {
acc.normalChoices.push(choice);
}
return acc;
}, { placeholderChoices: [], normalChoices: [] });
// If sorting is enabled or the user is searching, filter choices
// Do not sort placeholder
if (this.config.shouldSort || this.isSearching) {
choices.sort(filter);
normalChoices.sort(filter);
}
choices.forEach((choice) => {
// Prepend placeholedr
const sortedChoices = [...placeholderChoices, ...normalChoices];
sortedChoices.forEach((choice) => {
const dropdownItem = this._getTemplate('choice', choice);
const shouldRender = this.passedElement.type === 'select-one' || !choice.selected;
if (shouldRender) {
@ -2341,18 +2355,32 @@ class Choices {
});
});
// Split array into placeholedrs and "normal" choices
const { placeholderChoices, normalChoices } = allChoices.reduce((acc, choice) => {
if (choice.placeholder) {
acc.placeholderChoices.push(choice);
} else {
acc.normalChoices.push(choice);
}
return acc;
}, { placeholderChoices: [], normalChoices: [] });
// If sorting is enabled or the user is searching, filter choices
// Do not sort placeholder
if (this.config.shouldSort) {
allChoices.sort(filter);
normalChoices.sort(filter);
}
// Prepend placeholder
const sortedChoices = [...placeholderChoices, ...normalChoices];
// Determine whether there is a selected choice
const hasSelectedChoice = allChoices.some((choice) => {
const hasSelectedChoice = sortedChoices.some((choice) => {
return choice.selected === true;
});
// Add each choice
allChoices.forEach((choice, index) => {
sortedChoices.forEach((choice, index) => {
const isDisabled = choice.disabled ? choice.disabled : false;
const isSelected = choice.selected ? choice.selected : false;
// Pre-select first choice if it's a single select

View file

@ -146,7 +146,6 @@
<h2>Single select input</h2>
<label for="choices-single-default">Default</label>
<select class="form-control" data-trigger name="choices-single-default" id="choices-single-default">
<option selected disabled>This is a placeholder</option>
<option value="Dropdown item 1">Dropdown item 1</option>
<option value="Dropdown item 2">Dropdown item 2</option>
<option value="Dropdown item 3">Dropdown item 3</option>
@ -236,7 +235,7 @@
<label for="choices-placeholder-option">Placeholder option</label>
<select class="form-control" name="choices-placeholder-option" id="choices-placeholder-option">
<option selected placeholder>Press here</option>
<option selected placeholder disabled>Press here</option>
<option value="one">One</option>
<option value="two">Two</option>
<option value="three">Three</option>

View file

@ -256,7 +256,6 @@ describe('Choices', () => {
beforeEach(function() {
this.input = document.createElement('select');
this.input.className = 'js-choices';
this.input.placeholder = 'Placeholder text';
for (let i = 1; i < 4; i++) {
const option = document.createElement('option');
@ -407,7 +406,7 @@ describe('Choices', () => {
expect(showDropdownSpy).toHaveBeenCalled();
});
it('should trigger hideDropdown on dropdown closing', function() {
it('should trigger hideDropdown on dropdown closing', function() {
this.choices = new Choices(this.input);
const container = this.choices.containerOuter;
@ -492,6 +491,18 @@ it('should trigger hideDropdown on dropdown closing', function() {
expect(this.choices.currentState.choices[0].value).toEqual('Value 1');
});
it('should set placeholder as first option if shouldSort true', function() {
const option = document.createElement('option');
option.setAttribute('selected', '');
option.setAttribute('placeholder', '');
option.setAttribute('disabled', '');
option.innerHTML = 'Placeholder';
this.input.appendChild(option);
this.choices = new Choices(this.input, { shouldSort: true });
expect(this.choices.currentState.choices[0].value).toEqual('Placeholder');
});
});
describe('should accept multiple select inputs', function() {