Add clearItems method + update setChoices

This commit is contained in:
Josh Johnson 2019-11-28 21:12:33 +00:00
parent 862e1a52eb
commit 9be164e2e5
4 changed files with 125 additions and 51 deletions

View file

@ -824,12 +824,6 @@ choices.setValue(['Set value 1', 'Set value 2']);
choices.disable();
```
### destroy();
**Input types affected:** `text`, `select-multiple`, `select-one`
**Usage:** Kills the instance of Choices, removes all event listeners and returns passed input to its initial state.
### init();
**Input types affected:** `text`, `select-multiple`, `select-one`
@ -838,6 +832,12 @@ choices.disable();
**Note:** This is called implicitly when a new instance of Choices is created. This would be used after a Choices instance had already been destroyed (using `destroy()`).
### destroy();
**Input types affected:** `text`, `select-multiple`, `select-one`
**Usage:** Kills the instance of Choices, removes all event listeners and returns passed input to its initial state.
### highlightAll();
**Input types affected:** `text`, `select-multiple`
@ -880,7 +880,7 @@ choices.disable();
**Usage:** Hide option list dropdown (only affects select inputs).
### setChoices(choices, value, label, replaceChoices);
### setChoices(choices[, value[, label[, replaceChoices[, replaceItems]]]]);
**Input types affected:** `select-one`, `select-multiple`
@ -902,6 +902,7 @@ example.setChoices(
'value',
'label',
false,
true,
);
```
@ -959,6 +960,7 @@ example.setChoices(
'value',
'label',
false,
true,
);
```
@ -968,6 +970,12 @@ example.setChoices(
**Usage:** Clear all choices from select
### clearItems();
**Input types affected:** `select-one`, `select-multiple`
**Usage:** Clear all items from select
### getValue(valueOnly)
**Input types affected:** `text`, `select-one`, `select-multiple`

View file

@ -25,7 +25,12 @@ import {
activateChoices,
clearChoices,
} from './actions/choices';
import { addItem, removeItem, highlightItem } from './actions/items';
import {
addItem,
removeItem,
highlightItem,
clearItems,
} from './actions/items';
import { addGroup } from './actions/groups';
import { clearAll, resetTo, setIsLoading } from './actions/misc';
import {
@ -496,7 +501,8 @@ class Choices {
* @param {T} [choicesArrayOrFetcher]
* @param {string} [value = 'value'] - name of `value` field
* @param {string} [label = 'label'] - name of 'label' field
* @param {boolean} [replaceChoices = false] - whether to replace of add choices
* @param {boolean} [replaceChoices = false] - whether to clear existing choices
* @param {boolean} [replaceItems = false] - whether to clear existing items
* @returns {this | Promise<this>}
*
* @example
@ -558,6 +564,7 @@ class Choices {
value = 'value',
label = 'label',
replaceChoices = false,
replaceItems = false,
) {
if (!this.initialised) {
throw new ReferenceError(
@ -574,11 +581,14 @@ class Choices {
);
}
// Clear choices if needed
if (replaceChoices) {
this.clearChoices();
}
if (replaceItems) {
this.clearItems();
}
if (typeof choicesArrayOrFetcher === 'function') {
// it's a choices fetcher function
const fetcher = choicesArrayOrFetcher(this);
@ -589,7 +599,9 @@ class Choices {
return new Promise(resolve => requestAnimationFrame(resolve))
.then(() => this._handleLoadingState(true))
.then(() => fetcher)
.then(data => this.setChoices(data, value, label, replaceChoices))
.then(data =>
this.setChoices(data, value, label, replaceChoices, replaceItems),
)
.catch(err => {
if (!this.config.silent) {
console.error(err);
@ -651,6 +663,12 @@ class Choices {
return this;
}
clearItems() {
this._store.dispatch(clearItems());
return this;
}
clearStore() {
this._store.dispatch(clearAll());

View file

@ -28,12 +28,6 @@ describe('choices', () => {
instance = null;
});
const returnsInstance = () => {
it('returns this', () => {
expect(output).to.eql(instance);
});
};
describe('constructor', () => {
describe('config', () => {
describe('not passing config options', () => {
@ -88,6 +82,7 @@ describe('choices', () => {
`;
instance = new Choices('[data-choice]', {
// @ts-ignore
renderSelectedChoices: 'test',
});
@ -423,7 +418,9 @@ describe('choices', () => {
output = instance.enable();
});
returnsInstance(output);
it('returns this', () => {
expect(output).to.eql(instance);
});
it('returns early', () => {
expect(passedElementEnableSpy.called).to.equal(false);
@ -481,7 +478,9 @@ describe('choices', () => {
output = instance.disable();
});
returnsInstance(output);
it('returns this', () => {
expect(output).to.eql(instance);
});
it('returns early', () => {
expect(removeEventListenersSpy.called).to.equal(false);
@ -638,7 +637,9 @@ describe('choices', () => {
output = instance.hideDropdown();
});
returnsInstance(output);
it('returns this', () => {
expect(output).to.eql(instance);
});
it('returns early', () => {
expect(containerOuterCloseSpy.called).to.equal(false);
@ -735,7 +736,9 @@ describe('choices', () => {
output = instance.highlightItem();
});
returnsInstance(output);
it('returns this', () => {
expect(output).to.eql(instance);
});
it('returns early', () => {
expect(passedElementTriggerEventStub.called).to.equal(false);
@ -756,7 +759,9 @@ describe('choices', () => {
output = instance.highlightItem(item, true);
});
returnsInstance(output);
it('returns this', () => {
expect(output).to.eql(instance);
});
it('dispatches highlightItem action with correct arguments', () => {
expect(storeDispatchSpy.called).to.equal(true);
@ -817,7 +822,9 @@ describe('choices', () => {
expect(passedElementTriggerEventStub.called).to.equal(false);
});
returnsInstance(output);
it('returns this', () => {
expect(output).to.eql(instance);
});
});
});
});
@ -850,7 +857,9 @@ describe('choices', () => {
output = instance.unhighlightItem();
});
returnsInstance(output);
it('returns this', () => {
expect(output).to.eql(instance);
});
it('returns early', () => {
expect(passedElementTriggerEventStub.called).to.equal(false);
@ -871,7 +880,9 @@ describe('choices', () => {
output = instance.unhighlightItem(item, true);
});
returnsInstance(output);
it('returns this', () => {
expect(output).to.eql(instance);
});
it('dispatches highlightItem action with correct arguments', () => {
expect(storeDispatchSpy.called).to.equal(true);
@ -932,7 +943,9 @@ describe('choices', () => {
expect(passedElementTriggerEventStub.called).to.equal(false);
});
returnsInstance(output);
it('returns this', () => {
expect(output).to.eql(instance);
});
});
});
});
@ -966,7 +979,9 @@ describe('choices', () => {
storeGetItemsStub.reset();
});
returnsInstance(output);
it('returns this', () => {
expect(output).to.eql(instance);
});
it('highlights each item in store', () => {
expect(highlightItemStub.callCount).to.equal(items.length);
@ -1004,7 +1019,9 @@ describe('choices', () => {
storeGetItemsStub.reset();
});
returnsInstance(output);
it('returns this', () => {
expect(output).to.eql(instance);
});
it('unhighlights each item in store', () => {
expect(unhighlightItemStub.callCount).to.equal(items.length);
@ -1027,7 +1044,9 @@ describe('choices', () => {
instance._store.dispatch.reset();
});
returnsInstance(output);
it('returns this', () => {
expect(output).to.eql(instance);
});
it('dispatches clearChoices action', () => {
expect(storeDispatchStub.lastCall.args[0]).to.eql({
@ -1050,7 +1069,9 @@ describe('choices', () => {
instance._store.dispatch.reset();
});
returnsInstance(output);
it('returns this', () => {
expect(output).to.eql(instance);
});
it('dispatches clearAll action', () => {
expect(storeDispatchStub.lastCall.args[0]).to.eql({
@ -1075,7 +1096,9 @@ describe('choices', () => {
instance._store.dispatch.reset();
});
returnsInstance(output);
it('returns this', () => {
expect(output).to.eql(instance);
});
describe('text element', () => {
beforeEach(() => {
@ -1211,7 +1234,9 @@ describe('choices', () => {
output = instance.setValue(values);
});
returnsInstance(output);
it('returns this', () => {
expect(output).to.eql(instance);
});
it('returns early', () => {
expect(setChoiceOrItemStub.called).to.equal(false);
@ -1224,7 +1249,9 @@ describe('choices', () => {
output = instance.setValue(values);
});
returnsInstance(output);
it('returns this', () => {
expect(output).to.eql(instance);
});
it('sets each value', () => {
expect(setChoiceOrItemStub.callCount).to.equal(2);
@ -1252,7 +1279,9 @@ describe('choices', () => {
output = instance.setChoiceByValue([]);
});
returnsInstance(output);
it('returns this', () => {
expect(output).to.eql(instance);
});
it('returns early', () => {
expect(findAndSelectChoiceByValueStub.called).to.equal(false);
@ -1272,7 +1301,9 @@ describe('choices', () => {
output = instance.setChoiceByValue(value);
});
returnsInstance(output);
it('returns this', () => {
expect(output).to.eql(instance);
});
it('sets each choice with same value', () => {
expect(findAndSelectChoiceByValueStub.called).to.equal(true);
@ -1289,7 +1320,9 @@ describe('choices', () => {
output = instance.setChoiceByValue(values);
});
returnsInstance(output);
it('returns this', () => {
expect(output).to.eql(instance);
});
it('sets each choice with same value', () => {
expect(findAndSelectChoiceByValueStub.callCount).to.equal(2);
@ -1509,7 +1542,9 @@ describe('choices', () => {
output = instance.removeHighlightedItems();
});
returnsInstance(output);
it('returns this', () => {
expect(output).to.eql(instance);
});
it('removes each highlighted item in store', () => {
expect(removeItemStub.callCount).to.equal(2);
@ -1521,7 +1556,9 @@ describe('choices', () => {
output = instance.removeHighlightedItems(true);
});
returnsInstance(output);
it('returns this', () => {
expect(output).to.eql(instance);
});
it('triggers event with item value', () => {
expect(triggerChangeStub.callCount).to.equal(2);
@ -1533,6 +1570,7 @@ describe('choices', () => {
describe('setChoices', () => {
let clearChoicesStub;
let clearItemsStub;
let addGroupStub;
let addChoiceStub;
let containerOuterRemoveLoadingStateStub;
@ -1560,11 +1598,13 @@ describe('choices', () => {
beforeEach(() => {
clearChoicesStub = stub();
clearItemsStub = stub();
addGroupStub = stub();
addChoiceStub = stub();
containerOuterRemoveLoadingStateStub = stub();
instance.clearChoices = clearChoicesStub;
instance.clearItems = clearItemsStub;
instance._addGroup = addGroupStub;
instance._addChoice = addChoiceStub;
instance.containerOuter.removeLoadingState = containerOuterRemoveLoadingStateStub;
@ -1595,7 +1635,7 @@ describe('choices', () => {
instance._isSelectElement = true;
});
it('throws', () => {
it('throws a TypeError', () => {
expect(() =>
instance.setChoices(choices, null, 'label', false),
).to.throw(TypeError, /value/i);
@ -1643,16 +1683,8 @@ describe('choices', () => {
});
});
describe('passing an empty array with a true replaceChoices flag', () => {
it('choices are cleared', () => {
instance._isSelectElement = true;
instance.setChoices([], value, label, true);
expect(clearChoicesStub.called).to.equal(true);
});
});
describe('passing an empty array with a false replaceChoices flag', () => {
it('choices stay the same', () => {
it('does not clear existing choices', () => {
instance._isSelectElement = true;
instance.setChoices([], value, label, false);
expect(clearChoicesStub.called).to.equal(false);
@ -1660,18 +1692,32 @@ describe('choices', () => {
});
describe('passing true replaceChoices flag', () => {
it('choices are cleared', () => {
it('clears existing choices', () => {
instance.setChoices(choices, value, label, true);
expect(clearChoicesStub.called).to.equal(true);
});
});
describe('passing false replaceChoices flag', () => {
it('choices are not cleared', () => {
it('clears existing choices are not cleared', () => {
instance.setChoices(choices, value, label, false);
expect(clearChoicesStub.called).to.equal(false);
});
});
describe('passing true replaceItems flag', () => {
it('clears existing items', () => {
instance.setChoices(choices, value, label, true, true);
expect(clearItemsStub.called).to.equal(true);
});
});
describe('passing false replaceItems flag', () => {
it('does not clears existing items', () => {
instance.setChoices(choices, value, label, true, false);
expect(clearItemsStub.called).to.equal(false);
});
});
});
});
});

4
types/index.d.ts vendored
View file

@ -933,7 +933,8 @@ export default class Choices {
*
* @param {string} [value = 'value'] - name of `value` field
* @param {string} [label = 'label'] - name of 'label' field
* @param {boolean} [replaceChoices = false] - whether to replace of add choices
* @param {boolean} [replaceChoices = false] - whether to clear existing choices
* @param {boolean} [replaceItems = false] - whether to clear existing items
*
* @example
* ```js
@ -996,6 +997,7 @@ export default class Choices {
value?: string,
label?: string,
replaceChoices?: boolean,
replaceItems?: boolean,
): T extends object[] ? this : Promise<this>;
/**