Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix setChoices regression in v11.0.4, where replaceChoices argument would deselect selected items. Fixes #1278 #1279

Merged
merged 6 commits into from
Feb 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1088,13 +1088,13 @@ choices.disable();

**Usage:** Hide choices list dropdown.

### setChoices(choicesArrayOrFetcher?: (InputChoice | InputGroup)[] | ((instance: Choices) => (InputChoice | InputGroup)[] | Promise<(InputChoice | InputGroup)[]>), value?: string | null, label?: string, replaceChoices?: boolean): this | Promise<this>;
### setChoices(choicesArrayOrFetcher?: (InputChoice | InputGroup)[] | ((instance: Choices) => (InputChoice | InputGroup)[] | Promise<(InputChoice | InputGroup)[]>), value?: string | null, label?: string, replaceChoices?: boolean = false, clearSearchFlag?: boolean = false, replaceItems?: boolean = false): this | Promise<this>;

**Input types affected:** `select-one`, `select-multiple`

**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).
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 true `replaceItems` value to remove any items, if false choices for selected items are preserved. 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:**

Expand Down
22 changes: 16 additions & 6 deletions public/assets/scripts/choices.js
Original file line number Diff line number Diff line change
Expand Up @@ -3769,13 +3769,14 @@
* }], 'value', 'label', false);
* ```
*/
Choices.prototype.setChoices = function (choicesArrayOrFetcher, value, label, replaceChoices, clearSearchFlag) {
Choices.prototype.setChoices = function (choicesArrayOrFetcher, value, label, replaceChoices, clearSearchFlag, replaceItems) {
var _this = this;
if (choicesArrayOrFetcher === void 0) { choicesArrayOrFetcher = []; }
if (value === void 0) { value = 'value'; }
if (label === void 0) { label = 'label'; }
if (replaceChoices === void 0) { replaceChoices = false; }
if (clearSearchFlag === void 0) { clearSearchFlag = true; }
if (replaceItems === void 0) { replaceItems = false; }
if (!this.initialisedOK) {
this._warnChoicesInitFailed('setChoices');
return this;
Expand All @@ -3786,10 +3787,6 @@
if (typeof value !== 'string' || !value) {
throw new TypeError("value parameter must be a name of 'value' field in passed objects");
}
// Clear choices if needed
if (replaceChoices) {
this.clearChoices();
}
if (typeof choicesArrayOrFetcher === 'function') {
// it's a choices fetcher function
var fetcher_1 = choicesArrayOrFetcher(this);
Expand All @@ -3799,7 +3796,7 @@
return new Promise(function (resolve) { return requestAnimationFrame(resolve); })
.then(function () { return _this._handleLoadingState(true); })
.then(function () { return fetcher_1; })
.then(function (data) { return _this.setChoices(data, value, label, replaceChoices); })
.then(function (data) { return _this.setChoices(data, value, label, replaceChoices, clearSearchFlag, replaceItems); })
.catch(function (err) {
if (!_this.config.silent) {
console.error(err);
Expand All @@ -3823,6 +3820,16 @@
if (clearSearchFlag) {
_this._isSearching = false;
}
var items = {};
if (!replaceItems) {
_this._store.items.forEach(function (item) {
items[item.value] = item;
});
}
// Clear choices if needed
if (replaceChoices) {
_this.clearChoices();
}
var isDefaultValue = value === 'value';
var isDefaultLabel = label === 'label';
choicesArrayOrFetcher.forEach(function (groupOrChoice) {
Expand All @@ -3839,6 +3846,9 @@
choice = __assign(__assign({}, choice), { value: choice[value], label: choice[label] });
}
var choiceFull = mapInputToChoice(choice, false);
if (!replaceItems && choiceFull.value in items) {
choiceFull.selected = true;
}
_this._addChoice(choiceFull);
if (choiceFull.placeholder && !_this._hasNonChoicePlaceholder) {
_this._placeholderValue = unwrapStringForEscaped(choiceFull.label);
Expand Down
2 changes: 1 addition & 1 deletion public/assets/scripts/choices.min.js

Large diffs are not rendered by default.

22 changes: 16 additions & 6 deletions public/assets/scripts/choices.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3763,13 +3763,14 @@ var Choices = /** @class */ (function () {
* }], 'value', 'label', false);
* ```
*/
Choices.prototype.setChoices = function (choicesArrayOrFetcher, value, label, replaceChoices, clearSearchFlag) {
Choices.prototype.setChoices = function (choicesArrayOrFetcher, value, label, replaceChoices, clearSearchFlag, replaceItems) {
var _this = this;
if (choicesArrayOrFetcher === void 0) { choicesArrayOrFetcher = []; }
if (value === void 0) { value = 'value'; }
if (label === void 0) { label = 'label'; }
if (replaceChoices === void 0) { replaceChoices = false; }
if (clearSearchFlag === void 0) { clearSearchFlag = true; }
if (replaceItems === void 0) { replaceItems = false; }
if (!this.initialisedOK) {
this._warnChoicesInitFailed('setChoices');
return this;
Expand All @@ -3780,10 +3781,6 @@ var Choices = /** @class */ (function () {
if (typeof value !== 'string' || !value) {
throw new TypeError("value parameter must be a name of 'value' field in passed objects");
}
// Clear choices if needed
if (replaceChoices) {
this.clearChoices();
}
if (typeof choicesArrayOrFetcher === 'function') {
// it's a choices fetcher function
var fetcher_1 = choicesArrayOrFetcher(this);
Expand All @@ -3793,7 +3790,7 @@ var Choices = /** @class */ (function () {
return new Promise(function (resolve) { return requestAnimationFrame(resolve); })
.then(function () { return _this._handleLoadingState(true); })
.then(function () { return fetcher_1; })
.then(function (data) { return _this.setChoices(data, value, label, replaceChoices); })
.then(function (data) { return _this.setChoices(data, value, label, replaceChoices, clearSearchFlag, replaceItems); })
.catch(function (err) {
if (!_this.config.silent) {
console.error(err);
Expand All @@ -3817,6 +3814,16 @@ var Choices = /** @class */ (function () {
if (clearSearchFlag) {
_this._isSearching = false;
}
var items = {};
if (!replaceItems) {
_this._store.items.forEach(function (item) {
items[item.value] = item;
});
}
// Clear choices if needed
if (replaceChoices) {
_this.clearChoices();
}
var isDefaultValue = value === 'value';
var isDefaultLabel = label === 'label';
choicesArrayOrFetcher.forEach(function (groupOrChoice) {
Expand All @@ -3833,6 +3840,9 @@ var Choices = /** @class */ (function () {
choice = __assign(__assign({}, choice), { value: choice[value], label: choice[label] });
}
var choiceFull = mapInputToChoice(choice, false);
if (!replaceItems && choiceFull.value in items) {
choiceFull.selected = true;
}
_this._addChoice(choiceFull);
if (choiceFull.placeholder && !_this._hasNonChoicePlaceholder) {
_this._placeholderValue = unwrapStringForEscaped(choiceFull.label);
Expand Down
22 changes: 16 additions & 6 deletions public/assets/scripts/choices.search-basic.js
Original file line number Diff line number Diff line change
Expand Up @@ -3287,13 +3287,14 @@
* }], 'value', 'label', false);
* ```
*/
Choices.prototype.setChoices = function (choicesArrayOrFetcher, value, label, replaceChoices, clearSearchFlag) {
Choices.prototype.setChoices = function (choicesArrayOrFetcher, value, label, replaceChoices, clearSearchFlag, replaceItems) {
var _this = this;
if (choicesArrayOrFetcher === void 0) { choicesArrayOrFetcher = []; }
if (value === void 0) { value = 'value'; }
if (label === void 0) { label = 'label'; }
if (replaceChoices === void 0) { replaceChoices = false; }
if (clearSearchFlag === void 0) { clearSearchFlag = true; }
if (replaceItems === void 0) { replaceItems = false; }
if (!this.initialisedOK) {
this._warnChoicesInitFailed('setChoices');
return this;
Expand All @@ -3304,10 +3305,6 @@
if (typeof value !== 'string' || !value) {
throw new TypeError("value parameter must be a name of 'value' field in passed objects");
}
// Clear choices if needed
if (replaceChoices) {
this.clearChoices();
}
if (typeof choicesArrayOrFetcher === 'function') {
// it's a choices fetcher function
var fetcher_1 = choicesArrayOrFetcher(this);
Expand All @@ -3317,7 +3314,7 @@
return new Promise(function (resolve) { return requestAnimationFrame(resolve); })
.then(function () { return _this._handleLoadingState(true); })
.then(function () { return fetcher_1; })
.then(function (data) { return _this.setChoices(data, value, label, replaceChoices); })
.then(function (data) { return _this.setChoices(data, value, label, replaceChoices, clearSearchFlag, replaceItems); })
.catch(function (err) {
if (!_this.config.silent) {
console.error(err);
Expand All @@ -3341,6 +3338,16 @@
if (clearSearchFlag) {
_this._isSearching = false;
}
var items = {};
if (!replaceItems) {
_this._store.items.forEach(function (item) {
items[item.value] = item;
});
}
// Clear choices if needed
if (replaceChoices) {
_this.clearChoices();
}
var isDefaultValue = value === 'value';
var isDefaultLabel = label === 'label';
choicesArrayOrFetcher.forEach(function (groupOrChoice) {
Expand All @@ -3357,6 +3364,9 @@
choice = __assign(__assign({}, choice), { value: choice[value], label: choice[label] });
}
var choiceFull = mapInputToChoice(choice, false);
if (!replaceItems && choiceFull.value in items) {
choiceFull.selected = true;
}
_this._addChoice(choiceFull);
if (choiceFull.placeholder && !_this._hasNonChoicePlaceholder) {
_this._placeholderValue = unwrapStringForEscaped(choiceFull.label);
Expand Down
2 changes: 1 addition & 1 deletion public/assets/scripts/choices.search-basic.min.js

Large diffs are not rendered by default.

22 changes: 16 additions & 6 deletions public/assets/scripts/choices.search-basic.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3281,13 +3281,14 @@ var Choices = /** @class */ (function () {
* }], 'value', 'label', false);
* ```
*/
Choices.prototype.setChoices = function (choicesArrayOrFetcher, value, label, replaceChoices, clearSearchFlag) {
Choices.prototype.setChoices = function (choicesArrayOrFetcher, value, label, replaceChoices, clearSearchFlag, replaceItems) {
var _this = this;
if (choicesArrayOrFetcher === void 0) { choicesArrayOrFetcher = []; }
if (value === void 0) { value = 'value'; }
if (label === void 0) { label = 'label'; }
if (replaceChoices === void 0) { replaceChoices = false; }
if (clearSearchFlag === void 0) { clearSearchFlag = true; }
if (replaceItems === void 0) { replaceItems = false; }
if (!this.initialisedOK) {
this._warnChoicesInitFailed('setChoices');
return this;
Expand All @@ -3298,10 +3299,6 @@ var Choices = /** @class */ (function () {
if (typeof value !== 'string' || !value) {
throw new TypeError("value parameter must be a name of 'value' field in passed objects");
}
// Clear choices if needed
if (replaceChoices) {
this.clearChoices();
}
if (typeof choicesArrayOrFetcher === 'function') {
// it's a choices fetcher function
var fetcher_1 = choicesArrayOrFetcher(this);
Expand All @@ -3311,7 +3308,7 @@ var Choices = /** @class */ (function () {
return new Promise(function (resolve) { return requestAnimationFrame(resolve); })
.then(function () { return _this._handleLoadingState(true); })
.then(function () { return fetcher_1; })
.then(function (data) { return _this.setChoices(data, value, label, replaceChoices); })
.then(function (data) { return _this.setChoices(data, value, label, replaceChoices, clearSearchFlag, replaceItems); })
.catch(function (err) {
if (!_this.config.silent) {
console.error(err);
Expand All @@ -3335,6 +3332,16 @@ var Choices = /** @class */ (function () {
if (clearSearchFlag) {
_this._isSearching = false;
}
var items = {};
if (!replaceItems) {
_this._store.items.forEach(function (item) {
items[item.value] = item;
});
}
// Clear choices if needed
if (replaceChoices) {
_this.clearChoices();
}
var isDefaultValue = value === 'value';
var isDefaultLabel = label === 'label';
choicesArrayOrFetcher.forEach(function (groupOrChoice) {
Expand All @@ -3351,6 +3358,9 @@ var Choices = /** @class */ (function () {
choice = __assign(__assign({}, choice), { value: choice[value], label: choice[label] });
}
var choiceFull = mapInputToChoice(choice, false);
if (!replaceItems && choiceFull.value in items) {
choiceFull.selected = true;
}
_this._addChoice(choiceFull);
if (choiceFull.placeholder && !_this._hasNonChoicePlaceholder) {
_this._placeholderValue = unwrapStringForEscaped(choiceFull.label);
Expand Down
22 changes: 16 additions & 6 deletions public/assets/scripts/choices.search-prefix.js
Original file line number Diff line number Diff line change
Expand Up @@ -2129,13 +2129,14 @@
* }], 'value', 'label', false);
* ```
*/
Choices.prototype.setChoices = function (choicesArrayOrFetcher, value, label, replaceChoices, clearSearchFlag) {
Choices.prototype.setChoices = function (choicesArrayOrFetcher, value, label, replaceChoices, clearSearchFlag, replaceItems) {
var _this = this;
if (choicesArrayOrFetcher === void 0) { choicesArrayOrFetcher = []; }
if (value === void 0) { value = 'value'; }
if (label === void 0) { label = 'label'; }
if (replaceChoices === void 0) { replaceChoices = false; }
if (clearSearchFlag === void 0) { clearSearchFlag = true; }
if (replaceItems === void 0) { replaceItems = false; }
if (!this.initialisedOK) {
this._warnChoicesInitFailed('setChoices');
return this;
Expand All @@ -2146,10 +2147,6 @@
if (typeof value !== 'string' || !value) {
throw new TypeError("value parameter must be a name of 'value' field in passed objects");
}
// Clear choices if needed
if (replaceChoices) {
this.clearChoices();
}
if (typeof choicesArrayOrFetcher === 'function') {
// it's a choices fetcher function
var fetcher_1 = choicesArrayOrFetcher(this);
Expand All @@ -2159,7 +2156,7 @@
return new Promise(function (resolve) { return requestAnimationFrame(resolve); })
.then(function () { return _this._handleLoadingState(true); })
.then(function () { return fetcher_1; })
.then(function (data) { return _this.setChoices(data, value, label, replaceChoices); })
.then(function (data) { return _this.setChoices(data, value, label, replaceChoices, clearSearchFlag, replaceItems); })
.catch(function (err) {
if (!_this.config.silent) {
console.error(err);
Expand All @@ -2183,6 +2180,16 @@
if (clearSearchFlag) {
_this._isSearching = false;
}
var items = {};
if (!replaceItems) {
_this._store.items.forEach(function (item) {
items[item.value] = item;
});
}
// Clear choices if needed
if (replaceChoices) {
_this.clearChoices();
}
var isDefaultValue = value === 'value';
var isDefaultLabel = label === 'label';
choicesArrayOrFetcher.forEach(function (groupOrChoice) {
Expand All @@ -2199,6 +2206,9 @@
choice = __assign(__assign({}, choice), { value: choice[value], label: choice[label] });
}
var choiceFull = mapInputToChoice(choice, false);
if (!replaceItems && choiceFull.value in items) {
choiceFull.selected = true;
}
_this._addChoice(choiceFull);
if (choiceFull.placeholder && !_this._hasNonChoicePlaceholder) {
_this._placeholderValue = unwrapStringForEscaped(choiceFull.label);
Expand Down
2 changes: 1 addition & 1 deletion public/assets/scripts/choices.search-prefix.min.js

Large diffs are not rendered by default.

Loading
Loading