Adding an item comparer configuration to allow custom comparisons of items.

This commit is contained in:
Travis Tidwell 2018-02-02 09:09:21 -06:00 committed by Josh Johnson
parent 5f11caae1b
commit 0519b99397
3 changed files with 67 additions and 1 deletions

View file

@ -99,6 +99,9 @@ Or include Choices directly:
maxItemText: (maxItemCount) => {
return `Only ${maxItemCount} values can be added.`;
},
itemComparer: (choice, item) => {
return choice === item;
},
classNames: {
containerOuter: 'choices',
containerInner: 'choices__inner',
@ -458,6 +461,13 @@ const example = new Choices(element, {
**Usage:** The text that is shown when a user has focus on the input but has already reached the [max item count](https://github.com/jshjohnson/Choices#maxitemcount). To access the max item count, pass a function with a `maxItemCount` argument (see the [default config](https://github.com/jshjohnson/Choices#setup) for an example), otherwise pass a string.
### itemComparer
**Type:** `Function` **Default:** `strict equality`
**Input types affected:** `select-one`, `select-multiple`
**Usage:** Compare choice and value in appropriate way (e.g. deep equality for objects). To compare choice and value, pass a function with a `itemComparer` argument (see the [default config](https://github.com/jshjohnson/Choices#setup) for an example).
### classNames
**Type:** `Object` **Default:**

View file

@ -90,6 +90,9 @@ class Choices {
maxItemText: (maxItemCount) => {
return `Only ${maxItemCount} values can be added.`;
},
itemComparer: (choice, item) => {
return choice === item;
},
uniqueItemText: 'Only unique values can be added.',
classNames: {
containerOuter: 'choices',
@ -947,7 +950,7 @@ class Choices {
choiceValue.forEach((val) => {
const foundChoice = choices.find((choice) => {
// Check 'value' property exists and the choice isn't already selected
return choice.value === val;
return this.config.itemComparer(choice.value, val);
});
if (foundChoice) {

View file

@ -78,6 +78,7 @@ describe('Choices', () => {
expect(this.choices.config.noChoicesText).toEqual(jasmine.any(String));
expect(this.choices.config.itemSelectText).toEqual(jasmine.any(String));
expect(this.choices.config.classNames).toEqual(jasmine.any(Object));
expect(this.choices.config.itemComparer).toEqual(jasmine.any(Function));
expect(this.choices.config.callbackOnInit).toEqual(null);
expect(this.choices.config.callbackOnCreateTemplates).toEqual(null);
});
@ -1217,4 +1218,56 @@ describe('Choices', () => {
expect(selectedItems[0].customProperties).toBe(expectedCustomProperties);
});
});
describe('should allow to use object in value', function() {
beforeEach(function() {
this.input = document.createElement('select');
this.input.className = 'js-choices';
this.input.setAttribute('multiple', '');
document.body.appendChild(this.input);
this.choicesArray = [
{
label: 'One',
value: {
id: 1
}
},
{
label: 'Two',
value: {
id: 2
}
},
{
label: 'Three',
value: {
id: 3
}
}
];
});
afterEach(function() {
this.choices.destroy();
});
it('should allow the user to supply itemComparer via options', function() {
function comparer(choice, item) {
return choice.id === item.id;
}
this.choices = new Choices(this.input, {
itemComparer: comparer,
choices: this.choicesArray
});
this.choices.setValueByChoice({
id: 1
});
expect(this.choices.currentState.items[0].label).toBe(this.choicesArray[0].label);
});
});
});