fix unique dropdown for multi-select select boxes

This commit is contained in:
alex 2020-04-20 21:50:55 +02:00
parent 36a5a0bd67
commit 561a61de0f
3 changed files with 59 additions and 7 deletions

View file

@ -282,6 +282,41 @@ describe('Choices - select multiple', () => {
});
});
describe('unique values only', () => {
describe('unique values', () => {
beforeEach(() => {
cy.get('[data-test-hook=unique-values]')
.find('.choices__input--cloned')
.type('Choice 1')
.type('{enter}');
});
it('only allows me to input unique values', () => {
cy.get('[data-test-hook=unique-values]')
.find('.choices__list--multiple')
.first()
.children()
.should($items => {
expect($items.length).to.equal(1);
});
});
describe('inputting a non-unique value', () => {
it('displays dropdown prompt', () => {
cy.get('[data-test-hook=unique-values]')
.find('.choices__list--dropdown')
.should('be.visible')
.should($dropdown => {
const dropdownText = $dropdown.text().trim();
expect(dropdownText).to.equal(
'Only unique values can be added',
);
});
});
});
});
});
describe('disabled choice', () => {
describe('selecting a disabled choice', () => {
beforeEach(() => {

View file

@ -88,6 +88,22 @@
</select>
</div>
<div data-test-hook="unique-values">
<label for="choices-unique-values">Unique values</label>
<select
class="form-control"
name="choices-unique-values"
id="choices-unique-values"
multiple
>
<option value="Choice 1" selected>Choice 1</option>
<option value="Choice 1">Choice 1</option>
<option value="Choice 2">Choice 2</option>
<option value="Choice 3">Choice 3</option>
<option value="Choice 4">Choice 4</option>
</select>
</div>
<div data-test-hook="disabled-choice">
<label for="choices-disabled-choice">Disabled choice</label>
<select
@ -437,6 +453,9 @@
new Choices('#choices-disabled-choice', {
allowHTML: true,
});
new Choices('#choices-unique-values', {
duplicateItemsAllowed: false,
});
new Choices('#choices-add-items', {
addItems: true,

View file

@ -3,11 +3,11 @@ import merge from 'deepmerge';
import Fuse from 'fuse.js';
import {
Result,
activateChoices,
addChoice,
clearChoices,
filterChoices,
Result,
} from './actions/choices';
import { addGroup } from './actions/groups';
import { addItem, highlightItem, removeItem } from './actions/items';
@ -35,7 +35,6 @@ import { Notice } from './interfaces/notice';
import { Options } from './interfaces/options';
import { PassedElement } from './interfaces/passed-element';
import { State } from './interfaces/state';
import {
diff,
existsInArray,
@ -44,9 +43,9 @@ import {
getType,
isScrolledIntoView,
isType,
parseCustomProperties,
sortByScore,
strToEl,
parseCustomProperties,
} from './lib/utils';
import { defaultState } from './reducers';
import Store from './store/store';
@ -1555,13 +1554,12 @@ class Choices implements Choices {
const { activeItems } = this._store;
const canAddItem = this._canAddItem(activeItems, value);
const { BACK_KEY: backKey, DELETE_KEY: deleteKey } = KEY_CODES;
const canShowDropdownNotice =
this.config.addItems && canAddItem.notice && value;
// We are typing into a text input and have a value, we want to show a dropdown
// notice. Otherwise hide the dropdown
if (this._isTextElement) {
const canShowDropdownNotice =
this.config.addItems && canAddItem.notice && value;
if (canShowDropdownNotice) {
const dropdownItem = this._getTemplate('notice', canAddItem.notice);
this.dropdown.element.innerHTML = dropdownItem.outerHTML;
@ -1579,7 +1577,7 @@ class Choices implements Choices {
if (userHasRemovedValue && canReactivateChoices) {
this._isSearching = false;
this._store.dispatch(activateChoices(true));
} else if (canSearch) {
} else if (canSearch || canShowDropdownNotice) {
this._handleSearch(this.input.rawValue);
}
}