mirror of
https://github.com/Choices-js/Choices.git
synced 2024-05-02 05:52:46 +02:00
[MAJOR] Remove .ajax
and allow async function for .setChoices
(#701)
* WIP: remove ajax * copy #700 * remove ajax, add fetchChoices * extend setChoices * update README
This commit is contained in:
parent
1f5192b4ad
commit
e3cc6eaf1b
63
README.md
63
README.md
|
@ -863,7 +863,9 @@ choices.disable();
|
||||||
|
|
||||||
**Input types affected:** `select-one`, `select-multiple`
|
**Input types affected:** `select-one`, `select-multiple`
|
||||||
|
|
||||||
**Usage:** Set choices of select input via an array of objects, a value name and a label name. This behaves the same as passing items via the `choices` option but can be called after initialising Choices. This can also be used to add groups of choices (see example 2); Optionally pass a true `replaceChoices` value to remove any existing choices. Optionally pass a `customProperties` object to add additional data to your choices (useful when searching/filtering etc). Passing an empty array as the first parameter, and a true `replaceChoices` is the same as calling `clearChoices` (see below).
|
**Usage:** Set choices of select input via an array of objects (or function that returns array of object or promise of it), a value field name and a label field name.
|
||||||
|
|
||||||
|
This behaves the similar as passing items via the `choices` option but can be called after initialising Choices. This can also be used to add groups of choices (see example 3); Optionally pass a true `replaceChoices` value to remove any existing choices. Optionally pass a `customProperties` object to add additional data to your choices (useful when searching/filtering etc). Passing an empty array as the first parameter, and a true `replaceChoices` is the same as calling `clearChoices` (see below).
|
||||||
|
|
||||||
**Example 1:**
|
**Example 1:**
|
||||||
|
|
||||||
|
@ -887,6 +889,22 @@ example.setChoices(
|
||||||
```js
|
```js
|
||||||
const example = new Choices(element);
|
const example = new Choices(element);
|
||||||
|
|
||||||
|
// Passing a function that returns Promise of choices
|
||||||
|
example.setChoices(async () => {
|
||||||
|
try {
|
||||||
|
const items = await fetch('/items');
|
||||||
|
return items.json();
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example 3:**
|
||||||
|
|
||||||
|
```js
|
||||||
|
const example = new Choices(element);
|
||||||
|
|
||||||
example.setChoices(
|
example.setChoices(
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
|
@ -1009,49 +1027,6 @@ example.setChoiceByValue('Two'); // Choice with value of 'Two' has now been sele
|
||||||
|
|
||||||
**Usage:** Enables input to accept new values/select further choices.
|
**Usage:** Enables input to accept new values/select further choices.
|
||||||
|
|
||||||
### ajax(fn);
|
|
||||||
|
|
||||||
**Input types affected:** `select-one`, `select-multiple`
|
|
||||||
|
|
||||||
**Usage:** Populate choices/groups via a callback.
|
|
||||||
|
|
||||||
**Example:**
|
|
||||||
|
|
||||||
```js
|
|
||||||
var example = new Choices(element);
|
|
||||||
|
|
||||||
example.ajax(function(callback) {
|
|
||||||
fetch(url)
|
|
||||||
.then(function(response) {
|
|
||||||
response.json().then(function(data) {
|
|
||||||
callback(data, 'value', 'label');
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(function(error) {
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
**Example 2:**
|
|
||||||
If your structure differs from `data.value` and `data.key` structure you can write your own `key` and `value` into the `callback` function. This could be useful when you don't want to transform the given response.
|
|
||||||
|
|
||||||
```js
|
|
||||||
const example = new Choices(element);
|
|
||||||
|
|
||||||
example.ajax(function(callback) {
|
|
||||||
fetch(url)
|
|
||||||
.then(function(response) {
|
|
||||||
response.json().then(function(data) {
|
|
||||||
callback(data, 'data.key', 'data.value');
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(function(error) {
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Browser compatibility
|
## Browser compatibility
|
||||||
|
|
||||||
Choices is compiled using [Babel](https://babeljs.io/) to enable support for [ES5 browsers](http://caniuse.com/#feat=es5). If you need to support a browser that does not support one of the features listed below, I suggest including a polyfill from the very good [polyfill.io](https://cdn.polyfill.io/v2/docs/):
|
Choices is compiled using [Babel](https://babeljs.io/) to enable support for [ES5 browsers](http://caniuse.com/#feat=es5). If you need to support a browser that does not support one of the features listed below, I suggest including a polyfill from the very good [polyfill.io](https://cdn.polyfill.io/v2/docs/):
|
||||||
|
|
|
@ -320,7 +320,7 @@
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<label for="choices-single-remove-xhr"
|
<label for="choices-single-remove-xhr"
|
||||||
>Options from remote source (XHR) & remove button</label
|
>Options from remote source (Fetch API) & remove button</label
|
||||||
>
|
>
|
||||||
<select
|
<select
|
||||||
class="form-control"
|
class="form-control"
|
||||||
|
@ -627,17 +627,17 @@
|
||||||
placeholder: true,
|
placeholder: true,
|
||||||
placeholderValue: 'Pick an Strokes record',
|
placeholderValue: 'Pick an Strokes record',
|
||||||
maxItemCount: 5,
|
maxItemCount: 5,
|
||||||
}).ajax(function(callback) {
|
}).setChoices(function() {
|
||||||
fetch(
|
return fetch(
|
||||||
'https://api.discogs.com/artists/55980/releases?token=QBRmstCkwXEvCjTclCpumbtNwvVkEzGAdELXyRyW',
|
'https://api.discogs.com/artists/55980/releases?token=QBRmstCkwXEvCjTclCpumbtNwvVkEzGAdELXyRyW',
|
||||||
)
|
)
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
response.json().then(function(data) {
|
return response.json();
|
||||||
callback(data.releases, 'title', 'title');
|
|
||||||
});
|
|
||||||
})
|
})
|
||||||
.catch(function(error) {
|
.then(function(data) {
|
||||||
console.error(error);
|
return data.releases.map(function(release) {
|
||||||
|
return { value: release.title, label: release.title };
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -685,46 +685,39 @@
|
||||||
|
|
||||||
var singleFetch = new Choices('#choices-single-remote-fetch', {
|
var singleFetch = new Choices('#choices-single-remote-fetch', {
|
||||||
searchPlaceholderValue: 'Search for an Arctic Monkeys record',
|
searchPlaceholderValue: 'Search for an Arctic Monkeys record',
|
||||||
}).ajax(function(callback) {
|
})
|
||||||
fetch(
|
.setChoices(function() {
|
||||||
'https://api.discogs.com/artists/391170/releases?token=QBRmstCkwXEvCjTclCpumbtNwvVkEzGAdELXyRyW',
|
return fetch(
|
||||||
)
|
'https://api.discogs.com/artists/391170/releases?token=QBRmstCkwXEvCjTclCpumbtNwvVkEzGAdELXyRyW',
|
||||||
.then(function(response) {
|
)
|
||||||
response.json().then(function(data) {
|
.then(function(response) {
|
||||||
callback(data.releases, 'title', 'title');
|
return response.json();
|
||||||
singleFetch.setChoiceByValue('Fake Tales Of San Francisco');
|
})
|
||||||
|
.then(function(data) {
|
||||||
|
return data.releases.map(function(release) {
|
||||||
|
return { label: release.title, value: release.title };
|
||||||
|
});
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(function(error) {
|
.then(function(instance) {
|
||||||
console.error(error);
|
instance.setChoiceByValue('Fake Tales Of San Francisco');
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
var singleXhrRemove = new Choices('#choices-single-remove-xhr', {
|
var singleXhrRemove = new Choices('#choices-single-remove-xhr', {
|
||||||
removeItemButton: true,
|
removeItemButton: true,
|
||||||
searchPlaceholderValue: "Search for a Smiths' record",
|
searchPlaceholderValue: "Search for a Smiths' record",
|
||||||
}).ajax(function(callback) {
|
}).setChoices(function(callback) {
|
||||||
var request = new XMLHttpRequest();
|
return fetch(
|
||||||
request.open(
|
|
||||||
'get',
|
|
||||||
'https://api.discogs.com/artists/83080/releases?token=QBRmstCkwXEvCjTclCpumbtNwvVkEzGAdELXyRyW',
|
'https://api.discogs.com/artists/83080/releases?token=QBRmstCkwXEvCjTclCpumbtNwvVkEzGAdELXyRyW',
|
||||||
true,
|
)
|
||||||
);
|
.then(function(res) {
|
||||||
request.onreadystatechange = function() {
|
return res.json();
|
||||||
var status;
|
})
|
||||||
var data;
|
.then(function(data) {
|
||||||
if (request.readyState === 4) {
|
return data.releases.map(function(release) {
|
||||||
status = request.status;
|
return { label: release.title, value: release.title };
|
||||||
if (status === 200) {
|
});
|
||||||
data = JSON.parse(request.responseText);
|
});
|
||||||
callback(data.releases, 'title', 'title');
|
|
||||||
singleXhrRemove.setChoiceByValue('How Soon Is Now?');
|
|
||||||
} else {
|
|
||||||
console.error(status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
request.send();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var genericExamples = new Choices('[data-trigger]', {
|
var genericExamples = new Choices('[data-trigger]', {
|
||||||
|
|
|
@ -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>
|
||||||
|
@ -33,7 +63,12 @@
|
||||||
<label for="choices-basic">Basic</label>
|
<label for="choices-basic">Basic</label>
|
||||||
<button class="disable push-bottom">Disable</button>
|
<button class="disable push-bottom">Disable</button>
|
||||||
<button class="enable push-bottom">Enable</button>
|
<button class="enable push-bottom">Enable</button>
|
||||||
<select class="form-control" name="choices-basic" id="choices-basic" multiple>
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-basic"
|
||||||
|
id="choices-basic"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
<option value="Choice 1">Choice 1</option>
|
<option value="Choice 1">Choice 1</option>
|
||||||
<option value="Choice 2">Choice 2</option>
|
<option value="Choice 2">Choice 2</option>
|
||||||
<option value="Find me">Choice 3</option>
|
<option value="Find me">Choice 3</option>
|
||||||
|
@ -43,7 +78,12 @@
|
||||||
|
|
||||||
<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>
|
||||||
<select class="form-control" name="choices-remove-button" id="choices-remove-button" multiple>
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-remove-button"
|
||||||
|
id="choices-remove-button"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
<option value="Choice 1">Choice 1</option>
|
<option value="Choice 1">Choice 1</option>
|
||||||
<option value="Choice 2">Choice 2</option>
|
<option value="Choice 2">Choice 2</option>
|
||||||
<option value="Choice 3">Choice 3</option>
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
@ -53,7 +93,12 @@
|
||||||
|
|
||||||
<div data-test-hook="disabled-choice">
|
<div data-test-hook="disabled-choice">
|
||||||
<label for="choices-disabled-choice">Disabled choice</label>
|
<label for="choices-disabled-choice">Disabled choice</label>
|
||||||
<select class="form-control" name="choices-disabled-choice" id="choices-disabled-choice" multiple>
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-disabled-choice"
|
||||||
|
id="choices-disabled-choice"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
<option value="Choice 1">Choice 1</option>
|
<option value="Choice 1">Choice 1</option>
|
||||||
<option value="Choice 2">Choice 2</option>
|
<option value="Choice 2">Choice 2</option>
|
||||||
<option value="Choice 3">Choice 3</option>
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
@ -63,7 +108,12 @@
|
||||||
|
|
||||||
<div data-test-hook="add-items-disabled">
|
<div data-test-hook="add-items-disabled">
|
||||||
<label for="choices-add-items-disabled">Add items disabled</label>
|
<label for="choices-add-items-disabled">Add items disabled</label>
|
||||||
<select class="form-control" name="choices-add-items-disabled" id="choices-add-items-disabled" multiple>
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-add-items-disabled"
|
||||||
|
id="choices-add-items-disabled"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
<option value="Choice 1" selected>Choice 1</option>
|
<option value="Choice 1" selected>Choice 1</option>
|
||||||
<option value="Choice 2">Choice 2</option>
|
<option value="Choice 2">Choice 2</option>
|
||||||
<option value="Choice 3">Choice 3</option>
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
@ -72,7 +122,13 @@
|
||||||
|
|
||||||
<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>
|
||||||
<select class="form-control" name="choices-disabled-via-attr" id="choices-disabled-via-attr" multiple disabled>
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-disabled-via-attr"
|
||||||
|
id="choices-disabled-via-attr"
|
||||||
|
multiple
|
||||||
|
disabled
|
||||||
|
>
|
||||||
<option value="Choice 1" selected>Choice 1</option>
|
<option value="Choice 1" selected>Choice 1</option>
|
||||||
<option value="Choice 2">Choice 2</option>
|
<option value="Choice 2">Choice 2</option>
|
||||||
<option value="Choice 3">Choice 3</option>
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
@ -81,7 +137,12 @@
|
||||||
|
|
||||||
<div data-test-hook="selection-limit">
|
<div data-test-hook="selection-limit">
|
||||||
<label for="choices-selection-limit">Input limit</label>
|
<label for="choices-selection-limit">Input limit</label>
|
||||||
<select class="form-control" name="choices-selection-limit" id="choices-selection-limit" multiple>
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-selection-limit"
|
||||||
|
id="choices-selection-limit"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
<option value="Choice 1">Choice 1</option>
|
<option value="Choice 1">Choice 1</option>
|
||||||
<option value="Choice 2">Choice 2</option>
|
<option value="Choice 2">Choice 2</option>
|
||||||
<option value="Choice 3">Choice 3</option>
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
@ -93,7 +154,12 @@
|
||||||
|
|
||||||
<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>
|
||||||
<select class="form-control" name="choices-prepend-append" id="choices-prepend-append" multiple>
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-prepend-append"
|
||||||
|
id="choices-prepend-append"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
<option value="Choice 1">Choice 1</option>
|
<option value="Choice 1">Choice 1</option>
|
||||||
<option value="Choice 2">Choice 2</option>
|
<option value="Choice 2">Choice 2</option>
|
||||||
<option value="Choice 3">Choice 3</option>
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
@ -102,7 +168,12 @@
|
||||||
|
|
||||||
<div data-test-hook="render-choice-limit">
|
<div data-test-hook="render-choice-limit">
|
||||||
<label for="choices-render-choice-limit">Render choice limit</label>
|
<label for="choices-render-choice-limit">Render choice limit</label>
|
||||||
<select class="form-control" name="choices-render-choice-limit" id="choices-render-choice-limit" multiple>
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-render-choice-limit"
|
||||||
|
id="choices-render-choice-limit"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
<option value="Choice 1">Choice 1</option>
|
<option value="Choice 1">Choice 1</option>
|
||||||
<option value="Choice 2">Choice 2</option>
|
<option value="Choice 2">Choice 2</option>
|
||||||
<option value="Choice 3">Choice 3</option>
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
@ -111,7 +182,12 @@
|
||||||
|
|
||||||
<div data-test-hook="search-floor">
|
<div data-test-hook="search-floor">
|
||||||
<label for="choices-search-floor">Search floor</label>
|
<label for="choices-search-floor">Search floor</label>
|
||||||
<select class="form-control" name="choices-search-floor" id="choices-search-floor" multiple>
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-search-floor"
|
||||||
|
id="choices-search-floor"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
<option value="Choice 1">Choice 1</option>
|
<option value="Choice 1">Choice 1</option>
|
||||||
<option value="Choice 2">Choice 2</option>
|
<option value="Choice 2">Choice 2</option>
|
||||||
<option value="Choice 3">Choice 3</option>
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
@ -120,7 +196,12 @@
|
||||||
|
|
||||||
<div data-test-hook="placeholder">
|
<div data-test-hook="placeholder">
|
||||||
<label for="choices-placeholder">Placeholder</label>
|
<label for="choices-placeholder">Placeholder</label>
|
||||||
<select class="form-control" name="choices-placeholder" id="choices-placeholder" multiple>
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-placeholder"
|
||||||
|
id="choices-placeholder"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
<option value="Choice 1">Choice 1</option>
|
<option value="Choice 1">Choice 1</option>
|
||||||
<option value="Choice 2">Choice 2</option>
|
<option value="Choice 2">Choice 2</option>
|
||||||
<option value="Choice 3">Choice 3</option>
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
@ -129,12 +210,22 @@
|
||||||
|
|
||||||
<div data-test-hook="remote-data">
|
<div data-test-hook="remote-data">
|
||||||
<label for="choices-remote-data">Remote data</label>
|
<label for="choices-remote-data">Remote data</label>
|
||||||
<select class="form-control" name="choices-remote-data" id="choices-remote-data" multiple></select>
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-remote-data"
|
||||||
|
id="choices-remote-data"
|
||||||
|
multiple
|
||||||
|
></select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-test-hook="scrolling-dropdown">
|
<div data-test-hook="scrolling-dropdown">
|
||||||
<label for="choices-scrolling-dropdown">Scrolling dropdown</label>
|
<label for="choices-scrolling-dropdown">Scrolling dropdown</label>
|
||||||
<select class="form-control" name="choices-scrolling-dropdown" id="choices-scrolling-dropdown" multiple>
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-scrolling-dropdown"
|
||||||
|
id="choices-scrolling-dropdown"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
<option value="Choice 1">Choice 1</option>
|
<option value="Choice 1">Choice 1</option>
|
||||||
<option value="Choice 2">Choice 2</option>
|
<option value="Choice 2">Choice 2</option>
|
||||||
<option value="Choice 3">Choice 3</option>
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
@ -155,7 +246,12 @@
|
||||||
|
|
||||||
<div data-test-hook="groups">
|
<div data-test-hook="groups">
|
||||||
<label for="choices-groups">Choice groups</label>
|
<label for="choices-groups">Choice groups</label>
|
||||||
<select class="form-control" name="choices-groups" id="choices-groups" multiple>
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-groups"
|
||||||
|
id="choices-groups"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
<optgroup label="UK">
|
<optgroup label="UK">
|
||||||
<option value="London">London</option>
|
<option value="London">London</option>
|
||||||
<option value="Manchester">Manchester</option>
|
<option value="Manchester">Manchester</option>
|
||||||
|
@ -171,26 +267,47 @@
|
||||||
|
|
||||||
<div data-test-hook="custom-properties">
|
<div data-test-hook="custom-properties">
|
||||||
<label for="choices-custom-properties">Custom properties</label>
|
<label for="choices-custom-properties">Custom properties</label>
|
||||||
<select class="form-control" name="choices-custom-properties" id="choices-custom-properties" multiple></select>
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-custom-properties"
|
||||||
|
id="choices-custom-properties"
|
||||||
|
multiple
|
||||||
|
></select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-test-hook="non-string-values">
|
<div data-test-hook="non-string-values">
|
||||||
<label for="choices-non-string-values">Non-string values</label>
|
<label for="choices-non-string-values">Non-string values</label>
|
||||||
<select class="form-control" name="choices-non-string-values" id="choices-non-string-values"></select>
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-non-string-values"
|
||||||
|
id="choices-non-string-values"
|
||||||
|
></select>
|
||||||
</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>
|
||||||
<select class="form-control" name="choices-within-form" id="choices-within-form" multiple>
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-within-form"
|
||||||
|
id="choices-within-form"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
<option value="Choice 1">Choice 1</option>
|
<option value="Choice 1">Choice 1</option>
|
||||||
</select>
|
</select>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-test-hook="set-choice-by-value">
|
<div data-test-hook="set-choice-by-value">
|
||||||
<label for="choices-set-choice-by-value">Dynamically set choice by value</label>
|
<label for="choices-set-choice-by-value"
|
||||||
<select class="form-control" name="choices-set-choice-by-value" id="choices-set-choice-by-value" multiple>
|
>Dynamically set choice by value</label
|
||||||
|
>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-set-choice-by-value"
|
||||||
|
id="choices-set-choice-by-value"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
<option value="Choice 1">Choice 1</option>
|
<option value="Choice 1">Choice 1</option>
|
||||||
<option value="Choice 2">Choice 2</option>
|
<option value="Choice 2">Choice 2</option>
|
||||||
<option value="Choice 3">Choice 3</option>
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
@ -199,7 +316,12 @@
|
||||||
|
|
||||||
<div data-test-hook="search-by-label">
|
<div data-test-hook="search-by-label">
|
||||||
<label for="choices-search-by-label">Search by label</label>
|
<label for="choices-search-by-label">Search by label</label>
|
||||||
<select class="form-control" name="choices-search-by-label" id="choices-search-by-label" multiple>
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-search-by-label"
|
||||||
|
id="choices-search-by-label"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
<option value="value1">label1</option>
|
<option value="value1">label1</option>
|
||||||
<option value="value2">label2</option>
|
<option value="value2">label2</option>
|
||||||
</select>
|
</select>
|
||||||
|
@ -210,13 +332,17 @@
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
const choicesBasic = new Choices('#choices-basic');
|
const choicesBasic = new Choices('#choices-basic');
|
||||||
|
|
||||||
document.querySelector('button.disable').addEventListener('click', () => {
|
document
|
||||||
choicesBasic.disable();
|
.querySelector('button.disable')
|
||||||
});
|
.addEventListener('click', () => {
|
||||||
|
choicesBasic.disable();
|
||||||
|
});
|
||||||
|
|
||||||
document.querySelector('button.enable').addEventListener('click', () => {
|
document
|
||||||
choicesBasic.enable();
|
.querySelector('button.enable')
|
||||||
});
|
.addEventListener('click', () => {
|
||||||
|
choicesBasic.enable();
|
||||||
|
});
|
||||||
|
|
||||||
new Choices('#choices-remove-button', {
|
new Choices('#choices-remove-button', {
|
||||||
removeItemButton: true,
|
removeItemButton: true,
|
||||||
|
@ -254,16 +380,9 @@
|
||||||
|
|
||||||
new Choices('#choices-remote-data', {
|
new Choices('#choices-remote-data', {
|
||||||
shouldSort: false,
|
shouldSort: false,
|
||||||
}).ajax((callback) => {
|
}).setChoices(async () => {
|
||||||
fetch('/data')
|
const data = await fetch('/data');
|
||||||
.then((response) => {
|
return data.json();
|
||||||
response.json().then((data) => {
|
|
||||||
callback(data, 'value', 'label');
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.error(error);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-scrolling-dropdown', {
|
new Choices('#choices-scrolling-dropdown', {
|
||||||
|
@ -331,10 +450,12 @@
|
||||||
|
|
||||||
new Choices('#choices-within-form');
|
new Choices('#choices-within-form');
|
||||||
|
|
||||||
new Choices('#choices-set-choice-by-value').setChoiceByValue('Choice 2');
|
new Choices('#choices-set-choice-by-value').setChoiceByValue(
|
||||||
|
'Choice 2',
|
||||||
|
);
|
||||||
|
|
||||||
new Choices('#choices-search-by-label', { searchFields: ['label'] });
|
new Choices('#choices-search-by-label', { searchFields: ['label'] });
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -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>
|
||||||
|
@ -43,7 +73,11 @@
|
||||||
|
|
||||||
<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>
|
||||||
<select class="form-control" name="choices-remove-button" id="choices-remove-button">
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-remove-button"
|
||||||
|
id="choices-remove-button"
|
||||||
|
>
|
||||||
<option value="Choice 1">Choice 1</option>
|
<option value="Choice 1">Choice 1</option>
|
||||||
<option value="Choice 2">Choice 2</option>
|
<option value="Choice 2">Choice 2</option>
|
||||||
<option value="Choice 3">Choice 3</option>
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
@ -53,7 +87,11 @@
|
||||||
|
|
||||||
<div data-test-hook="disabled-choice">
|
<div data-test-hook="disabled-choice">
|
||||||
<label for="choices-disabled-choice">Disabled choice</label>
|
<label for="choices-disabled-choice">Disabled choice</label>
|
||||||
<select class="form-control" name="choices-disabled-choice" id="choices-disabled-choice">
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-disabled-choice"
|
||||||
|
id="choices-disabled-choice"
|
||||||
|
>
|
||||||
<option value="Choice 1">Choice 1</option>
|
<option value="Choice 1">Choice 1</option>
|
||||||
<option value="Choice 2">Choice 2</option>
|
<option value="Choice 2">Choice 2</option>
|
||||||
<option value="Choice 3">Choice 3</option>
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
@ -63,7 +101,11 @@
|
||||||
|
|
||||||
<div data-test-hook="add-items-disabled">
|
<div data-test-hook="add-items-disabled">
|
||||||
<label for="choices-add-items-disabled">Add items disabled</label>
|
<label for="choices-add-items-disabled">Add items disabled</label>
|
||||||
<select class="form-control" name="choices-add-items-disabled" id="choices-add-items-disabled">
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-add-items-disabled"
|
||||||
|
id="choices-add-items-disabled"
|
||||||
|
>
|
||||||
<option value="Choice 1" selected>Choice 1</option>
|
<option value="Choice 1" selected>Choice 1</option>
|
||||||
<option value="Choice 2">Choice 2</option>
|
<option value="Choice 2">Choice 2</option>
|
||||||
<option value="Choice 3">Choice 3</option>
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
@ -72,7 +114,12 @@
|
||||||
|
|
||||||
<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>
|
||||||
<select class="form-control" name="choices-disabled-via-attr" id="choices-disabled-via-attr" disabled>
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-disabled-via-attr"
|
||||||
|
id="choices-disabled-via-attr"
|
||||||
|
disabled
|
||||||
|
>
|
||||||
<option value="Choice 1" selected>Choice 1</option>
|
<option value="Choice 1" selected>Choice 1</option>
|
||||||
<option value="Choice 2">Choice 2</option>
|
<option value="Choice 2">Choice 2</option>
|
||||||
<option value="Choice 3">Choice 3</option>
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
@ -81,7 +128,11 @@
|
||||||
|
|
||||||
<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>
|
||||||
<select class="form-control" name="choices-prepend-append" id="choices-prepend-append">
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-prepend-append"
|
||||||
|
id="choices-prepend-append"
|
||||||
|
>
|
||||||
<option value="Choice 1">Choice 1</option>
|
<option value="Choice 1">Choice 1</option>
|
||||||
<option value="Choice 2">Choice 2</option>
|
<option value="Choice 2">Choice 2</option>
|
||||||
<option value="Choice 3">Choice 3</option>
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
@ -90,7 +141,11 @@
|
||||||
|
|
||||||
<div data-test-hook="render-choice-limit">
|
<div data-test-hook="render-choice-limit">
|
||||||
<label for="choices-render-choice-limit">Render choice limit</label>
|
<label for="choices-render-choice-limit">Render choice limit</label>
|
||||||
<select class="form-control" name="choices-render-choice-limit" id="choices-render-choice-limit">
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-render-choice-limit"
|
||||||
|
id="choices-render-choice-limit"
|
||||||
|
>
|
||||||
<option value="Choice 1">Choice 1</option>
|
<option value="Choice 1">Choice 1</option>
|
||||||
<option value="Choice 2">Choice 2</option>
|
<option value="Choice 2">Choice 2</option>
|
||||||
<option value="Choice 3">Choice 3</option>
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
@ -99,7 +154,11 @@
|
||||||
|
|
||||||
<div data-test-hook="search-disabled">
|
<div data-test-hook="search-disabled">
|
||||||
<label for="choices-search-disabled">Search disabled</label>
|
<label for="choices-search-disabled">Search disabled</label>
|
||||||
<select class="form-control" name="choices-search-disabled" id="choices-search-disabled">
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-search-disabled"
|
||||||
|
id="choices-search-disabled"
|
||||||
|
>
|
||||||
<option value="Choice 1">Choice 1</option>
|
<option value="Choice 1">Choice 1</option>
|
||||||
<option value="Choice 2">Choice 2</option>
|
<option value="Choice 2">Choice 2</option>
|
||||||
<option value="Choice 3">Choice 3</option>
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
@ -108,7 +167,11 @@
|
||||||
|
|
||||||
<div data-test-hook="search-floor">
|
<div data-test-hook="search-floor">
|
||||||
<label for="choices-search-floor">Search floor</label>
|
<label for="choices-search-floor">Search floor</label>
|
||||||
<select class="form-control" name="choices-search-floor" id="choices-search-floor">
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-search-floor"
|
||||||
|
id="choices-search-floor"
|
||||||
|
>
|
||||||
<option value="Choice 1">Choice 1</option>
|
<option value="Choice 1">Choice 1</option>
|
||||||
<option value="Choice 2">Choice 2</option>
|
<option value="Choice 2">Choice 2</option>
|
||||||
<option value="Choice 3">Choice 3</option>
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
@ -117,12 +180,20 @@
|
||||||
|
|
||||||
<div data-test-hook="remote-data">
|
<div data-test-hook="remote-data">
|
||||||
<label for="choices-remote-data">Remote data</label>
|
<label for="choices-remote-data">Remote data</label>
|
||||||
<select class="form-control" name="choices-remote-data" id="choices-remote-data"></select>
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-remote-data"
|
||||||
|
id="choices-remote-data"
|
||||||
|
></select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-test-hook="scrolling-dropdown">
|
<div data-test-hook="scrolling-dropdown">
|
||||||
<label for="choices-scrolling-dropdown">Scrolling dropdown</label>
|
<label for="choices-scrolling-dropdown">Scrolling dropdown</label>
|
||||||
<select class="form-control" name="choices-scrolling-dropdown" id="choices-scrolling-dropdown">
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-scrolling-dropdown"
|
||||||
|
id="choices-scrolling-dropdown"
|
||||||
|
>
|
||||||
<option value="Choice 1">Choice 1</option>
|
<option value="Choice 1">Choice 1</option>
|
||||||
<option value="Choice 2">Choice 2</option>
|
<option value="Choice 2">Choice 2</option>
|
||||||
<option value="Choice 3">Choice 3</option>
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
@ -143,7 +214,12 @@
|
||||||
|
|
||||||
<div data-test-hook="groups">
|
<div data-test-hook="groups">
|
||||||
<label for="choices-groups">Choice groups</label>
|
<label for="choices-groups">Choice groups</label>
|
||||||
<select class="form-control" name="choices-groups" id="choices-groups" multiple>
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-groups"
|
||||||
|
id="choices-groups"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
<optgroup label="UK">
|
<optgroup label="UK">
|
||||||
<option value="London">London</option>
|
<option value="London">London</option>
|
||||||
<option value="Manchester">Manchester</option>
|
<option value="Manchester">Manchester</option>
|
||||||
|
@ -159,7 +235,11 @@
|
||||||
|
|
||||||
<div data-test-hook="parent-child">
|
<div data-test-hook="parent-child">
|
||||||
<label for="choices-parent">Parent</label>
|
<label for="choices-parent">Parent</label>
|
||||||
<select class="form-control" name="choices-parent" id="choices-parent">
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-parent"
|
||||||
|
id="choices-parent"
|
||||||
|
>
|
||||||
<option value="Parent choice 1">Parent choice 1</option>
|
<option value="Parent choice 1">Parent choice 1</option>
|
||||||
<option value="Parent choice 2">Parent choice 2</option>
|
<option value="Parent choice 2">Parent choice 2</option>
|
||||||
<option value="Parent choice 3">Parent choice 3</option>
|
<option value="Parent choice 3">Parent choice 3</option>
|
||||||
|
@ -175,26 +255,44 @@
|
||||||
|
|
||||||
<div data-test-hook="custom-properties">
|
<div data-test-hook="custom-properties">
|
||||||
<label for="choices-custom-properties">Custom properties</label>
|
<label for="choices-custom-properties">Custom properties</label>
|
||||||
<select class="form-control" name="choices-custom-properties" id="choices-custom-properties"></select>
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-custom-properties"
|
||||||
|
id="choices-custom-properties"
|
||||||
|
></select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-test-hook="non-string-values">
|
<div data-test-hook="non-string-values">
|
||||||
<label for="choices-non-string-values">Non-string values</label>
|
<label for="choices-non-string-values">Non-string values</label>
|
||||||
<select class="form-control" name="choices-non-string-values" id="choices-non-string-values"></select>
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-non-string-values"
|
||||||
|
id="choices-non-string-values"
|
||||||
|
></select>
|
||||||
</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>
|
||||||
<select class="form-control" name="choices-within-form" id="choices-within-form">
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-within-form"
|
||||||
|
id="choices-within-form"
|
||||||
|
>
|
||||||
<option value="Choice 1">Choice 1</option>
|
<option value="Choice 1">Choice 1</option>
|
||||||
</select>
|
</select>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-test-hook="set-choice-by-value">
|
<div data-test-hook="set-choice-by-value">
|
||||||
<label for="choices-set-choice-by-value">Dynamically set choice by value</label>
|
<label for="choices-set-choice-by-value"
|
||||||
<select class="form-control" name="choices-set-choice-by-value" id="choices-set-choice-by-value">
|
>Dynamically set choice by value</label
|
||||||
|
>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-set-choice-by-value"
|
||||||
|
id="choices-set-choice-by-value"
|
||||||
|
>
|
||||||
<option value="Choice 1">Choice 1</option>
|
<option value="Choice 1">Choice 1</option>
|
||||||
<option value="Choice 2">Choice 2</option>
|
<option value="Choice 2">Choice 2</option>
|
||||||
<option value="Choice 3">Choice 3</option>
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
@ -203,7 +301,11 @@
|
||||||
|
|
||||||
<div data-test-hook="search-by-label">
|
<div data-test-hook="search-by-label">
|
||||||
<label for="choices-search-by-label">Search by label</label>
|
<label for="choices-search-by-label">Search by label</label>
|
||||||
<select class="form-control" name="choices-search-by-label" id="choices-search-by-label">
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-search-by-label"
|
||||||
|
id="choices-search-by-label"
|
||||||
|
>
|
||||||
<option value="value1">label1</option>
|
<option value="value1">label1</option>
|
||||||
<option value="value2">label2</option>
|
<option value="value2">label2</option>
|
||||||
</select>
|
</select>
|
||||||
|
@ -214,13 +316,17 @@
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
const choicesBasic = new Choices('#choices-basic');
|
const choicesBasic = new Choices('#choices-basic');
|
||||||
|
|
||||||
document.querySelector('button.disable').addEventListener('click', () => {
|
document
|
||||||
choicesBasic.disable();
|
.querySelector('button.disable')
|
||||||
});
|
.addEventListener('click', () => {
|
||||||
|
choicesBasic.disable();
|
||||||
|
});
|
||||||
|
|
||||||
document.querySelector('button.enable').addEventListener('click', () => {
|
document
|
||||||
choicesBasic.enable();
|
.querySelector('button.enable')
|
||||||
});
|
.addEventListener('click', () => {
|
||||||
|
choicesBasic.enable();
|
||||||
|
});
|
||||||
|
|
||||||
new Choices('#choices-remove-button', {
|
new Choices('#choices-remove-button', {
|
||||||
removeItemButton: true,
|
removeItemButton: true,
|
||||||
|
@ -242,12 +348,12 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-render-choice-limit', {
|
new Choices('#choices-render-choice-limit', {
|
||||||
renderChoiceLimit: 1
|
renderChoiceLimit: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-search-disabled', {
|
new Choices('#choices-search-disabled', {
|
||||||
searchEnabled: false
|
searchEnabled: false,
|
||||||
})
|
});
|
||||||
|
|
||||||
new Choices('#choices-search-floor', {
|
new Choices('#choices-search-floor', {
|
||||||
searchFloor: 5,
|
searchFloor: 5,
|
||||||
|
@ -255,16 +361,9 @@
|
||||||
|
|
||||||
new Choices('#choices-remote-data', {
|
new Choices('#choices-remote-data', {
|
||||||
shouldSort: false,
|
shouldSort: false,
|
||||||
}).ajax((callback) => {
|
}).setChoices(async () => {
|
||||||
fetch('/data')
|
const res = await fetch('/data');
|
||||||
.then((response) => {
|
return res.json();
|
||||||
response.json().then((data) => {
|
|
||||||
callback(data, 'value', 'label');
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.error(error);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-scrolling-dropdown', {
|
new Choices('#choices-scrolling-dropdown', {
|
||||||
|
@ -276,7 +375,7 @@
|
||||||
const parent = new Choices('#choices-parent');
|
const parent = new Choices('#choices-parent');
|
||||||
const child = new Choices('#choices-child').disable();
|
const child = new Choices('#choices-child').disable();
|
||||||
|
|
||||||
parent.passedElement.element.addEventListener('change', (event) => {
|
parent.passedElement.element.addEventListener('change', event => {
|
||||||
if (event.detail.value === 'Parent choice 2') {
|
if (event.detail.value === 'Parent choice 2') {
|
||||||
child.enable();
|
child.enable();
|
||||||
} else {
|
} else {
|
||||||
|
@ -310,8 +409,8 @@
|
||||||
customProperties: {
|
customProperties: {
|
||||||
country: 'Portugal',
|
country: 'Portugal',
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-non-string-values', {
|
new Choices('#choices-non-string-values', {
|
||||||
|
@ -343,10 +442,12 @@
|
||||||
|
|
||||||
new Choices('#choices-within-form');
|
new Choices('#choices-within-form');
|
||||||
|
|
||||||
new Choices('#choices-set-choice-by-value').setChoiceByValue('Choice 2');
|
new Choices('#choices-set-choice-by-value').setChoiceByValue(
|
||||||
|
'Choice 2',
|
||||||
|
);
|
||||||
|
|
||||||
new Choices('#choices-search-by-label', { searchFields: ['label'] });
|
new Choices('#choices-search-by-label', { searchFields: ['label'] });
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -31,7 +31,6 @@ import {
|
||||||
sortByScore,
|
sortByScore,
|
||||||
generateId,
|
generateId,
|
||||||
findAncestorByAttrName,
|
findAncestorByAttrName,
|
||||||
fetchFromObject,
|
|
||||||
isIE11,
|
isIE11,
|
||||||
existsInArray,
|
existsInArray,
|
||||||
cloneObject,
|
cloneObject,
|
||||||
|
@ -44,6 +43,10 @@ const USER_DEFAULTS = /** @type {Partial<import('../../types/index').Choices.Opt
|
||||||
* Choices
|
* Choices
|
||||||
* @author Josh Johnson<josh@joshuajohnson.co.uk>
|
* @author Josh Johnson<josh@joshuajohnson.co.uk>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {import('../../types/index').Choices.Choice} Choice
|
||||||
|
*/
|
||||||
class Choices {
|
class Choices {
|
||||||
/* ========================================
|
/* ========================================
|
||||||
= Static properties =
|
= Static properties =
|
||||||
|
@ -222,7 +225,7 @@ class Choices {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================
|
/* ========================================
|
||||||
= Public functions =
|
= Public methods =
|
||||||
======================================== */
|
======================================== */
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
|
@ -460,9 +463,93 @@ class Choices {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
setChoices(choices = [], value = '', label = '', replaceChoices = false) {
|
/**
|
||||||
if (!this._isSelectElement || !value) {
|
* Set choices of select input via an array of objects (or function that returns array of object or promise of it),
|
||||||
return this;
|
* a value field name and a label field name.
|
||||||
|
* This behaves the same as passing items via the choices option but can be called after initialising Choices.
|
||||||
|
* This can also be used to add groups of choices (see example 2); Optionally pass a true `replaceChoices` value to remove any existing choices.
|
||||||
|
* Optionally pass a `customProperties` object to add additional data to your choices (useful when searching/filtering etc).
|
||||||
|
*
|
||||||
|
* **Input types affected:** select-one, select-multiple
|
||||||
|
*
|
||||||
|
* @template {object[] | ((instance: Choices) => object[] | Promise<object[]>)} T
|
||||||
|
* @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
|
||||||
|
* @returns {this | Promise<this>}
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```js
|
||||||
|
* const example = new Choices(element);
|
||||||
|
*
|
||||||
|
* example.setChoices([
|
||||||
|
* {value: 'One', label: 'Label One', disabled: true},
|
||||||
|
* {value: 'Two', label: 'Label Two', selected: true},
|
||||||
|
* {value: 'Three', label: 'Label Three'},
|
||||||
|
* ], 'value', 'label', false);
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```js
|
||||||
|
* const example = new Choices(element);
|
||||||
|
*
|
||||||
|
* example.setChoices(async () => {
|
||||||
|
* try {
|
||||||
|
* const items = await fetch('/items');
|
||||||
|
* return items.json()
|
||||||
|
* } catch(err) {
|
||||||
|
* console.error(err)
|
||||||
|
* }
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```js
|
||||||
|
* const example = new Choices(element);
|
||||||
|
*
|
||||||
|
* example.setChoices([{
|
||||||
|
* label: 'Group one',
|
||||||
|
* id: 1,
|
||||||
|
* disabled: false,
|
||||||
|
* choices: [
|
||||||
|
* {value: 'Child One', label: 'Child One', selected: true},
|
||||||
|
* {value: 'Child Two', label: 'Child Two', disabled: true},
|
||||||
|
* {value: 'Child Three', label: 'Child Three'},
|
||||||
|
* ]
|
||||||
|
* },
|
||||||
|
* {
|
||||||
|
* label: 'Group two',
|
||||||
|
* id: 2,
|
||||||
|
* disabled: false,
|
||||||
|
* choices: [
|
||||||
|
* {value: 'Child Four', label: 'Child Four', disabled: true},
|
||||||
|
* {value: 'Child Five', label: 'Child Five'},
|
||||||
|
* {value: 'Child Six', label: 'Child Six', customProperties: {
|
||||||
|
* description: 'Custom description about child six',
|
||||||
|
* random: 'Another random custom property'
|
||||||
|
* }},
|
||||||
|
* ]
|
||||||
|
* }], 'value', 'label', false);
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
setChoices(
|
||||||
|
choicesArrayOrFetcher = [],
|
||||||
|
value = 'value',
|
||||||
|
label = 'label',
|
||||||
|
replaceChoices = false,
|
||||||
|
) {
|
||||||
|
if (!this.initialised)
|
||||||
|
throw new ReferenceError(
|
||||||
|
`setChoices was called on a non-initialized instance of Choices`,
|
||||||
|
);
|
||||||
|
if (!this._isSelectElement)
|
||||||
|
throw new TypeError(`setChoices can't be used with INPUT based Choices`);
|
||||||
|
|
||||||
|
if (typeof value !== 'string' || !value) {
|
||||||
|
throw new TypeError(
|
||||||
|
`value parameter must be a name of 'value' field in passed objects`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear choices if needed
|
// Clear choices if needed
|
||||||
|
@ -470,6 +557,34 @@ class Choices {
|
||||||
this.clearChoices();
|
this.clearChoices();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!Array.isArray(choicesArrayOrFetcher)) {
|
||||||
|
if (typeof choicesArrayOrFetcher !== 'function')
|
||||||
|
throw new TypeError(
|
||||||
|
`.setChoices must be called either with array of choices with a function resulting into Promise of array of choices`,
|
||||||
|
);
|
||||||
|
|
||||||
|
// it's a choices fetcher
|
||||||
|
requestAnimationFrame(() => this._handleLoadingState(true));
|
||||||
|
const fetcher = choicesArrayOrFetcher(this);
|
||||||
|
if (typeof fetcher === 'object' && typeof fetcher.then === 'function') {
|
||||||
|
// that's a promise
|
||||||
|
return fetcher
|
||||||
|
.then(data => this.setChoices(data, value, label, replaceChoices))
|
||||||
|
.catch(err => {
|
||||||
|
if (!this.config.silent) console.error(err);
|
||||||
|
})
|
||||||
|
.then(() => this._handleLoadingState(false))
|
||||||
|
.then(() => this);
|
||||||
|
}
|
||||||
|
// function returned something else than promise, let's check if it's an array of choices
|
||||||
|
if (!Array.isArray(fetcher))
|
||||||
|
throw new TypeError(
|
||||||
|
`.setChoices first argument function must return either array of choices or Promise, got: ${typeof fetcher}`,
|
||||||
|
);
|
||||||
|
// recursion with results, it's sync and choices were cleared already
|
||||||
|
return this.setChoices(fetcher, value, label, false);
|
||||||
|
}
|
||||||
|
|
||||||
this.containerOuter.removeLoadingState();
|
this.containerOuter.removeLoadingState();
|
||||||
const addGroupsAndChoices = groupOrChoice => {
|
const addGroupsAndChoices = groupOrChoice => {
|
||||||
if (groupOrChoice.choices) {
|
if (groupOrChoice.choices) {
|
||||||
|
@ -492,7 +607,7 @@ class Choices {
|
||||||
};
|
};
|
||||||
|
|
||||||
this._setLoading(true);
|
this._setLoading(true);
|
||||||
choices.forEach(addGroupsAndChoices);
|
choicesArrayOrFetcher.forEach(addGroupsAndChoices);
|
||||||
this._setLoading(false);
|
this._setLoading(false);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
|
@ -519,18 +634,7 @@ class Choices {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
ajax(fn) {
|
/* ===== End of Public methods ====== */
|
||||||
if (!this.initialised || !this._isSelectElement || !fn) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
requestAnimationFrame(() => this._handleLoadingState(true));
|
|
||||||
fn(this._ajaxCallback());
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ===== End of Public functions ====== */
|
|
||||||
|
|
||||||
/* =============================================
|
/* =============================================
|
||||||
= Private functions =
|
= Private functions =
|
||||||
|
@ -1054,55 +1158,6 @@ class Choices {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_ajaxCallback() {
|
|
||||||
return (results, value, label) => {
|
|
||||||
if (!results || !value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const parsedResults = isType('Object', results) ? [results] : results;
|
|
||||||
|
|
||||||
if (
|
|
||||||
parsedResults &&
|
|
||||||
isType('Array', parsedResults) &&
|
|
||||||
parsedResults.length
|
|
||||||
) {
|
|
||||||
// Remove loading states/text
|
|
||||||
this._handleLoadingState(false);
|
|
||||||
this._setLoading(true);
|
|
||||||
// Add each result as a choice
|
|
||||||
parsedResults.forEach(result => {
|
|
||||||
if (result.choices) {
|
|
||||||
this._addGroup({
|
|
||||||
group: result,
|
|
||||||
id: result.id || null,
|
|
||||||
valueKey: value,
|
|
||||||
labelKey: label,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this._addChoice({
|
|
||||||
value: fetchFromObject(result, value),
|
|
||||||
label: fetchFromObject(result, label),
|
|
||||||
isSelected: result.selected,
|
|
||||||
isDisabled: result.disabled,
|
|
||||||
customProperties: result.customProperties,
|
|
||||||
placeholder: result.placeholder,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this._setLoading(false);
|
|
||||||
|
|
||||||
if (this._isSelectOneElement) {
|
|
||||||
this._selectPlaceholderChoice();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// No results, remove loading state
|
|
||||||
this._handleLoadingState(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
_searchChoices(value) {
|
_searchChoices(value) {
|
||||||
const newValue = isType('String', value) ? value.trim() : value;
|
const newValue = isType('String', value) ? value.trim() : value;
|
||||||
const currentValue = isType('String', this._currentValue)
|
const currentValue = isType('String', this._currentValue)
|
||||||
|
|
|
@ -881,84 +881,74 @@ describe('choices', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('ajax', () => {
|
describe('setChoices with callback/Promise', () => {
|
||||||
const callbackoutput = 'worked';
|
|
||||||
|
|
||||||
let handleLoadingStateStub;
|
|
||||||
let ajaxCallbackStub;
|
|
||||||
|
|
||||||
const returnsEarly = () => {
|
|
||||||
it('returns early', () => {
|
|
||||||
expect(handleLoadingStateStub.called).to.equal(false);
|
|
||||||
expect(ajaxCallbackStub.called).to.equal(false);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
handleLoadingStateStub = stub();
|
|
||||||
ajaxCallbackStub = stub().returns(callbackoutput);
|
|
||||||
|
|
||||||
instance._ajaxCallback = ajaxCallbackStub;
|
|
||||||
instance._handleLoadingState = handleLoadingStateStub;
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
instance._ajaxCallback.reset();
|
|
||||||
instance._handleLoadingState.reset();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('not initialised', () => {
|
describe('not initialised', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
instance.initialised = false;
|
instance.initialised = false;
|
||||||
output = instance.ajax(() => {});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
returnsInstance(output);
|
it('should throw', () => {
|
||||||
returnsEarly();
|
expect(() => instance.setChoices(null)).Throw(ReferenceError);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('text element', () => {
|
describe('text element', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
instance._isSelectElement = false;
|
instance._isSelectElement = false;
|
||||||
output = instance.ajax(() => {});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
returnsInstance(output);
|
it('should throw', () => {
|
||||||
returnsEarly();
|
expect(() => instance.setChoices(null)).Throw(TypeError);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('passing invalid function', () => {
|
describe('passing invalid function', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
output = instance.ajax(null);
|
instance._isSelectElement = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
returnsInstance(output);
|
it('should throw on non function', () => {
|
||||||
returnsEarly();
|
expect(() => instance.setChoices(null)).Throw(TypeError, /Promise/i);
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should throw on function that doesn't return promise`, () => {
|
||||||
|
expect(() => instance.setChoices(() => 'boo')).to.throw(
|
||||||
|
TypeError,
|
||||||
|
/promise/i,
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('select element', () => {
|
describe('select element', () => {
|
||||||
let callback;
|
it('fetches and sets choices', async () => {
|
||||||
|
document.body.innerHTML = '<select id="test" />';
|
||||||
|
const choice = new Choices('#test');
|
||||||
|
const handleLoadingStateSpy = spy(choice, '_handleLoadingState');
|
||||||
|
|
||||||
beforeEach(() => {
|
let fetcherCalled = false;
|
||||||
instance.initialised = true;
|
const fetcher = async inst => {
|
||||||
instance._isSelectElement = true;
|
expect(inst).to.eq(choice);
|
||||||
ajaxCallbackStub = stub();
|
fetcherCalled = true;
|
||||||
callback = stub();
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||||
output = instance.ajax(callback);
|
return [
|
||||||
});
|
{ label: 'l1', value: 'v1', customProperties: 'prop1' },
|
||||||
|
{ label: 'l2', value: 'v2', customProperties: 'prop2' },
|
||||||
returnsInstance(output);
|
];
|
||||||
|
};
|
||||||
it('sets loading state', done => {
|
expect(choice._store.choices.length).to.equal(0);
|
||||||
requestAnimationFrame(() => {
|
const promise = choice.setChoices(fetcher);
|
||||||
expect(handleLoadingStateStub.called).to.equal(true);
|
await new Promise(resolve =>
|
||||||
done();
|
requestAnimationFrame(() => {
|
||||||
});
|
expect(handleLoadingStateSpy.callCount).to.equal(1);
|
||||||
});
|
resolve();
|
||||||
|
}),
|
||||||
it('calls passed function with ajax callback', () => {
|
);
|
||||||
expect(callback.called).to.equal(true);
|
expect(fetcherCalled).to.be.true;
|
||||||
expect(callback.lastCall.args[0]).to.eql(callbackoutput);
|
const res = await promise;
|
||||||
|
expect(res).to.equal(choice);
|
||||||
|
expect(choice._store.choices[1].value).to.equal('v2');
|
||||||
|
expect(choice._store.choices[1].label).to.equal('l2');
|
||||||
|
expect(choice._store.choices[1].customProperties).to.equal('prop2');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1353,31 +1343,29 @@ describe('choices', () => {
|
||||||
instance.containerOuter.removeLoadingState.reset();
|
instance.containerOuter.removeLoadingState.reset();
|
||||||
});
|
});
|
||||||
|
|
||||||
const returnsEarly = () => {
|
|
||||||
it('returns early', () => {
|
|
||||||
expect(addGroupStub.called).to.equal(false);
|
|
||||||
expect(addChoiceStub.called).to.equal(false);
|
|
||||||
expect(clearChoicesStub.called).to.equal(false);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
describe('when element is not select element', () => {
|
describe('when element is not select element', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
instance._isSelectElement = false;
|
instance._isSelectElement = false;
|
||||||
instance.setChoices(choices, value, label, false);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
returnsEarly();
|
it('throws', () => {
|
||||||
|
expect(() =>
|
||||||
|
instance.setChoices(choices, value, label, false),
|
||||||
|
).to.throw(TypeError, /input/i);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('passing invalid arguments', () => {
|
describe('passing invalid arguments', () => {
|
||||||
describe('passing no value', () => {
|
describe('passing no value', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
instance._isSelectElement = true;
|
instance._isSelectElement = true;
|
||||||
instance.setChoices(choices, undefined, 'label', false);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
returnsEarly();
|
it('throws', () => {
|
||||||
|
expect(() =>
|
||||||
|
instance.setChoices(choices, null, 'label', false),
|
||||||
|
).to.throw(TypeError, /value/i);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -142,19 +142,6 @@ export const getWindowHeight = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchFromObject = (object, path) => {
|
|
||||||
const index = path.indexOf('.');
|
|
||||||
|
|
||||||
if (index > -1) {
|
|
||||||
return fetchFromObject(
|
|
||||||
object[path.substring(0, index)],
|
|
||||||
path.substr(index + 1),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return object[path];
|
|
||||||
};
|
|
||||||
|
|
||||||
export const isIE11 = () =>
|
export const isIE11 = () =>
|
||||||
!!(
|
!!(
|
||||||
navigator.userAgent.match(/Trident/) &&
|
navigator.userAgent.match(/Trident/) &&
|
||||||
|
|
|
@ -10,7 +10,6 @@ import {
|
||||||
sanitise,
|
sanitise,
|
||||||
sortByAlpha,
|
sortByAlpha,
|
||||||
sortByScore,
|
sortByScore,
|
||||||
fetchFromObject,
|
|
||||||
existsInArray,
|
existsInArray,
|
||||||
cloneObject,
|
cloneObject,
|
||||||
dispatchEvent,
|
dispatchEvent,
|
||||||
|
@ -198,19 +197,6 @@ describe('utils', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('fetchFromObject', () => {
|
|
||||||
it('fetches value from object using given path', () => {
|
|
||||||
const object = {
|
|
||||||
band: {
|
|
||||||
name: 'The Strokes',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const output = fetchFromObject(object, 'band.name');
|
|
||||||
expect(output).to.equal(object.band.name);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('existsInArray', () => {
|
describe('existsInArray', () => {
|
||||||
it('determines whether a value exists within given array', () => {
|
it('determines whether a value exists within given array', () => {
|
||||||
const values = [
|
const values = [
|
||||||
|
|
112
types/index.d.ts
vendored
112
types/index.d.ts
vendored
|
@ -872,16 +872,47 @@ export default class Choices {
|
||||||
*/
|
*/
|
||||||
getValue(valueOnly?: boolean): string | string[];
|
getValue(valueOnly?: boolean): string | string[];
|
||||||
|
|
||||||
|
/** Direct populate choices
|
||||||
|
*
|
||||||
|
* @param {string[] | Choices.Item[]} items
|
||||||
|
*/
|
||||||
|
setValue(items: string[] | Choices.Item[]): this;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set choices of select input via an array of objects, a value name and a label name.
|
* Set value of input based on existing Choice. `value` can be either a single string or an array of strings
|
||||||
|
*
|
||||||
|
* **Input types affected:** select-one, select-multiple
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```
|
||||||
|
* const example = new Choices(element, {
|
||||||
|
* choices: [
|
||||||
|
* {value: 'One', label: 'Label One'},
|
||||||
|
* {value: 'Two', label: 'Label Two', disabled: true},
|
||||||
|
* {value: 'Three', label: 'Label Three'},
|
||||||
|
* ],
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* example.setChoiceByValue('Two'); // Choice with value of 'Two' has now been selected.
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
setChoiceByValue(value: string | string[]): this;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set choices of select input via an array of objects (or function that returns array of object or promise of it),
|
||||||
|
* a value field name and a label field name.
|
||||||
* This behaves the same as passing items via the choices option but can be called after initialising Choices.
|
* This behaves the same as passing items via the choices option but can be called after initialising Choices.
|
||||||
* This can also be used to add groups of choices (see example 2); Optionally pass a true `replaceChoices` value to remove any existing choices.
|
* This can also be used to add groups of choices (see example 2); Optionally pass a true `replaceChoices` value to remove any existing choices.
|
||||||
* Optionally pass a `customProperties` object to add additional data to your choices (useful when searching/filtering etc).
|
* Optionally pass a `customProperties` object to add additional data to your choices (useful when searching/filtering etc).
|
||||||
*
|
*
|
||||||
* **Input types affected:** select-one, select-multiple
|
* **Input types affected:** select-one, select-multiple
|
||||||
*
|
*
|
||||||
* @example Example 1:
|
* @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
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```js
|
||||||
* const example = new Choices(element);
|
* const example = new Choices(element);
|
||||||
*
|
*
|
||||||
* example.setChoices([
|
* example.setChoices([
|
||||||
|
@ -891,8 +922,22 @@ export default class Choices {
|
||||||
* ], 'value', 'label', false);
|
* ], 'value', 'label', false);
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* @example Example 2:
|
* @example
|
||||||
|
* ```js
|
||||||
|
* const example = new Choices(element);
|
||||||
|
*
|
||||||
|
* example.setChoices(async () => {
|
||||||
|
* try {
|
||||||
|
* const items = await fetch('/items');
|
||||||
|
* return items.json()
|
||||||
|
* } catch(err) {
|
||||||
|
* console.error(err)
|
||||||
|
* }
|
||||||
|
* });
|
||||||
* ```
|
* ```
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```js
|
||||||
* const example = new Choices(element);
|
* const example = new Choices(element);
|
||||||
*
|
*
|
||||||
* example.setChoices([{
|
* example.setChoices([{
|
||||||
|
@ -920,35 +965,14 @@ export default class Choices {
|
||||||
* }], 'value', 'label', false);
|
* }], 'value', 'label', false);
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
setValue(args: string[]): this;
|
setChoices<
|
||||||
|
T extends object[] | ((instance: Choices) => object[] | Promise<object[]>)
|
||||||
/**
|
>(
|
||||||
* Set value of input based on existing Choice. `value` can be either a single string or an array of strings
|
choices: T,
|
||||||
*
|
value?: string,
|
||||||
* **Input types affected:** select-one, select-multiple
|
label?: string,
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* const example = new Choices(element, {
|
|
||||||
* choices: [
|
|
||||||
* {value: 'One', label: 'Label One'},
|
|
||||||
* {value: 'Two', label: 'Label Two', disabled: true},
|
|
||||||
* {value: 'Three', label: 'Label Three'},
|
|
||||||
* ],
|
|
||||||
* });
|
|
||||||
*
|
|
||||||
* example.setChoiceByValue('Two'); // Choice with value of 'Two' has now been selected.
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
setChoiceByValue(value: string | string[]): this;
|
|
||||||
|
|
||||||
/** Direct populate choices */
|
|
||||||
setChoices(
|
|
||||||
choices: Choices.Choice[],
|
|
||||||
value: string,
|
|
||||||
label: string,
|
|
||||||
replaceChoices?: boolean,
|
replaceChoices?: boolean,
|
||||||
): this;
|
): T extends object[] ? this : Promise<this>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear all choices from select.
|
* Clear all choices from select.
|
||||||
|
@ -984,28 +1008,4 @@ export default class Choices {
|
||||||
* **Input types affected:** text, select-one, select-multiple
|
* **Input types affected:** text, select-one, select-multiple
|
||||||
*/
|
*/
|
||||||
disable(): this;
|
disable(): this;
|
||||||
|
|
||||||
/**
|
|
||||||
* Populate choices/groups via a callback.
|
|
||||||
*
|
|
||||||
* **Input types affected:** select-one, select-multiple
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* var example = new Choices(element);
|
|
||||||
*
|
|
||||||
* example.ajax(function(callback) {
|
|
||||||
* fetch(url)
|
|
||||||
* .then(function(response) {
|
|
||||||
* response.json().then(function(data) {
|
|
||||||
* callback(data, 'value', 'label');
|
|
||||||
* });
|
|
||||||
* })
|
|
||||||
* .catch(function(error) {
|
|
||||||
* console.log(error);
|
|
||||||
* });
|
|
||||||
* });
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
ajax(fn: (values: any) => any): this;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue