mirror of
https://github.com/Choices-js/Choices.git
synced 2024-05-02 22:03:11 +02:00
callback to filter items before adding (#485)
* Add item custom callback * Minor unit test updates * Test updates, Changed callback name to more clearly distinguish it's function * Fix description wording in cypress * Update README * Updated filter item callback name to be addItemFilter
This commit is contained in:
parent
23e5e7674f
commit
ba09fb00e6
19
README.md
19
README.md
|
@ -92,6 +92,7 @@ will be returned. If you target one element, that instance will be returned.
|
|||
position: 'auto',
|
||||
resetScrollPosition: true,
|
||||
regexFilter: null,
|
||||
addItemFilter: null,
|
||||
shouldSort: true,
|
||||
shouldSortItems: false,
|
||||
sortFn: () => {...},
|
||||
|
@ -339,6 +340,24 @@ Pass an array of objects:
|
|||
|
||||
**Usage:** Whether the scroll position should reset after adding an item.
|
||||
|
||||
### addItemFilter
|
||||
**Type:** `Function` **Default:** `null`
|
||||
|
||||
**Input types affected:** `text`
|
||||
|
||||
**Usage:** A callback function that will need to return `true` for a user to successfully add an item.
|
||||
|
||||
**Example:**
|
||||
|
||||
```js
|
||||
// Only adds items matching the text test
|
||||
new Choices(element, {
|
||||
addItemFilter: function (value) {
|
||||
return (value !== 'test')
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### regexFilter
|
||||
**Type:** `Regex` **Default:** `null`
|
||||
|
||||
|
|
|
@ -293,6 +293,39 @@ describe('Choices - text element', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('custom add item callback', () => {
|
||||
describe('inputting a value that satisfies the addItemFilter', () => {
|
||||
const input = 'test';
|
||||
|
||||
it('allows me to add choice', () => {
|
||||
cy.get('[data-test-hook=add-item-callback]')
|
||||
.find('.choices__input--cloned')
|
||||
.type(input)
|
||||
.type('{enter}');
|
||||
|
||||
cy.get('[data-test-hook=add-item-callback]')
|
||||
.find('.choices__list--multiple .choices__item')
|
||||
.last()
|
||||
.should($choice => {
|
||||
expect($choice.text().trim()).to.equal(input);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('inputting a value that does not satisfy the callback', () => {
|
||||
it('displays dropdown prompt', () => {
|
||||
cy.get('[data-test-hook=add-item-callback]')
|
||||
.find('.choices__input--cloned')
|
||||
.type(`this is not the allowed text`)
|
||||
.type('{enter}');
|
||||
|
||||
cy.get('[data-test-hook=add-item-callback]')
|
||||
.find('.choices__list--dropdown')
|
||||
.should('not.be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('disabled via attribute', () => {
|
||||
it('does not allow me to input data', () => {
|
||||
cy.get('[data-test-hook=disabled-via-attr]')
|
||||
|
|
|
@ -64,6 +64,11 @@
|
|||
<input class="form-control" id="choices-adding-items-disabled" type="text">
|
||||
</div>
|
||||
|
||||
<div data-test-hook="add-item-callback">
|
||||
<label for="choices-add-item-callback">Callback on Add Item</label>
|
||||
<input class="form-control" id="choices-add-item-callback" type="text">
|
||||
</div>
|
||||
|
||||
<div data-test-hook="disabled-via-attr">
|
||||
<label for="choices-disabled-via-attr">Disabled via attribute</label>
|
||||
<input class="form-control" id="choices-disabled-via-attr" type="text" disabled>
|
||||
|
@ -120,6 +125,12 @@
|
|||
addItems: false,
|
||||
});
|
||||
|
||||
new Choices('#choices-add-item-callback', {
|
||||
addItemFilter: function (value) {
|
||||
return (value !== 'test')
|
||||
}
|
||||
});
|
||||
|
||||
new Choices('#choices-disabled-via-attr');
|
||||
|
||||
new Choices('#choices-prepend-append', {
|
||||
|
|
|
@ -987,6 +987,19 @@ class Choices {
|
|||
? this.config.uniqueItemText(value)
|
||||
: this.config.uniqueItemText;
|
||||
}
|
||||
|
||||
if (
|
||||
isType('Function', this.config.addItemFilter) &&
|
||||
this.config.addItemFilter(value) &&
|
||||
this._isTextElement &&
|
||||
this.config.addItems &&
|
||||
canAddItem
|
||||
) {
|
||||
canAddItem = false;
|
||||
notice = isType('Function', this.config.customAddItemText)
|
||||
? this.config.customAddItemText(value)
|
||||
: this.config.customAddItemText;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -64,6 +64,7 @@ export const DEFAULT_CONFIG = {
|
|||
noChoicesText: 'No choices to choose from',
|
||||
itemSelectText: 'Press to select',
|
||||
uniqueItemText: 'Only unique values can be added',
|
||||
customAddItemText: 'Only values matching specific conditions can be added.',
|
||||
addItemText: value => `Press Enter to add <b>"${stripHTML(value)}"</b>`,
|
||||
maxItemText: maxItemCount => `Only ${maxItemCount} values can be added`,
|
||||
itemComparer: (choice, item) => choice === item,
|
||||
|
@ -71,6 +72,7 @@ export const DEFAULT_CONFIG = {
|
|||
includeScore: true,
|
||||
},
|
||||
callbackOnInit: null,
|
||||
addItemFilter: null,
|
||||
callbackOnCreateTemplates: null,
|
||||
classNames: DEFAULT_CLASSNAMES,
|
||||
};
|
||||
|
|
|
@ -82,9 +82,11 @@ describe('constants', () => {
|
|||
expect(DEFAULT_CONFIG.noChoicesText).to.be.a('string');
|
||||
expect(DEFAULT_CONFIG.itemSelectText).to.be.a('string');
|
||||
expect(DEFAULT_CONFIG.uniqueItemText).to.be.a('string');
|
||||
expect(DEFAULT_CONFIG.customAddItemText).to.be.a('string');
|
||||
expect(DEFAULT_CONFIG.addItemText).to.be.a('function');
|
||||
expect(DEFAULT_CONFIG.maxItemText).to.be.a('function');
|
||||
expect(DEFAULT_CONFIG.fuseOptions).to.be.an('object');
|
||||
expect(DEFAULT_CONFIG.addItemFilter).to.equal(null);
|
||||
expect(DEFAULT_CONFIG.callbackOnInit).to.equal(null);
|
||||
expect(DEFAULT_CONFIG.callbackOnCreateTemplates).to.equal(null);
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue