mirror of
https://github.com/Choices-js/Choices.git
synced 2024-05-23 16:02:21 +02:00
rename addItemFilterFn (#699)
This commit is contained in:
parent
2a03d9be12
commit
b080bcda7d
18
README.md
18
README.md
|
@ -92,7 +92,7 @@ will be returned. If you target one element, that instance will be returned.
|
||||||
renderChoiceLimit: -1,
|
renderChoiceLimit: -1,
|
||||||
maxItemCount: -1,
|
maxItemCount: -1,
|
||||||
addItems: true,
|
addItems: true,
|
||||||
addItemFilterFn: null,
|
addItemFilter: null,
|
||||||
removeItems: true,
|
removeItems: true,
|
||||||
removeItemButton: false,
|
removeItemButton: false,
|
||||||
editItems: false,
|
editItems: false,
|
||||||
|
@ -370,23 +370,29 @@ Pass an array of objects:
|
||||||
|
|
||||||
**Usage:** Whether the scroll position should reset after adding an item.
|
**Usage:** Whether the scroll position should reset after adding an item.
|
||||||
|
|
||||||
### addItemFilterFn
|
### addItemFilter
|
||||||
|
|
||||||
**Type:** `Function` **Default:** `null`
|
**Type:** `string | RegExp | Function` **Default:** `null`
|
||||||
|
|
||||||
**Input types affected:** `text`
|
**Input types affected:** `text`
|
||||||
|
|
||||||
**Usage:** A filter function that will need to return `true` for a user to successfully add an item.
|
**Usage:** A RegExp or string (will be passed to RegExp constructor internally) or filter function that will need to return `true` for a user to successfully add an item.
|
||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// Only adds items matching the text test
|
// Only adds items matching the text test
|
||||||
new Choices(element, {
|
new Choices(element, {
|
||||||
addItemFilterFn: (value) => {
|
addItemFilter: (value) => {
|
||||||
return (value !== 'test');
|
return ['orange', 'apple', 'banana'].includes(value);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// only items ending to `-red`
|
||||||
|
new Choices(element, {
|
||||||
|
addItemFilter: '-red$';
|
||||||
|
});
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### shouldSort
|
### shouldSort
|
||||||
|
|
1447
public/index.html
1447
public/index.html
File diff suppressed because it is too large
Load diff
|
@ -1,28 +1,58 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta
|
||||||
|
name="viewport"
|
||||||
|
content="width=device-width,initial-scale=1,user-scalable=no"
|
||||||
|
/>
|
||||||
|
<title>Choices</title>
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
itemprop="description"
|
||||||
|
content="A lightweight, configurable select box/text input plugin. Similar to Select2 and Selectize but without the jQuery dependency."
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="180x180"
|
||||||
|
href="../assets/images/apple-touch-icon.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
href="../assets/images/favicon-32x32.png"
|
||||||
|
sizes="32x32"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
href="../assets/images/favicon-16x16.png"
|
||||||
|
sizes="16x16"
|
||||||
|
/>
|
||||||
|
<link rel="manifest" href="../assets/images/manifest.json" />
|
||||||
|
<link
|
||||||
|
rel="mask-icon"
|
||||||
|
href="../assets/images/safari-pinned-tab.svg"
|
||||||
|
color="#00bcd4"
|
||||||
|
/>
|
||||||
|
<link rel="shortcut icon" href="../assets/images/favicon.ico" />
|
||||||
|
<meta
|
||||||
|
name="msapplication-config"
|
||||||
|
content="../assets/images/browserconfig.xml"
|
||||||
|
/>
|
||||||
|
<meta name="theme-color" content="#ffffff" />
|
||||||
|
|
||||||
<head>
|
<!-- Ignore these -->
|
||||||
<meta charset="UTF-8">
|
<link rel="stylesheet" href="../assets/styles/base.min.css?version=6.0.3" />
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
|
<!-- End ignore these -->
|
||||||
<title>Choices</title>
|
|
||||||
<meta name=description itemprop=description content="A lightweight, configurable select box/text input plugin. Similar to Select2 and Selectize but without the jQuery dependency.">
|
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="../assets/images/apple-touch-icon.png">
|
|
||||||
<link rel="icon" type="image/png" href="../assets/images/favicon-32x32.png" sizes="32x32">
|
|
||||||
<link rel="icon" type="image/png" href="../assets/images/favicon-16x16.png" sizes="16x16">
|
|
||||||
<link rel="manifest" href="../assets/images/manifest.json">
|
|
||||||
<link rel="mask-icon" href="../assets/images/safari-pinned-tab.svg" color="#00bcd4">
|
|
||||||
<link rel="shortcut icon" href="../assets/images/favicon.ico">
|
|
||||||
<meta name="msapplication-config" content="../assets/images/browserconfig.xml">
|
|
||||||
<meta name="theme-color" content="#ffffff">
|
|
||||||
|
|
||||||
<!-- Ignore these -->
|
<!-- Choices includes -->
|
||||||
<link rel="stylesheet" href="../assets/styles/base.min.css?version=6.0.3">
|
<link
|
||||||
<!-- End ignore these -->
|
rel="stylesheet"
|
||||||
|
href="../assets/styles/choices.min.css?version=6.0.3"
|
||||||
<!-- Choices includes -->
|
/>
|
||||||
<link rel="stylesheet" href="../assets/styles/choices.min.css?version=6.0.3">
|
<script src="../assets/scripts/choices.min.js?version=6.0.3"></script>
|
||||||
<script src="../assets/scripts/choices.min.js?version=6.0.3"></script>
|
<!-- End Choices includes -->
|
||||||
<!-- End Choices includes -->
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
@ -31,63 +61,76 @@
|
||||||
<h2>Text inputs</h2>
|
<h2>Text inputs</h2>
|
||||||
<div data-test-hook="basic">
|
<div data-test-hook="basic">
|
||||||
<label for="choices-basic">Basic</label>
|
<label for="choices-basic">Basic</label>
|
||||||
<input class="form-control" id="choices-basic" type="text">
|
<input class="form-control" id="choices-basic" type="text" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-test-hook="edit-items">
|
<div data-test-hook="edit-items">
|
||||||
<label for="choices-edit-items">Edit items</label>
|
<label for="choices-edit-items">Edit items</label>
|
||||||
<input class="form-control" id="choices-edit-items" type="text">
|
<input class="form-control" id="choices-edit-items" type="text" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-test-hook="remove-button">
|
<div data-test-hook="remove-button">
|
||||||
<label for="choices-remove-button">Remove button</label>
|
<label for="choices-remove-button">Remove button</label>
|
||||||
<input class="form-control" id="choices-remove-button" type="text">
|
<input class="form-control" id="choices-remove-button" type="text" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-test-hook="unique-values">
|
<div data-test-hook="unique-values">
|
||||||
<label for="choices-unique-values">Unique values</label>
|
<label for="choices-unique-values">Unique values</label>
|
||||||
<input class="form-control" id="choices-unique-values" type="text">
|
<input class="form-control" id="choices-unique-values" type="text" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-test-hook="input-limit">
|
<div data-test-hook="input-limit">
|
||||||
<label for="choices-input-limit">Input limit</label>
|
<label for="choices-input-limit">Input limit</label>
|
||||||
<input class="form-control" id="choices-input-limit" type="text">
|
<input class="form-control" id="choices-input-limit" type="text" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-test-hook="add-item-filter">
|
<div data-test-hook="add-item-filter">
|
||||||
<label for="choices-add-item-filter">Add item filter</label>
|
<label for="choices-add-item-filter">Add item filter</label>
|
||||||
<input class="form-control" id="choices-add-item-filter" type="text">
|
<input
|
||||||
|
class="form-control"
|
||||||
|
id="choices-add-item-filter"
|
||||||
|
type="text"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-test-hook="adding-items-disabled">
|
<div data-test-hook="adding-items-disabled">
|
||||||
<label for="choices-adding-items-disabled">Add items disabled</label>
|
<label for="choices-adding-items-disabled">Add items disabled</label>
|
||||||
<input class="form-control" id="choices-adding-items-disabled" type="text">
|
<input
|
||||||
|
class="form-control"
|
||||||
|
id="choices-adding-items-disabled"
|
||||||
|
type="text"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-test-hook="disabled-via-attr">
|
<div data-test-hook="disabled-via-attr">
|
||||||
<label for="choices-disabled-via-attr">Disabled via attribute</label>
|
<label for="choices-disabled-via-attr">Disabled via attribute</label>
|
||||||
<input class="form-control" id="choices-disabled-via-attr" type="text" disabled>
|
<input
|
||||||
|
class="form-control"
|
||||||
|
id="choices-disabled-via-attr"
|
||||||
|
type="text"
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-test-hook="prepend-append">
|
<div data-test-hook="prepend-append">
|
||||||
<label for="choices-prepend-append">Prepend/append</label>
|
<label for="choices-prepend-append">Prepend/append</label>
|
||||||
<input class="form-control" id="choices-prepend-append" type="text">
|
<input class="form-control" id="choices-prepend-append" type="text" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-test-hook="prepopulated">
|
<div data-test-hook="prepopulated">
|
||||||
<label for="choices-prepopulated">Pre-populated choices</label>
|
<label for="choices-prepopulated">Pre-populated choices</label>
|
||||||
<input class="form-control" id="choices-prepopulated" type="text">
|
<input class="form-control" id="choices-prepopulated" type="text" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-test-hook="placeholder">
|
<div data-test-hook="placeholder">
|
||||||
<label for="choices-placeholder">Placeholder</label>
|
<label for="choices-placeholder">Placeholder</label>
|
||||||
<input class="form-control" id="choices-placeholder" type="text">
|
<input class="form-control" id="choices-placeholder" type="text" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-test-hook="within-form">
|
<div data-test-hook="within-form">
|
||||||
<form>
|
<form>
|
||||||
<label for="choices-within-form">Within form</label>
|
<label for="choices-within-form">Within form</label>
|
||||||
<input class="form-control" id="choices-within-form" type="text">
|
<input class="form-control" id="choices-within-form" type="text" />
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -114,8 +157,8 @@
|
||||||
|
|
||||||
new Choices('#choices-add-item-filter', {
|
new Choices('#choices-add-item-filter', {
|
||||||
addItems: true,
|
addItems: true,
|
||||||
addItemFilterFn: (value) => {
|
addItemFilter: value => {
|
||||||
const regex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
const regex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||||
const expression = new RegExp(regex.source, 'i');
|
const expression = new RegExp(regex.source, 'i');
|
||||||
return expression.test(value);
|
return expression.test(value);
|
||||||
},
|
},
|
||||||
|
@ -133,13 +176,16 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-prepopulated', {
|
new Choices('#choices-prepopulated', {
|
||||||
items: ['Josh Johnson', {
|
items: [
|
||||||
value: 'joe@bloggs.co.uk',
|
'Josh Johnson',
|
||||||
label: 'Joe Bloggs',
|
{
|
||||||
customProperties: {
|
value: 'joe@bloggs.co.uk',
|
||||||
description: 'Joe Blogg is such a generic name',
|
label: 'Joe Bloggs',
|
||||||
}
|
customProperties: {
|
||||||
}],
|
description: 'Joe Blogg is such a generic name',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-placeholder', {
|
new Choices('#choices-placeholder', {
|
||||||
|
@ -151,4 +197,4 @@
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -79,6 +79,18 @@ class Choices {
|
||||||
{ arrayMerge: (destinationArray, sourceArray) => [...sourceArray] },
|
{ arrayMerge: (destinationArray, sourceArray) => [...sourceArray] },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Convert addItemFilter to function
|
||||||
|
if (
|
||||||
|
userConfig.addItemFilter &&
|
||||||
|
typeof userConfig.addItemFilter !== 'function'
|
||||||
|
) {
|
||||||
|
const re =
|
||||||
|
userConfig.addItemFilter instanceof RegExp
|
||||||
|
? userConfig.addItemFilter
|
||||||
|
: new RegExp(userConfig.addItemFilter);
|
||||||
|
this.config.addItemFilter = re.test.bind(re);
|
||||||
|
}
|
||||||
|
|
||||||
const invalidConfigOptions = diff(this.config, DEFAULT_CONFIG);
|
const invalidConfigOptions = diff(this.config, DEFAULT_CONFIG);
|
||||||
if (invalidConfigOptions.length) {
|
if (invalidConfigOptions.length) {
|
||||||
console.warn(
|
console.warn(
|
||||||
|
@ -1026,13 +1038,14 @@ class Choices {
|
||||||
this._isTextElement &&
|
this._isTextElement &&
|
||||||
this.config.addItems &&
|
this.config.addItems &&
|
||||||
canAddItem &&
|
canAddItem &&
|
||||||
isType('Function', this.config.addItemFilterFn) &&
|
typeof this.config.addItemFilter === 'function' &&
|
||||||
!this.config.addItemFilterFn(value)
|
!this.config.addItemFilter(value)
|
||||||
) {
|
) {
|
||||||
canAddItem = false;
|
canAddItem = false;
|
||||||
notice = isType('Function', this.config.customAddItemText)
|
notice =
|
||||||
? this.config.customAddItemText(value)
|
typeof this.config.customAddItemText === 'function'
|
||||||
: this.config.customAddItemText;
|
? this.config.customAddItemText(value)
|
||||||
|
: this.config.customAddItemText;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ export const DEFAULT_CONFIG = {
|
||||||
renderChoiceLimit: -1,
|
renderChoiceLimit: -1,
|
||||||
maxItemCount: -1,
|
maxItemCount: -1,
|
||||||
addItems: true,
|
addItems: true,
|
||||||
addItemFilterFn: null,
|
addItemFilter: null,
|
||||||
removeItems: true,
|
removeItems: true,
|
||||||
removeItemButton: false,
|
removeItemButton: false,
|
||||||
editItems: false,
|
editItems: false,
|
||||||
|
|
|
@ -55,7 +55,7 @@ describe('constants', () => {
|
||||||
expect(DEFAULT_CONFIG.renderChoiceLimit).to.be.a('number');
|
expect(DEFAULT_CONFIG.renderChoiceLimit).to.be.a('number');
|
||||||
expect(DEFAULT_CONFIG.maxItemCount).to.be.a('number');
|
expect(DEFAULT_CONFIG.maxItemCount).to.be.a('number');
|
||||||
expect(DEFAULT_CONFIG.addItems).to.be.a('boolean');
|
expect(DEFAULT_CONFIG.addItems).to.be.a('boolean');
|
||||||
expect(DEFAULT_CONFIG.addItemFilterFn).to.equal(null);
|
expect(DEFAULT_CONFIG.addItemFilter).to.equal(null);
|
||||||
expect(DEFAULT_CONFIG.removeItems).to.be.a('boolean');
|
expect(DEFAULT_CONFIG.removeItems).to.be.a('boolean');
|
||||||
expect(DEFAULT_CONFIG.removeItemButton).to.be.a('boolean');
|
expect(DEFAULT_CONFIG.removeItemButton).to.be.a('boolean');
|
||||||
expect(DEFAULT_CONFIG.editItems).to.be.a('boolean');
|
expect(DEFAULT_CONFIG.editItems).to.be.a('boolean');
|
||||||
|
|
3
types/index.d.ts
vendored
3
types/index.d.ts
vendored
|
@ -18,6 +18,7 @@ declare namespace Choices {
|
||||||
type stringFunction = () => string;
|
type stringFunction = () => string;
|
||||||
type noticeStringFunction = (value: string) => string;
|
type noticeStringFunction = (value: string) => string;
|
||||||
type noticeLimitFunction = (maxItemCount: number) => string;
|
type noticeLimitFunction = (maxItemCount: number) => string;
|
||||||
|
type filterFunction = (value: string) => boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Choice {
|
interface Choice {
|
||||||
|
@ -403,7 +404,7 @@ declare namespace Choices {
|
||||||
*
|
*
|
||||||
* @default null
|
* @default null
|
||||||
*/
|
*/
|
||||||
addItemFilterFn: (value: string) => boolean;
|
addItemFilter: string | RegExp | Choices.Types.filterFunction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The text that is shown when a user has inputted a new item but has not pressed the enter key. To access the current input value, pass a function with a `value` argument (see the **default config** [https://github.com/jshjohnson/Choices#setup] for an example), otherwise pass a string.
|
* The text that is shown when a user has inputted a new item but has not pressed the enter key. To access the current input value, pass a function with a `value` argument (see the **default config** [https://github.com/jshjohnson/Choices#setup] for an example), otherwise pass a string.
|
||||||
|
|
Loading…
Reference in a new issue