mirror of
https://github.com/Choices-js/Choices.git
synced 2024-06-27 18:01:54 +02:00
Merge pull request #984 from victiondev/feat/allowHTML
feat: Introduce allowHTML option to allow people to disable injecting HTML into choices.
This commit is contained in:
commit
0b6973b322
17
README.md
17
README.md
|
@ -109,6 +109,7 @@ Or include Choices directly:
|
||||||
removeItems: true,
|
removeItems: true,
|
||||||
removeItemButton: false,
|
removeItemButton: false,
|
||||||
editItems: false,
|
editItems: false,
|
||||||
|
allowHTML: true
|
||||||
duplicateItemsAllowed: true,
|
duplicateItemsAllowed: true,
|
||||||
delimiter: ',',
|
delimiter: ',',
|
||||||
paste: true,
|
paste: true,
|
||||||
|
@ -314,6 +315,16 @@ Pass an array of objects:
|
||||||
|
|
||||||
**Usage:** Whether a user can edit items. An item's value can be edited by pressing the backspace.
|
**Usage:** Whether a user can edit items. An item's value can be edited by pressing the backspace.
|
||||||
|
|
||||||
|
### allowHTML
|
||||||
|
|
||||||
|
**Type:** `Boolean` **Default:** `true`
|
||||||
|
|
||||||
|
**Input types affected:** `text`, `select-one`, `select-multiple`
|
||||||
|
|
||||||
|
**Usage:** Whether HTML should be rendered in all Choices elements. If `false`, all elements (placeholder, items, etc.) will be treated as plain text. If `true`, this can be used to perform XSS scripting attacks if you load choices from a remote source.
|
||||||
|
|
||||||
|
**Deprecation Warning:** This will default to `false` in a future release.
|
||||||
|
|
||||||
### duplicateItemsAllowed
|
### duplicateItemsAllowed
|
||||||
|
|
||||||
**Type:** `Boolean` **Default:** `true`
|
**Type:** `Boolean` **Default:** `true`
|
||||||
|
@ -637,6 +648,8 @@ classNames: {
|
||||||
If you want just extend a little original template then you may use `Choices.defaults.templates` to get access to
|
If you want just extend a little original template then you may use `Choices.defaults.templates` to get access to
|
||||||
original template function.
|
original template function.
|
||||||
|
|
||||||
|
Templates receive the full Choices config as the first argument to any template, which allows you to conditionally display things based on the options specified.
|
||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -656,7 +669,7 @@ or more complex:
|
||||||
const example = new Choices(element, {
|
const example = new Choices(element, {
|
||||||
callbackOnCreateTemplates: function(template) {
|
callbackOnCreateTemplates: function(template) {
|
||||||
return {
|
return {
|
||||||
item: (classNames, data) => {
|
item: ({ classNames }, data) => {
|
||||||
return template(`
|
return template(`
|
||||||
<div class="${classNames.item} ${
|
<div class="${classNames.item} ${
|
||||||
data.highlighted
|
data.highlighted
|
||||||
|
@ -671,7 +684,7 @@ const example = new Choices(element, {
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
},
|
},
|
||||||
choice: (classNames, data) => {
|
choice: ({ classNames }, data) => {
|
||||||
return template(`
|
return template(`
|
||||||
<div class="${classNames.item} ${classNames.itemChoice} ${
|
<div class="${classNames.item} ${classNames.itemChoice} ${
|
||||||
data.disabled ? classNames.itemDisabled : classNames.itemSelectable
|
data.disabled ? classNames.itemDisabled : classNames.itemSelectable
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
describe('Choices - select multiple', () => {
|
describe('Choices - select multiple', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('/select-multiple');
|
cy.visit('/select-multiple', {
|
||||||
|
onBeforeLoad(win) {
|
||||||
|
cy.stub(win.console, 'warn').as('consoleWarn');
|
||||||
|
},
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('scenarios', () => {
|
describe('scenarios', () => {
|
||||||
|
@ -865,5 +869,78 @@ describe('Choices - select multiple', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('allow html', () => {
|
||||||
|
describe('is undefined', () => {
|
||||||
|
it('logs a deprecation warning', () => {
|
||||||
|
cy.get('@consoleWarn').should(
|
||||||
|
'be.calledOnceWithExactly',
|
||||||
|
'Deprecation warning: allowHTML will default to false in a future release. To render HTML in Choices, you will need to set it to true. Setting allowHTML will suppress this message.',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not show as text when selected', () => {
|
||||||
|
cy.get('[data-test-hook=allowhtml-undefined]')
|
||||||
|
.find('.choices__list--multiple .choices__item')
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal('Choice 1');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not show html as text in dropdown', () => {
|
||||||
|
cy.get('[data-test-hook=allowhtml-undefined]')
|
||||||
|
.find('.choices__list--dropdown .choices__list')
|
||||||
|
.children()
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal('Choice 2');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('set to true', () => {
|
||||||
|
it('does not show as text when selected', () => {
|
||||||
|
cy.get('[data-test-hook=allowhtml-true]')
|
||||||
|
.find('.choices__list--multiple .choices__item')
|
||||||
|
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal('Choice 1');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not show html as text in dropdown', () => {
|
||||||
|
cy.get('[data-test-hook=allowhtml-true]')
|
||||||
|
.find('.choices__list--dropdown .choices__list')
|
||||||
|
.children()
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal('Choice 2');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('set to false', () => {
|
||||||
|
it('shows html as text when selected', () => {
|
||||||
|
cy.get('[data-test-hook=allowhtml-false]')
|
||||||
|
.find('.choices__list--multiple .choices__item')
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal('<b>Choice 1</b>');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('shows html as text', () => {
|
||||||
|
cy.get('[data-test-hook=allowhtml-false]')
|
||||||
|
.find('.choices__list--dropdown .choices__list')
|
||||||
|
.children()
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal('<b>Choice 2</b>');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
describe('Choices - select one', () => {
|
describe('Choices - select one', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('/select-one');
|
cy.visit('/select-one', {
|
||||||
|
onBeforeLoad(win) {
|
||||||
|
cy.stub(win.console, 'warn').as('consoleWarn');
|
||||||
|
},
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('scenarios', () => {
|
describe('scenarios', () => {
|
||||||
|
@ -51,9 +55,7 @@ describe('Choices - select one', () => {
|
||||||
describe('selecting choices', () => {
|
describe('selecting choices', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
// open dropdown
|
// open dropdown
|
||||||
cy.get('[data-test-hook=basic]')
|
cy.get('[data-test-hook=basic]').find('.choices').click();
|
||||||
.find('.choices')
|
|
||||||
.click();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const selectedChoiceText = 'Choice 1';
|
const selectedChoiceText = 'Choice 1';
|
||||||
|
@ -68,7 +70,7 @@ describe('Choices - select one', () => {
|
||||||
cy.get('[data-test-hook=basic]')
|
cy.get('[data-test-hook=basic]')
|
||||||
.find('.choices__list--single .choices__item')
|
.find('.choices__list--single .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($item => {
|
.should(($item) => {
|
||||||
expect($item).to.contain(selectedChoiceText);
|
expect($item).to.contain(selectedChoiceText);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -84,7 +86,7 @@ describe('Choices - select one', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.should($item => {
|
.should(($item) => {
|
||||||
expect($item).to.contain(selectedChoiceText);
|
expect($item).to.contain(selectedChoiceText);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -93,9 +95,7 @@ describe('Choices - select one', () => {
|
||||||
describe('searching choices', () => {
|
describe('searching choices', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
// open dropdown
|
// open dropdown
|
||||||
cy.get('[data-test-hook=basic]')
|
cy.get('[data-test-hook=basic]').find('.choices').click();
|
||||||
.find('.choices')
|
|
||||||
.click();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('on input', () => {
|
describe('on input', () => {
|
||||||
|
@ -109,7 +109,7 @@ describe('Choices - select one', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal('Choice 2');
|
expect($choice.text().trim()).to.equal('Choice 2');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -125,7 +125,7 @@ describe('Choices - select one', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal('Choice 3');
|
expect($choice.text().trim()).to.equal('Choice 3');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -140,7 +140,7 @@ describe('Choices - select one', () => {
|
||||||
cy.get('[data-test-hook=basic]')
|
cy.get('[data-test-hook=basic]')
|
||||||
.find('.choices__list--dropdown')
|
.find('.choices__list--dropdown')
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.should($dropdown => {
|
.should(($dropdown) => {
|
||||||
const dropdownText = $dropdown.text().trim();
|
const dropdownText = $dropdown.text().trim();
|
||||||
expect(dropdownText).to.equal('No results found');
|
expect(dropdownText).to.equal('No results found');
|
||||||
});
|
});
|
||||||
|
@ -206,7 +206,7 @@ describe('Choices - select one', () => {
|
||||||
cy.get('[data-test-hook=remove-button]')
|
cy.get('[data-test-hook=remove-button]')
|
||||||
.find('.choices__list--single .choices__item')
|
.find('.choices__list--single .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.then($choice => {
|
.then(($choice) => {
|
||||||
removedChoiceText = $choice.text().trim();
|
removedChoiceText = $choice.text().trim();
|
||||||
})
|
})
|
||||||
.click();
|
.click();
|
||||||
|
@ -229,7 +229,7 @@ describe('Choices - select one', () => {
|
||||||
it('updates the value of the original input', () => {
|
it('updates the value of the original input', () => {
|
||||||
cy.get('[data-test-hook=remove-button]')
|
cy.get('[data-test-hook=remove-button]')
|
||||||
.find('.choices__input[hidden]')
|
.find('.choices__input[hidden]')
|
||||||
.should($select => {
|
.should(($select) => {
|
||||||
const val = $select.val() || [];
|
const val = $select.val() || [];
|
||||||
|
|
||||||
expect(val).to.not.contain(removedChoiceText);
|
expect(val).to.not.contain(removedChoiceText);
|
||||||
|
@ -248,7 +248,7 @@ describe('Choices - select one', () => {
|
||||||
|
|
||||||
cy.get('[data-test-hook=disabled-choice]')
|
cy.get('[data-test-hook=disabled-choice]')
|
||||||
.find('.choices__list--dropdown .choices__item--disabled')
|
.find('.choices__list--dropdown .choices__item--disabled')
|
||||||
.then($choice => {
|
.then(($choice) => {
|
||||||
selectedChoiceText = $choice.text().trim();
|
selectedChoiceText = $choice.text().trim();
|
||||||
})
|
})
|
||||||
.click();
|
.click();
|
||||||
|
@ -258,7 +258,7 @@ describe('Choices - select one', () => {
|
||||||
cy.get('[data-test-hook=prepend-append]')
|
cy.get('[data-test-hook=prepend-append]')
|
||||||
.find('.choices__list--single .choices__item')
|
.find('.choices__list--single .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text()).to.not.contain(selectedChoiceText);
|
expect($choice.text()).to.not.contain(selectedChoiceText);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -305,9 +305,7 @@ describe('Choices - select one', () => {
|
||||||
|
|
||||||
describe('on click', () => {
|
describe('on click', () => {
|
||||||
it('does not open choice dropdown', () => {
|
it('does not open choice dropdown', () => {
|
||||||
cy.get('[data-test-hook=disabled-via-attr]')
|
cy.get('[data-test-hook=disabled-via-attr]').find('.choices').click();
|
||||||
.find('.choices')
|
|
||||||
.click();
|
|
||||||
|
|
||||||
cy.get('[data-test-hook=disabled-via-attr]')
|
cy.get('[data-test-hook=disabled-via-attr]')
|
||||||
.find('.choices__list--dropdown')
|
.find('.choices__list--dropdown')
|
||||||
|
@ -335,7 +333,7 @@ describe('Choices - select one', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.last()
|
.last()
|
||||||
.then($choice => {
|
.then(($choice) => {
|
||||||
selectedChoiceText = $choice.text().trim();
|
selectedChoiceText = $choice.text().trim();
|
||||||
})
|
})
|
||||||
.click();
|
.click();
|
||||||
|
@ -345,7 +343,7 @@ describe('Choices - select one', () => {
|
||||||
cy.get('[data-test-hook=prepend-append]')
|
cy.get('[data-test-hook=prepend-append]')
|
||||||
.find('.choices__list--single .choices__item')
|
.find('.choices__list--single .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.data('value')).to.equal(
|
expect($choice.data('value')).to.equal(
|
||||||
`before-${selectedChoiceText}-after`,
|
`before-${selectedChoiceText}-after`,
|
||||||
);
|
);
|
||||||
|
@ -356,7 +354,7 @@ describe('Choices - select one', () => {
|
||||||
cy.get('[data-test-hook=prepend-append]')
|
cy.get('[data-test-hook=prepend-append]')
|
||||||
.find('.choices__list--single .choices__item')
|
.find('.choices__list--single .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text()).to.not.contain(
|
expect($choice.text()).to.not.contain(
|
||||||
`before-${selectedChoiceText}-after`,
|
`before-${selectedChoiceText}-after`,
|
||||||
);
|
);
|
||||||
|
@ -389,9 +387,7 @@ describe('Choices - select one', () => {
|
||||||
const selectedChoiceText = 'Choice 3';
|
const selectedChoiceText = 'Choice 3';
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.get('[data-test-hook=search-disabled]')
|
cy.get('[data-test-hook=search-disabled]').find('.choices').click();
|
||||||
.find('.choices')
|
|
||||||
.click();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not display a search input', () => {
|
it('does not display a search input', () => {
|
||||||
|
@ -410,7 +406,7 @@ describe('Choices - select one', () => {
|
||||||
cy.get('[data-test-hook=search-disabled]')
|
cy.get('[data-test-hook=search-disabled]')
|
||||||
.find('.choices__list--single .choices__item')
|
.find('.choices__list--single .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($item => {
|
.should(($item) => {
|
||||||
expect($item).to.contain(selectedChoiceText);
|
expect($item).to.contain(selectedChoiceText);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -442,7 +438,7 @@ describe('Choices - select one', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.not.contain(searchTerm);
|
expect($choice.text().trim()).to.not.contain(searchTerm);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -460,7 +456,7 @@ describe('Choices - select one', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.contain(searchTerm);
|
expect($choice.text().trim()).to.contain(searchTerm);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -476,7 +472,7 @@ describe('Choices - select one', () => {
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.should('have.class', 'choices__placeholder')
|
.should('have.class', 'choices__placeholder')
|
||||||
.and($placeholder => {
|
.and(($placeholder) => {
|
||||||
expect($placeholder).to.contain('I am a placeholder');
|
expect($placeholder).to.contain('I am a placeholder');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -524,7 +520,7 @@ describe('Choices - select one', () => {
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.should('have.class', 'choices__placeholder')
|
.should('have.class', 'choices__placeholder')
|
||||||
.and($placeholder => {
|
.and(($placeholder) => {
|
||||||
expect($placeholder).to.contain('I am a placeholder');
|
expect($placeholder).to.contain('I am a placeholder');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -577,7 +573,7 @@ describe('Choices - select one', () => {
|
||||||
.should('have.length', 1)
|
.should('have.length', 1)
|
||||||
.first()
|
.first()
|
||||||
.should('have.class', 'choices__placeholder')
|
.should('have.class', 'choices__placeholder')
|
||||||
.and($placeholder => {
|
.and(($placeholder) => {
|
||||||
expect($placeholder).to.contain('Loading...');
|
expect($placeholder).to.contain('Loading...');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -620,19 +616,17 @@ describe('Choices - select one', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.get('[data-test-hook=scrolling-dropdown]')
|
cy.get('[data-test-hook=scrolling-dropdown]')
|
||||||
.find('.choices__list--dropdown .choices__list .choices__item')
|
.find('.choices__list--dropdown .choices__list .choices__item')
|
||||||
.then($choices => {
|
.then(($choices) => {
|
||||||
choicesCount = $choices.length;
|
choicesCount = $choices.length;
|
||||||
});
|
});
|
||||||
|
|
||||||
cy.get('[data-test-hook=scrolling-dropdown]')
|
cy.get('[data-test-hook=scrolling-dropdown]').find('.choices').click();
|
||||||
.find('.choices')
|
|
||||||
.click();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('highlights first choice on dropdown open', () => {
|
it('highlights first choice on dropdown open', () => {
|
||||||
cy.get('[data-test-hook=scrolling-dropdown]')
|
cy.get('[data-test-hook=scrolling-dropdown]')
|
||||||
.find('.choices__list--dropdown .choices__list .is-highlighted')
|
.find('.choices__list--dropdown .choices__list .is-highlighted')
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal('Choice 1');
|
expect($choice.text().trim()).to.equal('Choice 1');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -641,7 +635,7 @@ describe('Choices - select one', () => {
|
||||||
for (let index = 0; index < choicesCount; index++) {
|
for (let index = 0; index < choicesCount; index++) {
|
||||||
cy.get('[data-test-hook=scrolling-dropdown]')
|
cy.get('[data-test-hook=scrolling-dropdown]')
|
||||||
.find('.choices__list--dropdown .choices__list .is-highlighted')
|
.find('.choices__list--dropdown .choices__list .is-highlighted')
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal(`Choice ${index + 1}`);
|
expect($choice.text().trim()).to.equal(`Choice ${index + 1}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -665,7 +659,7 @@ describe('Choices - select one', () => {
|
||||||
|
|
||||||
cy.get('[data-test-hook=scrolling-dropdown]')
|
cy.get('[data-test-hook=scrolling-dropdown]')
|
||||||
.find('.choices__list--dropdown .choices__list .is-highlighted')
|
.find('.choices__list--dropdown .choices__list .is-highlighted')
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal(`Choice ${index}`);
|
expect($choice.text().trim()).to.equal(`Choice ${index}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -684,7 +678,7 @@ describe('Choices - select one', () => {
|
||||||
cy.get('[data-test-hook=groups]')
|
cy.get('[data-test-hook=groups]')
|
||||||
.find('.choices__list--dropdown .choices__list .choices__group')
|
.find('.choices__list--dropdown .choices__list .choices__group')
|
||||||
.first()
|
.first()
|
||||||
.then($group => {
|
.then(($group) => {
|
||||||
groupValue = $group.text().trim();
|
groupValue = $group.text().trim();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -705,7 +699,7 @@ describe('Choices - select one', () => {
|
||||||
cy.get('[data-test-hook=groups]')
|
cy.get('[data-test-hook=groups]')
|
||||||
.find('.choices__list--dropdown .choices__list .choices__group')
|
.find('.choices__list--dropdown .choices__list .choices__group')
|
||||||
.first()
|
.first()
|
||||||
.should($group => {
|
.should(($group) => {
|
||||||
expect($group.text().trim()).to.not.equal(groupValue);
|
expect($group.text().trim()).to.not.equal(groupValue);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -736,7 +730,7 @@ describe('Choices - select one', () => {
|
||||||
cy.get('[data-test-hook=groups]')
|
cy.get('[data-test-hook=groups]')
|
||||||
.find('.choices__list--dropdown .choices__list .choices__group')
|
.find('.choices__list--dropdown .choices__list .choices__group')
|
||||||
.first()
|
.first()
|
||||||
.should($group => {
|
.should(($group) => {
|
||||||
expect($group.text().trim()).to.equal(groupValue);
|
expect($group.text().trim()).to.equal(groupValue);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -806,9 +800,7 @@ describe('Choices - select one', () => {
|
||||||
|
|
||||||
describe('custom properties', () => {
|
describe('custom properties', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.get('[data-test-hook=custom-properties]')
|
cy.get('[data-test-hook=custom-properties]').find('.choices').click();
|
||||||
.find('.choices')
|
|
||||||
.click();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('on input', () => {
|
describe('on input', () => {
|
||||||
|
@ -837,7 +829,7 @@ describe('Choices - select one', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal(city);
|
expect($choice.text().trim()).to.equal(city);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -851,9 +843,7 @@ describe('Choices - select one', () => {
|
||||||
|
|
||||||
describe('non-string values', () => {
|
describe('non-string values', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.get('[data-test-hook=non-string-values]')
|
cy.get('[data-test-hook=non-string-values]').find('.choices').click();
|
||||||
.find('.choices')
|
|
||||||
.click();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('displays expected amount of choices in dropdown', () => {
|
it('displays expected amount of choices in dropdown', () => {
|
||||||
|
@ -869,7 +859,7 @@ describe('Choices - select one', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.then($choice => {
|
.then(($choice) => {
|
||||||
$selectedChoice = $choice;
|
$selectedChoice = $choice;
|
||||||
})
|
})
|
||||||
.click();
|
.click();
|
||||||
|
@ -877,7 +867,7 @@ describe('Choices - select one', () => {
|
||||||
cy.get('[data-test-hook=non-string-values]')
|
cy.get('[data-test-hook=non-string-values]')
|
||||||
.find('.choices__list--single .choices__item')
|
.find('.choices__list--single .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($item => {
|
.should(($item) => {
|
||||||
expect($item.text().trim()).to.equal($selectedChoice.text().trim());
|
expect($item.text().trim()).to.equal($selectedChoice.text().trim());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -887,7 +877,7 @@ describe('Choices - select one', () => {
|
||||||
describe('selecting choice', () => {
|
describe('selecting choice', () => {
|
||||||
describe('on enter key', () => {
|
describe('on enter key', () => {
|
||||||
it('does not submit form', () => {
|
it('does not submit form', () => {
|
||||||
cy.get('[data-test-hook=within-form] form').then($form => {
|
cy.get('[data-test-hook=within-form] form').then(($form) => {
|
||||||
$form.submit(() => {
|
$form.submit(() => {
|
||||||
// this will fail the test if the form submits
|
// this will fail the test if the form submits
|
||||||
throw new Error('Form submitted');
|
throw new Error('Form submitted');
|
||||||
|
@ -900,14 +890,12 @@ describe('Choices - select one', () => {
|
||||||
.find('.choices__input--cloned')
|
.find('.choices__input--cloned')
|
||||||
.type('{enter}');
|
.type('{enter}');
|
||||||
|
|
||||||
cy.get('[data-test-hook=within-form]')
|
cy.get('[data-test-hook=within-form]').find('.choices').click();
|
||||||
.find('.choices')
|
|
||||||
.click();
|
|
||||||
|
|
||||||
cy.get('[data-test-hook=within-form]')
|
cy.get('[data-test-hook=within-form]')
|
||||||
.find('.choices__list--single .choices__item')
|
.find('.choices__list--single .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($item => {
|
.should(($item) => {
|
||||||
expect($item).to.contain('Choice 1');
|
expect($item).to.contain('Choice 1');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -922,7 +910,7 @@ describe('Choices - select one', () => {
|
||||||
cy.get('[data-test-hook=set-choice-by-value]')
|
cy.get('[data-test-hook=set-choice-by-value]')
|
||||||
.find('.choices__list--single .choices__item')
|
.find('.choices__list--single .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal(
|
expect($choice.text().trim()).to.equal(
|
||||||
dynamicallySelectedChoiceValue,
|
dynamicallySelectedChoiceValue,
|
||||||
);
|
);
|
||||||
|
@ -932,7 +920,7 @@ describe('Choices - select one', () => {
|
||||||
it('does not remove choice from dropdown list', () => {
|
it('does not remove choice from dropdown list', () => {
|
||||||
cy.get('[data-test-hook=set-choice-by-value]')
|
cy.get('[data-test-hook=set-choice-by-value]')
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.then($choicesList => {
|
.then(($choicesList) => {
|
||||||
expect($choicesList).to.contain(dynamicallySelectedChoiceValue);
|
expect($choicesList).to.contain(dynamicallySelectedChoiceValue);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -940,7 +928,7 @@ describe('Choices - select one', () => {
|
||||||
it('updates the value of the original input', () => {
|
it('updates the value of the original input', () => {
|
||||||
cy.get('[data-test-hook=set-choice-by-value]')
|
cy.get('[data-test-hook=set-choice-by-value]')
|
||||||
.find('.choices__input[hidden]')
|
.find('.choices__input[hidden]')
|
||||||
.should($select => {
|
.should(($select) => {
|
||||||
const val = $select.val() || [];
|
const val = $select.val() || [];
|
||||||
expect(val).to.contain(dynamicallySelectedChoiceValue);
|
expect(val).to.contain(dynamicallySelectedChoiceValue);
|
||||||
});
|
});
|
||||||
|
@ -949,9 +937,7 @@ describe('Choices - select one', () => {
|
||||||
|
|
||||||
describe('searching by label only', () => {
|
describe('searching by label only', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.get('[data-test-hook=search-by-label]')
|
cy.get('[data-test-hook=search-by-label]').find('.choices').click();
|
||||||
.find('.choices')
|
|
||||||
.click();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('gets zero results when searching by value', () => {
|
it('gets zero results when searching by value', () => {
|
||||||
|
@ -963,7 +949,7 @@ describe('Choices - select one', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal('No results found');
|
expect($choice.text().trim()).to.equal('No results found');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -977,7 +963,7 @@ describe('Choices - select one', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal('label1');
|
expect($choice.text().trim()).to.equal('label1');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -998,7 +984,7 @@ describe('Choices - select one', () => {
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.should('have.class', 'choices__item--disabled')
|
.should('have.class', 'choices__item--disabled')
|
||||||
.then($choice => {
|
.then(($choice) => {
|
||||||
disabledValue = $choice.val();
|
disabledValue = $choice.val();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1006,19 +992,64 @@ describe('Choices - select one', () => {
|
||||||
it('selects the first enabled choice', () => {
|
it('selects the first enabled choice', () => {
|
||||||
cy.get('[data-test-hook=disabled-first-choice-via-options]')
|
cy.get('[data-test-hook=disabled-first-choice-via-options]')
|
||||||
.find('.choices__input[hidden]')
|
.find('.choices__input[hidden]')
|
||||||
.then($option => {
|
.then(($option) => {
|
||||||
expect($option.text().trim()).to.not.equal(disabledValue);
|
expect($option.text().trim()).to.not.equal(disabledValue);
|
||||||
});
|
});
|
||||||
|
|
||||||
cy.get('[data-test-hook=disabled-first-choice-via-options]')
|
cy.get('[data-test-hook=disabled-first-choice-via-options]')
|
||||||
.find('.choices__item.choices__item--selectable')
|
.find('.choices__item.choices__item--selectable')
|
||||||
.first()
|
.first()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.not.equal(disabledValue);
|
expect($choice.text().trim()).to.not.equal(disabledValue);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('allow html', () => {
|
||||||
|
describe('is undefined', () => {
|
||||||
|
it('logs a deprecation warning', () => {
|
||||||
|
cy.get('@consoleWarn').should(
|
||||||
|
'be.calledOnceWithExactly',
|
||||||
|
'Deprecation warning: allowHTML will default to false in a future release. To render HTML in Choices, you will need to set it to true. Setting allowHTML will suppress this message.',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not show html as text', () => {
|
||||||
|
cy.get('[data-test-hook=allowhtml-undefined]')
|
||||||
|
.find('.choices__list--dropdown .choices__list')
|
||||||
|
.children()
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal('Choice 1');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('set to true', () => {
|
||||||
|
it('does not show html as text', () => {
|
||||||
|
cy.get('[data-test-hook=allowhtml-true]')
|
||||||
|
.find('.choices__list--dropdown .choices__list')
|
||||||
|
.children()
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal('Choice 1');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('set to false', () => {
|
||||||
|
it('shows html as text', () => {
|
||||||
|
cy.get('[data-test-hook=allowhtml-false]')
|
||||||
|
.find('.choices__list--dropdown .choices__list')
|
||||||
|
.children()
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal('<b>Choice 1</b>');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('re-initialising a choices instance', () => {
|
describe('re-initialising a choices instance', () => {
|
||||||
it('preserves the choices list', () => {
|
it('preserves the choices list', () => {
|
||||||
cy.get('[data-test-hook=new-destroy-init]')
|
cy.get('[data-test-hook=new-destroy-init]')
|
||||||
|
@ -1029,9 +1060,7 @@ describe('Choices - select one', () => {
|
||||||
cy.get('[data-test-hook=new-destroy-init]')
|
cy.get('[data-test-hook=new-destroy-init]')
|
||||||
.find('button.destroy')
|
.find('button.destroy')
|
||||||
.click();
|
.click();
|
||||||
cy.get('[data-test-hook=new-destroy-init]')
|
cy.get('[data-test-hook=new-destroy-init]').find('button.init').click();
|
||||||
.find('button.init')
|
|
||||||
.click();
|
|
||||||
|
|
||||||
cy.get('[data-test-hook=new-destroy-init]')
|
cy.get('[data-test-hook=new-destroy-init]')
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
describe('Choices - text element', () => {
|
describe('Choices - text element', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('/text');
|
cy.visit('/text', {
|
||||||
|
onBeforeLoad(win) {
|
||||||
|
cy.stub(win.console, 'warn').as('consoleWarn');
|
||||||
|
},
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('scenarios', () => {
|
describe('scenarios', () => {
|
||||||
|
@ -17,7 +21,7 @@ describe('Choices - text element', () => {
|
||||||
cy.get('[data-test-hook=basic]')
|
cy.get('[data-test-hook=basic]')
|
||||||
.find('.choices__list--multiple .choices__item')
|
.find('.choices__list--multiple .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($el => {
|
.should(($el) => {
|
||||||
expect($el).to.contain(textInput);
|
expect($el).to.contain(textInput);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -42,7 +46,7 @@ describe('Choices - text element', () => {
|
||||||
cy.get('[data-test-hook=basic]')
|
cy.get('[data-test-hook=basic]')
|
||||||
.find('.choices__list--dropdown')
|
.find('.choices__list--dropdown')
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.should($dropdown => {
|
.should(($dropdown) => {
|
||||||
const dropdownText = $dropdown.text().trim();
|
const dropdownText = $dropdown.text().trim();
|
||||||
expect(dropdownText).to.equal(
|
expect(dropdownText).to.equal(
|
||||||
`Press Enter to add "${textInput}"`,
|
`Press Enter to add "${textInput}"`,
|
||||||
|
@ -74,7 +78,7 @@ describe('Choices - text element', () => {
|
||||||
cy.get('[data-test-hook=edit-items]')
|
cy.get('[data-test-hook=edit-items]')
|
||||||
.find('.choices__list--multiple .choices__item')
|
.find('.choices__list--multiple .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.data('value')).to.equal(`${textInput}-edited`);
|
expect($choice.data('value')).to.equal(`${textInput}-edited`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -90,7 +94,7 @@ describe('Choices - text element', () => {
|
||||||
it('highlights all items', () => {
|
it('highlights all items', () => {
|
||||||
cy.get('[data-test-hook=edit-items]')
|
cy.get('[data-test-hook=edit-items]')
|
||||||
.find('.choices__list--multiple .choices__item')
|
.find('.choices__list--multiple .choices__item')
|
||||||
.each($choice => {
|
.each(($choice) => {
|
||||||
expect($choice.hasClass('is-highlighted')).to.equal(true);
|
expect($choice.hasClass('is-highlighted')).to.equal(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -124,7 +128,7 @@ describe('Choices - text element', () => {
|
||||||
cy.get('[data-test-hook=remove-button]')
|
cy.get('[data-test-hook=remove-button]')
|
||||||
.find('.choices__list--multiple')
|
.find('.choices__list--multiple')
|
||||||
.children()
|
.children()
|
||||||
.should($items => {
|
.should(($items) => {
|
||||||
expect($items.length).to.equal(1);
|
expect($items.length).to.equal(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -137,7 +141,7 @@ describe('Choices - text element', () => {
|
||||||
|
|
||||||
cy.get('[data-test-hook=remove-button]')
|
cy.get('[data-test-hook=remove-button]')
|
||||||
.find('.choices__list--multiple .choices__item')
|
.find('.choices__list--multiple .choices__item')
|
||||||
.should($items => {
|
.should(($items) => {
|
||||||
expect($items.length).to.equal(0);
|
expect($items.length).to.equal(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -152,7 +156,7 @@ describe('Choices - text element', () => {
|
||||||
|
|
||||||
cy.get('[data-test-hook=remove-button]')
|
cy.get('[data-test-hook=remove-button]')
|
||||||
.find('.choices__input[hidden]')
|
.find('.choices__input[hidden]')
|
||||||
.then($input => {
|
.then(($input) => {
|
||||||
expect($input.val()).to.not.contain(textInput);
|
expect($input.val()).to.not.contain(textInput);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -175,7 +179,7 @@ describe('Choices - text element', () => {
|
||||||
.find('.choices__list--multiple')
|
.find('.choices__list--multiple')
|
||||||
.first()
|
.first()
|
||||||
.children()
|
.children()
|
||||||
.should($items => {
|
.should(($items) => {
|
||||||
expect($items.length).to.equal(1);
|
expect($items.length).to.equal(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -185,7 +189,7 @@ describe('Choices - text element', () => {
|
||||||
cy.get('[data-test-hook=unique-values]')
|
cy.get('[data-test-hook=unique-values]')
|
||||||
.find('.choices__list--dropdown')
|
.find('.choices__list--dropdown')
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.should($dropdown => {
|
.should(($dropdown) => {
|
||||||
const dropdownText = $dropdown.text().trim();
|
const dropdownText = $dropdown.text().trim();
|
||||||
expect(dropdownText).to.equal(
|
expect(dropdownText).to.equal(
|
||||||
'Only unique values can be added',
|
'Only unique values can be added',
|
||||||
|
@ -212,7 +216,7 @@ describe('Choices - text element', () => {
|
||||||
.find('.choices__list--multiple')
|
.find('.choices__list--multiple')
|
||||||
.first()
|
.first()
|
||||||
.children()
|
.children()
|
||||||
.should($items => {
|
.should(($items) => {
|
||||||
expect($items.length).to.equal(inputLimit);
|
expect($items.length).to.equal(inputLimit);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -222,7 +226,7 @@ describe('Choices - text element', () => {
|
||||||
cy.get('[data-test-hook=input-limit]')
|
cy.get('[data-test-hook=input-limit]')
|
||||||
.find('.choices__list--dropdown')
|
.find('.choices__list--dropdown')
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.should($dropdown => {
|
.should(($dropdown) => {
|
||||||
const dropdownText = $dropdown.text().trim();
|
const dropdownText = $dropdown.text().trim();
|
||||||
expect(dropdownText).to.equal(
|
expect(dropdownText).to.equal(
|
||||||
`Only ${inputLimit} values can be added`,
|
`Only ${inputLimit} values can be added`,
|
||||||
|
@ -245,7 +249,7 @@ describe('Choices - text element', () => {
|
||||||
cy.get('[data-test-hook=add-item-filter]')
|
cy.get('[data-test-hook=add-item-filter]')
|
||||||
.find('.choices__list--multiple .choices__item')
|
.find('.choices__list--multiple .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal(input);
|
expect($choice.text().trim()).to.equal(input);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -261,7 +265,7 @@ describe('Choices - text element', () => {
|
||||||
cy.get('[data-test-hook=add-item-filter]')
|
cy.get('[data-test-hook=add-item-filter]')
|
||||||
.find('.choices__list--dropdown')
|
.find('.choices__list--dropdown')
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.should($dropdown => {
|
.should(($dropdown) => {
|
||||||
const dropdownText = $dropdown.text().trim();
|
const dropdownText = $dropdown.text().trim();
|
||||||
expect(dropdownText).to.equal(
|
expect(dropdownText).to.equal(
|
||||||
'Only values matching specific conditions can be added',
|
'Only values matching specific conditions can be added',
|
||||||
|
@ -283,7 +287,7 @@ describe('Choices - text element', () => {
|
||||||
cy.get('[data-test-hook=prepend-append]')
|
cy.get('[data-test-hook=prepend-append]')
|
||||||
.find('.choices__list--multiple .choices__item')
|
.find('.choices__list--multiple .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.data('value')).to.equal(`before-${textInput}-after`);
|
expect($choice.data('value')).to.equal(`before-${textInput}-after`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -292,7 +296,7 @@ describe('Choices - text element', () => {
|
||||||
cy.get('[data-test-hook=prepend-append]')
|
cy.get('[data-test-hook=prepend-append]')
|
||||||
.find('.choices__list--multiple .choices__item')
|
.find('.choices__list--multiple .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text()).to.not.contain(`before-${textInput}-after`);
|
expect($choice.text()).to.not.contain(`before-${textInput}-after`);
|
||||||
expect($choice.text()).to.contain(textInput);
|
expect($choice.text()).to.contain(textInput);
|
||||||
});
|
});
|
||||||
|
@ -319,21 +323,21 @@ describe('Choices - text element', () => {
|
||||||
it('pre-populates choices', () => {
|
it('pre-populates choices', () => {
|
||||||
cy.get('[data-test-hook=prepopulated]')
|
cy.get('[data-test-hook=prepopulated]')
|
||||||
.find('.choices__list--multiple .choices__item')
|
.find('.choices__list--multiple .choices__item')
|
||||||
.should($choices => {
|
.should(($choices) => {
|
||||||
expect($choices.length).to.equal(2);
|
expect($choices.length).to.equal(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
cy.get('[data-test-hook=prepopulated]')
|
cy.get('[data-test-hook=prepopulated]')
|
||||||
.find('.choices__list--multiple .choices__item')
|
.find('.choices__list--multiple .choices__item')
|
||||||
.first()
|
.first()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal('Josh Johnson');
|
expect($choice.text().trim()).to.equal('Josh Johnson');
|
||||||
});
|
});
|
||||||
|
|
||||||
cy.get('[data-test-hook=prepopulated]')
|
cy.get('[data-test-hook=prepopulated]')
|
||||||
.find('.choices__list--multiple .choices__item')
|
.find('.choices__list--multiple .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal('Joe Bloggs');
|
expect($choice.text().trim()).to.equal('Joe Bloggs');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -355,11 +359,53 @@ describe('Choices - text element', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('allow html', () => {
|
||||||
|
describe('is undefined', () => {
|
||||||
|
it('logs a deprecation warning', () => {
|
||||||
|
cy.get('@consoleWarn').should(
|
||||||
|
'be.calledOnceWithExactly',
|
||||||
|
'Deprecation warning: allowHTML will default to false in a future release. To render HTML in Choices, you will need to set it to true. Setting allowHTML will suppress this message.',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not show html as text', () => {
|
||||||
|
cy.get('[data-test-hook=allowhtml-undefined]')
|
||||||
|
.find('.choices__list--multiple .choices__item')
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal('Mason Rogers');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('set to true', () => {
|
||||||
|
it('does not show html as text', () => {
|
||||||
|
cy.get('[data-test-hook=allowhtml-true]')
|
||||||
|
.find('.choices__list--multiple .choices__item')
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal('Mason Rogers');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('set to false', () => {
|
||||||
|
it('shows html as text', () => {
|
||||||
|
cy.get('[data-test-hook=allowhtml-false]')
|
||||||
|
.find('.choices__list--multiple .choices__item')
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal('<b>Mason Rogers</b>');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('within form', () => {
|
describe('within form', () => {
|
||||||
describe('inputting item', () => {
|
describe('inputting item', () => {
|
||||||
describe('on enter key', () => {
|
describe('on enter key', () => {
|
||||||
it('does not submit form', () => {
|
it('does not submit form', () => {
|
||||||
cy.get('[data-test-hook=within-form] form').then($form => {
|
cy.get('[data-test-hook=within-form] form').then(($form) => {
|
||||||
$form.submit(() => {
|
$form.submit(() => {
|
||||||
// this will fail the test if the form submits
|
// this will fail the test if the form submits
|
||||||
throw new Error('Form submitted');
|
throw new Error('Form submitted');
|
||||||
|
@ -374,7 +420,7 @@ describe('Choices - text element', () => {
|
||||||
cy.get('[data-test-hook=within-form]')
|
cy.get('[data-test-hook=within-form]')
|
||||||
.find('.choices__list--multiple .choices__item')
|
.find('.choices__list--multiple .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($el => {
|
.should(($el) => {
|
||||||
expect($el).to.contain(textInput);
|
expect($el).to.contain(textInput);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*! choices.js v9.0.1 | © 2021 Josh Johnson | https://github.com/jshjohnson/Choices#readme */
|
/*! choices.js v9.1.0 | © 2021 Josh Johnson | https://github.com/jshjohnson/Choices#readme */
|
||||||
(function webpackUniversalModuleDefinition(root, factory) {
|
(function webpackUniversalModuleDefinition(root, factory) {
|
||||||
if(typeof exports === 'object' && typeof module === 'object')
|
if(typeof exports === 'object' && typeof module === 'object')
|
||||||
module.exports = factory();
|
module.exports = factory();
|
||||||
|
@ -291,6 +291,10 @@ function () {
|
||||||
userConfig = {};
|
userConfig = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (userConfig.allowHTML === undefined) {
|
||||||
|
console.warn('Deprecation warning: allowHTML will default to false in a future release. To render HTML in Choices, you will need to set it to true. Setting allowHTML will suppress this message.');
|
||||||
|
}
|
||||||
|
|
||||||
this.config = deepmerge_1.default.all([defaults_1.DEFAULT_CONFIG, Choices.defaults.options, userConfig], // When merging array configs, replace with a copy of the userConfig array,
|
this.config = deepmerge_1.default.all([defaults_1.DEFAULT_CONFIG, Choices.defaults.options, userConfig], // When merging array configs, replace with a copy of the userConfig array,
|
||||||
// instead of concatenating with the default array
|
// instead of concatenating with the default array
|
||||||
{
|
{
|
||||||
|
@ -2209,8 +2213,7 @@ function () {
|
||||||
args[_i - 1] = arguments[_i];
|
args[_i - 1] = arguments[_i];
|
||||||
}
|
}
|
||||||
|
|
||||||
var classNames = this.config.classNames;
|
return (_a = this._templates[template]).call.apply(_a, __spreadArray([this, this.config], args, false));
|
||||||
return (_a = this._templates[template]).call.apply(_a, __spreadArray([this, classNames], args, false));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Choices.prototype._createTemplates = function () {
|
Choices.prototype._createTemplates = function () {
|
||||||
|
@ -3483,6 +3486,7 @@ exports.DEFAULT_CONFIG = {
|
||||||
removeItems: true,
|
removeItems: true,
|
||||||
removeItemButton: false,
|
removeItemButton: false,
|
||||||
editItems: false,
|
editItems: false,
|
||||||
|
allowHTML: true,
|
||||||
duplicateItemsAllowed: true,
|
duplicateItemsAllowed: true,
|
||||||
delimiter: ',',
|
delimiter: ',',
|
||||||
paste: true,
|
paste: true,
|
||||||
|
@ -3644,7 +3648,7 @@ var sanitise = function (value) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return value.replace(/&/g, '&').replace(/>/g, '&rt;').replace(/</g, '<').replace(/"/g, '"');
|
return value.replace(/&/g, '&').replace(/>/g, '>').replace(/</g, '<').replace(/"/g, '"');
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.sanitise = sanitise;
|
exports.sanitise = sanitise;
|
||||||
|
@ -4376,7 +4380,7 @@ Object.defineProperty(exports, "__esModule", ({
|
||||||
}));
|
}));
|
||||||
var templates = {
|
var templates = {
|
||||||
containerOuter: function (_a, dir, isSelectElement, isSelectOneElement, searchEnabled, passedElementType) {
|
containerOuter: function (_a, dir, isSelectElement, isSelectOneElement, searchEnabled, passedElementType) {
|
||||||
var containerOuter = _a.containerOuter;
|
var containerOuter = _a.classNames.containerOuter;
|
||||||
var div = Object.assign(document.createElement('div'), {
|
var div = Object.assign(document.createElement('div'), {
|
||||||
className: containerOuter
|
className: containerOuter
|
||||||
});
|
});
|
||||||
|
@ -4403,32 +4407,39 @@ var templates = {
|
||||||
return div;
|
return div;
|
||||||
},
|
},
|
||||||
containerInner: function (_a) {
|
containerInner: function (_a) {
|
||||||
var containerInner = _a.containerInner;
|
var containerInner = _a.classNames.containerInner;
|
||||||
return Object.assign(document.createElement('div'), {
|
return Object.assign(document.createElement('div'), {
|
||||||
className: containerInner
|
className: containerInner
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
itemList: function (_a, isSelectOneElement) {
|
itemList: function (_a, isSelectOneElement) {
|
||||||
var list = _a.list,
|
var _b = _a.classNames,
|
||||||
listSingle = _a.listSingle,
|
list = _b.list,
|
||||||
listItems = _a.listItems;
|
listSingle = _b.listSingle,
|
||||||
|
listItems = _b.listItems;
|
||||||
return Object.assign(document.createElement('div'), {
|
return Object.assign(document.createElement('div'), {
|
||||||
className: "".concat(list, " ").concat(isSelectOneElement ? listSingle : listItems)
|
className: "".concat(list, " ").concat(isSelectOneElement ? listSingle : listItems)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
placeholder: function (_a, value) {
|
placeholder: function (_a, value) {
|
||||||
var placeholder = _a.placeholder;
|
var _b;
|
||||||
return Object.assign(document.createElement('div'), {
|
|
||||||
className: placeholder,
|
var allowHTML = _a.allowHTML,
|
||||||
innerHTML: value
|
placeholder = _a.classNames.placeholder;
|
||||||
});
|
return Object.assign(document.createElement('div'), (_b = {
|
||||||
|
className: placeholder
|
||||||
|
}, _b[allowHTML ? 'innerHTML' : 'innerText'] = value, _b));
|
||||||
},
|
},
|
||||||
item: function (_a, _b, removeItemButton) {
|
item: function (_a, _b, removeItemButton) {
|
||||||
var item = _a.item,
|
var _c, _d;
|
||||||
button = _a.button,
|
|
||||||
highlightedState = _a.highlightedState,
|
var allowHTML = _a.allowHTML,
|
||||||
itemSelectable = _a.itemSelectable,
|
_e = _a.classNames,
|
||||||
placeholder = _a.placeholder;
|
item = _e.item,
|
||||||
|
button = _e.button,
|
||||||
|
highlightedState = _e.highlightedState,
|
||||||
|
itemSelectable = _e.itemSelectable,
|
||||||
|
placeholder = _e.placeholder;
|
||||||
var id = _b.id,
|
var id = _b.id,
|
||||||
value = _b.value,
|
value = _b.value,
|
||||||
label = _b.label,
|
label = _b.label,
|
||||||
|
@ -4437,10 +4448,9 @@ var templates = {
|
||||||
disabled = _b.disabled,
|
disabled = _b.disabled,
|
||||||
highlighted = _b.highlighted,
|
highlighted = _b.highlighted,
|
||||||
isPlaceholder = _b.placeholder;
|
isPlaceholder = _b.placeholder;
|
||||||
var div = Object.assign(document.createElement('div'), {
|
var div = Object.assign(document.createElement('div'), (_c = {
|
||||||
className: item,
|
className: item
|
||||||
innerHTML: label
|
}, _c[allowHTML ? 'innerHTML' : 'innerText'] = label, _c));
|
||||||
});
|
|
||||||
Object.assign(div.dataset, {
|
Object.assign(div.dataset, {
|
||||||
item: '',
|
item: '',
|
||||||
id: id,
|
id: id,
|
||||||
|
@ -4471,11 +4481,10 @@ var templates = {
|
||||||
/** @todo This MUST be localizable, not hardcoded! */
|
/** @todo This MUST be localizable, not hardcoded! */
|
||||||
|
|
||||||
var REMOVE_ITEM_TEXT = 'Remove item';
|
var REMOVE_ITEM_TEXT = 'Remove item';
|
||||||
var removeButton = Object.assign(document.createElement('button'), {
|
var removeButton = Object.assign(document.createElement('button'), (_d = {
|
||||||
type: 'button',
|
type: 'button',
|
||||||
className: button,
|
className: button
|
||||||
innerHTML: REMOVE_ITEM_TEXT
|
}, _d[allowHTML ? 'innerHTML' : 'innerText'] = REMOVE_ITEM_TEXT, _d));
|
||||||
});
|
|
||||||
removeButton.setAttribute('aria-label', "".concat(REMOVE_ITEM_TEXT, ": '").concat(value, "'"));
|
removeButton.setAttribute('aria-label', "".concat(REMOVE_ITEM_TEXT, ": '").concat(value, "'"));
|
||||||
removeButton.dataset.button = '';
|
removeButton.dataset.button = '';
|
||||||
div.appendChild(removeButton);
|
div.appendChild(removeButton);
|
||||||
|
@ -4484,7 +4493,7 @@ var templates = {
|
||||||
return div;
|
return div;
|
||||||
},
|
},
|
||||||
choiceList: function (_a, isSelectOneElement) {
|
choiceList: function (_a, isSelectOneElement) {
|
||||||
var list = _a.list;
|
var list = _a.classNames.list;
|
||||||
var div = Object.assign(document.createElement('div'), {
|
var div = Object.assign(document.createElement('div'), {
|
||||||
className: list
|
className: list
|
||||||
});
|
});
|
||||||
|
@ -4497,9 +4506,13 @@ var templates = {
|
||||||
return div;
|
return div;
|
||||||
},
|
},
|
||||||
choiceGroup: function (_a, _b) {
|
choiceGroup: function (_a, _b) {
|
||||||
var group = _a.group,
|
var _c;
|
||||||
groupHeading = _a.groupHeading,
|
|
||||||
itemDisabled = _a.itemDisabled;
|
var allowHTML = _a.allowHTML,
|
||||||
|
_d = _a.classNames,
|
||||||
|
group = _d.group,
|
||||||
|
groupHeading = _d.groupHeading,
|
||||||
|
itemDisabled = _d.itemDisabled;
|
||||||
var id = _b.id,
|
var id = _b.id,
|
||||||
value = _b.value,
|
value = _b.value,
|
||||||
disabled = _b.disabled;
|
disabled = _b.disabled;
|
||||||
|
@ -4517,19 +4530,22 @@ var templates = {
|
||||||
div.setAttribute('aria-disabled', 'true');
|
div.setAttribute('aria-disabled', 'true');
|
||||||
}
|
}
|
||||||
|
|
||||||
div.appendChild(Object.assign(document.createElement('div'), {
|
div.appendChild(Object.assign(document.createElement('div'), (_c = {
|
||||||
className: groupHeading,
|
className: groupHeading
|
||||||
innerHTML: value
|
}, _c[allowHTML ? 'innerHTML' : 'innerText'] = value, _c)));
|
||||||
}));
|
|
||||||
return div;
|
return div;
|
||||||
},
|
},
|
||||||
choice: function (_a, _b, selectText) {
|
choice: function (_a, _b, selectText) {
|
||||||
var item = _a.item,
|
var _c;
|
||||||
itemChoice = _a.itemChoice,
|
|
||||||
itemSelectable = _a.itemSelectable,
|
var allowHTML = _a.allowHTML,
|
||||||
selectedState = _a.selectedState,
|
_d = _a.classNames,
|
||||||
itemDisabled = _a.itemDisabled,
|
item = _d.item,
|
||||||
placeholder = _a.placeholder;
|
itemChoice = _d.itemChoice,
|
||||||
|
itemSelectable = _d.itemSelectable,
|
||||||
|
selectedState = _d.selectedState,
|
||||||
|
itemDisabled = _d.itemDisabled,
|
||||||
|
placeholder = _d.placeholder;
|
||||||
var id = _b.id,
|
var id = _b.id,
|
||||||
value = _b.value,
|
value = _b.value,
|
||||||
label = _b.label,
|
label = _b.label,
|
||||||
|
@ -4538,11 +4554,9 @@ var templates = {
|
||||||
isDisabled = _b.disabled,
|
isDisabled = _b.disabled,
|
||||||
isSelected = _b.selected,
|
isSelected = _b.selected,
|
||||||
isPlaceholder = _b.placeholder;
|
isPlaceholder = _b.placeholder;
|
||||||
var div = Object.assign(document.createElement('div'), {
|
var div = Object.assign(document.createElement('div'), (_c = {
|
||||||
id: elementId,
|
id: elementId
|
||||||
innerHTML: label,
|
}, _c[allowHTML ? 'innerHTML' : 'innerText'] = label, _c.className = "".concat(item, " ").concat(itemChoice), _c));
|
||||||
className: "".concat(item, " ").concat(itemChoice)
|
|
||||||
});
|
|
||||||
|
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
div.classList.add(selectedState);
|
div.classList.add(selectedState);
|
||||||
|
@ -4572,10 +4586,12 @@ var templates = {
|
||||||
return div;
|
return div;
|
||||||
},
|
},
|
||||||
input: function (_a, placeholderValue) {
|
input: function (_a, placeholderValue) {
|
||||||
var input = _a.input,
|
var _b = _a.classNames,
|
||||||
inputCloned = _a.inputCloned;
|
input = _b.input,
|
||||||
|
inputCloned = _b.inputCloned;
|
||||||
var inp = Object.assign(document.createElement('input'), {
|
var inp = Object.assign(document.createElement('input'), {
|
||||||
type: 'text',
|
type: 'search',
|
||||||
|
name: 'search_terms',
|
||||||
className: "".concat(input, " ").concat(inputCloned),
|
className: "".concat(input, " ").concat(inputCloned),
|
||||||
autocomplete: 'off',
|
autocomplete: 'off',
|
||||||
autocapitalize: 'off',
|
autocapitalize: 'off',
|
||||||
|
@ -4587,18 +4603,23 @@ var templates = {
|
||||||
return inp;
|
return inp;
|
||||||
},
|
},
|
||||||
dropdown: function (_a) {
|
dropdown: function (_a) {
|
||||||
var list = _a.list,
|
var _b = _a.classNames,
|
||||||
listDropdown = _a.listDropdown;
|
list = _b.list,
|
||||||
|
listDropdown = _b.listDropdown;
|
||||||
var div = document.createElement('div');
|
var div = document.createElement('div');
|
||||||
div.classList.add(list, listDropdown);
|
div.classList.add(list, listDropdown);
|
||||||
div.setAttribute('aria-expanded', 'false');
|
div.setAttribute('aria-expanded', 'false');
|
||||||
return div;
|
return div;
|
||||||
},
|
},
|
||||||
notice: function (_a, innerHTML, type) {
|
notice: function (_a, innerText, type) {
|
||||||
var item = _a.item,
|
var _b;
|
||||||
itemChoice = _a.itemChoice,
|
|
||||||
noResults = _a.noResults,
|
var allowHTML = _a.allowHTML,
|
||||||
noChoices = _a.noChoices;
|
_c = _a.classNames,
|
||||||
|
item = _c.item,
|
||||||
|
itemChoice = _c.itemChoice,
|
||||||
|
noResults = _c.noResults,
|
||||||
|
noChoices = _c.noChoices;
|
||||||
|
|
||||||
if (type === void 0) {
|
if (type === void 0) {
|
||||||
type = '';
|
type = '';
|
||||||
|
@ -4612,10 +4633,7 @@ var templates = {
|
||||||
classes.push(noResults);
|
classes.push(noResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Object.assign(document.createElement('div'), {
|
return Object.assign(document.createElement('div'), (_b = {}, _b[allowHTML ? 'innerHTML' : 'innerText'] = innerText, _b.className = classes.join(' '), _b));
|
||||||
innerHTML: innerHTML,
|
|
||||||
className: classes.join(' ')
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
option: function (_a) {
|
option: function (_a) {
|
||||||
var label = _a.label,
|
var label = _a.label,
|
||||||
|
|
2
public/assets/scripts/choices.min.js
vendored
2
public/assets/scripts/choices.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -534,6 +534,7 @@
|
||||||
for (i = 0; i < genericExamples.length; ++i) {
|
for (i = 0; i < genericExamples.length; ++i) {
|
||||||
var element = genericExamples[i];
|
var element = genericExamples[i];
|
||||||
new Choices(element, {
|
new Choices(element, {
|
||||||
|
allowHTML: true,
|
||||||
placeholderValue: 'This is a placeholder set in the config',
|
placeholderValue: 'This is a placeholder set in the config',
|
||||||
searchPlaceholderValue: 'This is a search placeholder',
|
searchPlaceholderValue: 'This is a search placeholder',
|
||||||
});
|
});
|
||||||
|
@ -542,6 +543,7 @@
|
||||||
var textRemove = new Choices(
|
var textRemove = new Choices(
|
||||||
document.getElementById('choices-text-remove-button'),
|
document.getElementById('choices-text-remove-button'),
|
||||||
{
|
{
|
||||||
|
allowHTML: true,
|
||||||
delimiter: ',',
|
delimiter: ',',
|
||||||
editItems: true,
|
editItems: true,
|
||||||
maxItemCount: 5,
|
maxItemCount: 5,
|
||||||
|
@ -550,12 +552,14 @@
|
||||||
);
|
);
|
||||||
|
|
||||||
var textUniqueVals = new Choices('#choices-text-unique-values', {
|
var textUniqueVals = new Choices('#choices-text-unique-values', {
|
||||||
|
allowHTML: true,
|
||||||
paste: false,
|
paste: false,
|
||||||
duplicateItemsAllowed: false,
|
duplicateItemsAllowed: false,
|
||||||
editItems: true,
|
editItems: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
var texti18n = new Choices('#choices-text-i18n', {
|
var texti18n = new Choices('#choices-text-i18n', {
|
||||||
|
allowHTML: true,
|
||||||
paste: false,
|
paste: false,
|
||||||
duplicateItemsAllowed: false,
|
duplicateItemsAllowed: false,
|
||||||
editItems: true,
|
editItems: true,
|
||||||
|
@ -572,6 +576,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
var textEmailFilter = new Choices('#choices-text-email-filter', {
|
var textEmailFilter = new Choices('#choices-text-email-filter', {
|
||||||
|
allowHTML: true,
|
||||||
editItems: true,
|
editItems: true,
|
||||||
addItemFilter: function(value) {
|
addItemFilter: function(value) {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
|
@ -585,6 +590,7 @@
|
||||||
}).setValue(['joe@bloggs.com']);
|
}).setValue(['joe@bloggs.com']);
|
||||||
|
|
||||||
var textDisabled = new Choices('#choices-text-disabled', {
|
var textDisabled = new Choices('#choices-text-disabled', {
|
||||||
|
allowHTML: true,
|
||||||
addItems: false,
|
addItems: false,
|
||||||
removeItems: false,
|
removeItems: false,
|
||||||
}).disable();
|
}).disable();
|
||||||
|
@ -592,12 +598,14 @@
|
||||||
var textPrependAppendVal = new Choices(
|
var textPrependAppendVal = new Choices(
|
||||||
'#choices-text-prepend-append-value',
|
'#choices-text-prepend-append-value',
|
||||||
{
|
{
|
||||||
|
allowHTML: true,
|
||||||
prependValue: 'item-',
|
prependValue: 'item-',
|
||||||
appendValue: '-' + Date.now(),
|
appendValue: '-' + Date.now(),
|
||||||
}
|
}
|
||||||
).removeActiveItems();
|
).removeActiveItems();
|
||||||
|
|
||||||
var textPresetVal = new Choices('#choices-text-preset-values', {
|
var textPresetVal = new Choices('#choices-text-preset-values', {
|
||||||
|
allowHTML: true,
|
||||||
items: [
|
items: [
|
||||||
'Josh Johnson',
|
'Josh Johnson',
|
||||||
{
|
{
|
||||||
|
@ -611,10 +619,12 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
var multipleDefault = new Choices(
|
var multipleDefault = new Choices(
|
||||||
document.getElementById('choices-multiple-groups')
|
document.getElementById('choices-multiple-groups'),
|
||||||
|
{ allowHTML: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
var multipleFetch = new Choices('#choices-multiple-remote-fetch', {
|
var multipleFetch = new Choices('#choices-multiple-remote-fetch', {
|
||||||
|
allowHTML: false,
|
||||||
placeholder: true,
|
placeholder: true,
|
||||||
placeholderValue: 'Pick an Strokes record',
|
placeholderValue: 'Pick an Strokes record',
|
||||||
maxItemCount: 5,
|
maxItemCount: 5,
|
||||||
|
@ -635,12 +645,14 @@
|
||||||
var multipleCancelButton = new Choices(
|
var multipleCancelButton = new Choices(
|
||||||
'#choices-multiple-remove-button',
|
'#choices-multiple-remove-button',
|
||||||
{
|
{
|
||||||
|
allowHTML: true,
|
||||||
removeItemButton: true,
|
removeItemButton: true,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
/* Use label on event */
|
/* Use label on event */
|
||||||
var choicesSelect = new Choices('#choices-multiple-labels', {
|
var choicesSelect = new Choices('#choices-multiple-labels', {
|
||||||
|
allowHTML: true,
|
||||||
removeItemButton: true,
|
removeItemButton: true,
|
||||||
choices: [
|
choices: [
|
||||||
{ value: 'One', label: 'Label One' },
|
{ value: 'One', label: 'Label One' },
|
||||||
|
@ -675,6 +687,7 @@
|
||||||
);
|
);
|
||||||
|
|
||||||
var singleFetch = new Choices('#choices-single-remote-fetch', {
|
var singleFetch = new Choices('#choices-single-remote-fetch', {
|
||||||
|
allowHTML: false,
|
||||||
searchPlaceholderValue: 'Search for an Arctic Monkeys record',
|
searchPlaceholderValue: 'Search for an Arctic Monkeys record',
|
||||||
})
|
})
|
||||||
.setChoices(function() {
|
.setChoices(function() {
|
||||||
|
@ -695,6 +708,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
var singleXhrRemove = new Choices('#choices-single-remove-xhr', {
|
var singleXhrRemove = new Choices('#choices-single-remove-xhr', {
|
||||||
|
allowHTML: true,
|
||||||
removeItemButton: true,
|
removeItemButton: true,
|
||||||
searchPlaceholderValue: "Search for a Smiths' record",
|
searchPlaceholderValue: "Search for a Smiths' record",
|
||||||
}).setChoices(function(callback) {
|
}).setChoices(function(callback) {
|
||||||
|
@ -712,6 +726,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
var singleNoSearch = new Choices('#choices-single-no-search', {
|
var singleNoSearch = new Choices('#choices-single-no-search', {
|
||||||
|
allowHTML: true,
|
||||||
searchEnabled: false,
|
searchEnabled: false,
|
||||||
removeItemButton: true,
|
removeItemButton: true,
|
||||||
choices: [
|
choices: [
|
||||||
|
@ -731,6 +746,7 @@
|
||||||
);
|
);
|
||||||
|
|
||||||
var singlePresetOpts = new Choices('#choices-single-preset-options', {
|
var singlePresetOpts = new Choices('#choices-single-preset-options', {
|
||||||
|
allowHTML: true,
|
||||||
placeholder: true,
|
placeholder: true,
|
||||||
}).setChoices(
|
}).setChoices(
|
||||||
[
|
[
|
||||||
|
@ -760,6 +776,7 @@
|
||||||
);
|
);
|
||||||
|
|
||||||
var singleSelectedOpt = new Choices('#choices-single-selected-option', {
|
var singleSelectedOpt = new Choices('#choices-single-selected-option', {
|
||||||
|
allowHTML: true,
|
||||||
searchFields: ['label', 'value', 'customProperties.description'],
|
searchFields: ['label', 'value', 'customProperties.description'],
|
||||||
choices: [
|
choices: [
|
||||||
{ value: 'One', label: 'Label One', selected: true },
|
{ value: 'One', label: 'Label One', selected: true },
|
||||||
|
@ -777,17 +794,20 @@
|
||||||
var customChoicesPropertiesViaDataAttributes = new Choices(
|
var customChoicesPropertiesViaDataAttributes = new Choices(
|
||||||
'#choices-with-custom-props-via-html',
|
'#choices-with-custom-props-via-html',
|
||||||
{
|
{
|
||||||
|
allowHTML: true,
|
||||||
searchFields: ['label', 'value', 'customProperties'],
|
searchFields: ['label', 'value', 'customProperties'],
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
var singleNoSorting = new Choices('#choices-single-no-sorting', {
|
var singleNoSorting = new Choices('#choices-single-no-sorting', {
|
||||||
|
allowHTML: true,
|
||||||
shouldSort: false,
|
shouldSort: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
var cities = new Choices(document.getElementById('cities'));
|
var cities = new Choices(document.getElementById('cities'), { allowHTML: true });
|
||||||
var tubeStations = new Choices(
|
var tubeStations = new Choices(
|
||||||
document.getElementById('tube-stations')
|
document.getElementById('tube-stations'),
|
||||||
|
{ allowHTML: true }
|
||||||
).disable();
|
).disable();
|
||||||
|
|
||||||
cities.passedElement.element.addEventListener('change', function(e) {
|
cities.passedElement.element.addEventListener('change', function(e) {
|
||||||
|
@ -801,11 +821,12 @@
|
||||||
var customTemplates = new Choices(
|
var customTemplates = new Choices(
|
||||||
document.getElementById('choices-single-custom-templates'),
|
document.getElementById('choices-single-custom-templates'),
|
||||||
{
|
{
|
||||||
|
allowHTML: true,
|
||||||
callbackOnCreateTemplates: function(strToEl) {
|
callbackOnCreateTemplates: function(strToEl) {
|
||||||
var classNames = this.config.classNames;
|
var classNames = this.config.classNames;
|
||||||
var itemSelectText = this.config.itemSelectText;
|
var itemSelectText = this.config.itemSelectText;
|
||||||
return {
|
return {
|
||||||
item: function(classNames, data) {
|
item: function({ classNames }, data) {
|
||||||
return strToEl(
|
return strToEl(
|
||||||
'\
|
'\
|
||||||
<div\
|
<div\
|
||||||
|
@ -839,7 +860,7 @@
|
||||||
'
|
'
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
choice: function(classNames, data) {
|
choice: function({ classNames }, data) {
|
||||||
return strToEl(
|
return strToEl(
|
||||||
'\
|
'\
|
||||||
<div\
|
<div\
|
||||||
|
@ -889,9 +910,12 @@
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
var resetSimple = new Choices(document.getElementById('reset-simple'));
|
var resetSimple = new Choices(document.getElementById('reset-simple'), {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
var resetMultiple = new Choices('#reset-multiple', {
|
var resetMultiple = new Choices('#reset-multiple', {
|
||||||
|
allowHTML: true,
|
||||||
removeItemButton: true,
|
removeItemButton: true,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -345,11 +345,43 @@
|
||||||
<option value="value2">label2</option>
|
<option value="value2">label2</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="allowhtml-undefined">
|
||||||
|
<label for="choices-allowhtml-undefined">HTML allowed by default</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-allowhtml-undefined"
|
||||||
|
id="choices-allowhtml-undefined"
|
||||||
|
multiple
|
||||||
|
></select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="allowhtml-true">
|
||||||
|
<label for="choices-allowhtml-true">HTML allowed</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-allowhtml-true"
|
||||||
|
id="choices-allowhtml-true"
|
||||||
|
multiple
|
||||||
|
></select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="allowhtml-false">
|
||||||
|
<label for="choices-allowhtml-false">HTML disabled</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-allowhtml-false"
|
||||||
|
id="choices-allowhtml-false"
|
||||||
|
multiple
|
||||||
|
></select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
const choicesBasic = new Choices('#choices-basic');
|
const choicesBasic = new Choices('#choices-basic', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
document
|
document
|
||||||
.querySelector('button.disable')
|
.querySelector('button.disable')
|
||||||
|
@ -364,39 +396,54 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-remove-button', {
|
new Choices('#choices-remove-button', {
|
||||||
|
allowHTML: true,
|
||||||
removeItemButton: true,
|
removeItemButton: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-disabled-choice');
|
new Choices('#choices-disabled-choice', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
new Choices('#choices-add-items-disabled', {
|
new Choices('#choices-add-items-disabled', {
|
||||||
|
allowHTML: true,
|
||||||
addItems: false,
|
addItems: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-disabled-via-attr');
|
new Choices('#choices-disabled-via-attr', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
new Choices('#choices-selection-limit', {
|
new Choices('#choices-selection-limit', {
|
||||||
|
allowHTML: true,
|
||||||
maxItemCount: 5,
|
maxItemCount: 5,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-prepend-append', {
|
new Choices('#choices-prepend-append', {
|
||||||
|
allowHTML: true,
|
||||||
prependValue: 'before-',
|
prependValue: 'before-',
|
||||||
appendValue: '-after',
|
appendValue: '-after',
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-render-choice-limit', {
|
new Choices('#choices-render-choice-limit', {
|
||||||
|
allowHTML: true,
|
||||||
renderChoiceLimit: 1,
|
renderChoiceLimit: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-search-floor', {
|
new Choices('#choices-search-floor', {
|
||||||
|
allowHTML: true,
|
||||||
searchFloor: 5,
|
searchFloor: 5,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-placeholder-via-option-value');
|
new Choices('#choices-placeholder-via-option-value', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
new Choices('#choices-placeholder-via-option-attr');
|
new Choices('#choices-placeholder-via-option-attr', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
new Choices('#choices-remote-data', {
|
new Choices('#choices-remote-data', {
|
||||||
|
allowHTML: true,
|
||||||
shouldSort: false,
|
shouldSort: false,
|
||||||
}).setChoices(async () => {
|
}).setChoices(async () => {
|
||||||
const data = await fetch('/data');
|
const data = await fetch('/data');
|
||||||
|
@ -404,12 +451,16 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-scrolling-dropdown', {
|
new Choices('#choices-scrolling-dropdown', {
|
||||||
|
allowHTML: true,
|
||||||
shouldSort: false,
|
shouldSort: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-groups');
|
new Choices('#choices-groups', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
new Choices('#choices-custom-properties', {
|
new Choices('#choices-custom-properties', {
|
||||||
|
allowHTML: true,
|
||||||
searchFields: ['label', 'value', 'customProperties.country'],
|
searchFields: ['label', 'value', 'customProperties.country'],
|
||||||
choices: [
|
choices: [
|
||||||
{
|
{
|
||||||
|
@ -440,6 +491,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-non-string-values', {
|
new Choices('#choices-non-string-values', {
|
||||||
|
allowHTML: true,
|
||||||
choices: [
|
choices: [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
|
@ -466,13 +518,83 @@
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-within-form');
|
new Choices('#choices-within-form', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
new Choices('#choices-set-choice-by-value').setChoiceByValue(
|
new Choices('#choices-set-choice-by-value', {
|
||||||
'Choice 2',
|
allowHTML: true,
|
||||||
);
|
}).setChoiceByValue('Choice 2');
|
||||||
|
|
||||||
new Choices('#choices-search-by-label', { searchFields: ['label'] });
|
new Choices('#choices-search-by-label', {
|
||||||
|
allowHTML: true,
|
||||||
|
searchFields: ['label']
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-allowhtml-undefined', {
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
label: '<b>Choice 1</b>',
|
||||||
|
value: 'Choice 1',
|
||||||
|
selected: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
label: '<b>Choice 2</b>',
|
||||||
|
value: 'Choice 2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
label: 'Choice 3',
|
||||||
|
value: 'Choice 3',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-allowhtml-true', {
|
||||||
|
allowHTML: true,
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
label: '<b>Choice 1</b>',
|
||||||
|
value: 'Choice 1',
|
||||||
|
selected: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
label: '<b>Choice 2</b>',
|
||||||
|
value: 'Choice 2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
label: 'Choice 3',
|
||||||
|
value: 'Choice 3',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-allowhtml-false', {
|
||||||
|
allowHTML: false,
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
label: '<b>Choice 1</b>',
|
||||||
|
value: 'Choice 1',
|
||||||
|
selected: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
label: '<b>Choice 2</b>',
|
||||||
|
value: 'Choice 2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
label: 'Choice 3',
|
||||||
|
value: 'Choice 3',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -354,6 +354,33 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="allowhtml-undefined">
|
||||||
|
<label for="choices-allowhtml-undefined">HTML allowed by default</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-allowhtml-undefined"
|
||||||
|
id="choices-allowhtml-undefined"
|
||||||
|
></select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="allowhtml-true">
|
||||||
|
<label for="choices-allowhtml-true">HTML allowed</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-allowhtml-true"
|
||||||
|
id="choices-allowhtml-true"
|
||||||
|
></select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="allowhtml-false">
|
||||||
|
<label for="choices-allowhtml-false">HTML disabled</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-allowhtml-false"
|
||||||
|
id="choices-allowhtml-false"
|
||||||
|
></select>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div data-test-hook="new-destroy-init">
|
<div data-test-hook="new-destroy-init">
|
||||||
<label for="choices-new-destroy-init">New, Destroy, Init</label>
|
<label for="choices-new-destroy-init">New, Destroy, Init</label>
|
||||||
<select
|
<select
|
||||||
|
@ -372,7 +399,9 @@
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
const choicesBasic = new Choices('#choices-basic');
|
const choicesBasic = new Choices('#choices-basic', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
document
|
document
|
||||||
.querySelector('button.disable')
|
.querySelector('button.disable')
|
||||||
|
@ -387,14 +416,17 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-remove-button', {
|
new Choices('#choices-remove-button', {
|
||||||
|
allowHTML: true,
|
||||||
removeItemButton: true,
|
removeItemButton: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-disabled-choice', {
|
new Choices('#choices-disabled-choice', {
|
||||||
|
allowHTML: true,
|
||||||
removeItemButton: true,
|
removeItemButton: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-disabled-choice-via-options', {
|
new Choices('#choices-disabled-choice-via-options', {
|
||||||
|
allowHTML: true,
|
||||||
removeItemButton: true,
|
removeItemButton: true,
|
||||||
choices: [
|
choices: [
|
||||||
{
|
{
|
||||||
|
@ -418,33 +450,45 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-add-items-disabled', {
|
new Choices('#choices-add-items-disabled', {
|
||||||
|
allowHTML: true,
|
||||||
addItems: false,
|
addItems: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-disabled-via-attr');
|
new Choices('#choices-disabled-via-attr', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
new Choices('#choices-prepend-append', {
|
new Choices('#choices-prepend-append', {
|
||||||
|
allowHTML: true,
|
||||||
prependValue: 'before-',
|
prependValue: 'before-',
|
||||||
appendValue: '-after',
|
appendValue: '-after',
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-render-choice-limit', {
|
new Choices('#choices-render-choice-limit', {
|
||||||
|
allowHTML: true,
|
||||||
renderChoiceLimit: 1,
|
renderChoiceLimit: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-search-disabled', {
|
new Choices('#choices-search-disabled', {
|
||||||
|
allowHTML: true,
|
||||||
searchEnabled: false,
|
searchEnabled: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-search-floor', {
|
new Choices('#choices-search-floor', {
|
||||||
|
allowHTML: true,
|
||||||
searchFloor: 5,
|
searchFloor: 5,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-placeholder-via-option-value');
|
new Choices('#choices-placeholder-via-option-value', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
new Choices('#choices-placeholder-via-option-attr');
|
new Choices('#choices-placeholder-via-option-attr', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
new Choices('#choices-remote-data', {
|
new Choices('#choices-remote-data', {
|
||||||
|
allowHTML: true,
|
||||||
shouldSort: false,
|
shouldSort: false,
|
||||||
}).setChoices(async () => {
|
}).setChoices(async () => {
|
||||||
const res = await fetch('/data');
|
const res = await fetch('/data');
|
||||||
|
@ -452,13 +496,20 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-scrolling-dropdown', {
|
new Choices('#choices-scrolling-dropdown', {
|
||||||
|
allowHTML: true,
|
||||||
shouldSort: false,
|
shouldSort: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-groups');
|
new Choices('#choices-groups', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
const parent = new Choices('#choices-parent');
|
const parent = new Choices('#choices-parent', {
|
||||||
const child = new Choices('#choices-child').disable();
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
const child = new Choices('#choices-child', {
|
||||||
|
allowHTML: true,
|
||||||
|
}).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') {
|
||||||
|
@ -469,6 +520,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-custom-properties', {
|
new Choices('#choices-custom-properties', {
|
||||||
|
allowHTML: true,
|
||||||
searchFields: ['label', 'value', 'customProperties.country'],
|
searchFields: ['label', 'value', 'customProperties.country'],
|
||||||
choices: [
|
choices: [
|
||||||
{
|
{
|
||||||
|
@ -499,6 +551,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-non-string-values', {
|
new Choices('#choices-non-string-values', {
|
||||||
|
allowHTML: true,
|
||||||
choices: [
|
choices: [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
|
@ -525,15 +578,69 @@
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-within-form');
|
new Choices('#choices-within-form', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
new Choices('#choices-set-choice-by-value').setChoiceByValue(
|
new Choices('#choices-set-choice-by-value', {
|
||||||
'Choice 2',
|
allowHTML: true,
|
||||||
);
|
}).setChoiceByValue('Choice 2');
|
||||||
|
|
||||||
new Choices('#choices-search-by-label', { searchFields: ['label'] });
|
new Choices('#choices-search-by-label', {
|
||||||
|
allowHTML: true,
|
||||||
|
searchFields: ['label']
|
||||||
|
});
|
||||||
|
|
||||||
const newDestroyInitChoices = new Choices('#choices-new-destroy-init');
|
new Choices('#choices-allowhtml-undefined', {
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
label: '<b>Choice 1</b>',
|
||||||
|
value: 'Choice 1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
label: 'Choice 2',
|
||||||
|
value: 'Choice 2',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-allowhtml-true', {
|
||||||
|
allowHTML: true,
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
label: '<b>Choice 1</b>',
|
||||||
|
value: 'Choice 1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
label: 'Choice 2',
|
||||||
|
value: 'Choice 2',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-allowhtml-false', {
|
||||||
|
allowHTML: false,
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
label: '<b>Choice 1</b>',
|
||||||
|
value: 'Choice 1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
label: 'Choice 2',
|
||||||
|
value: 'Choice 2',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const newDestroyInitChoices = new Choices('#choices-new-destroy-init', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
document
|
document
|
||||||
.querySelector('button.destroy')
|
.querySelector('button.destroy')
|
||||||
.addEventListener('click', () => {
|
.addEventListener('click', () => {
|
||||||
|
|
|
@ -76,6 +76,21 @@
|
||||||
<input class="form-control" id="choices-unique-values" type="text" />
|
<input class="form-control" id="choices-unique-values" type="text" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="allowhtml-undefined">
|
||||||
|
<label for="allowhtml-undefined">HTML allowed by default</label>
|
||||||
|
<input class="form-control" id="allowhtml-undefined" type="text" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="allowhtml-true">
|
||||||
|
<label for="allowhtml-true">HTML allowed</label>
|
||||||
|
<input class="form-control" id="allowhtml-true" type="text" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="allowhtml-false">
|
||||||
|
<label for="allowhtml-false">HTML disabled</label>
|
||||||
|
<input class="form-control" id="allowhtml-false" type="text" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<div data-test-hook="input-limit">
|
<div data-test-hook="input-limit">
|
||||||
<label for="choices-input-limit">Input limit</label>
|
<label for="choices-input-limit">Input limit</label>
|
||||||
<input class="form-control" id="choices-input-limit" type="text" />
|
<input class="form-control" id="choices-input-limit" type="text" />
|
||||||
|
@ -134,25 +149,52 @@
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
new Choices('#choices-basic');
|
new Choices('#choices-basic', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
new Choices('#choices-edit-items', {
|
new Choices('#choices-edit-items', {
|
||||||
|
allowHTML: true,
|
||||||
editItems: true,
|
editItems: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-remove-button', {
|
new Choices('#choices-remove-button', {
|
||||||
|
allowHTML: true,
|
||||||
removeItemButton: true,
|
removeItemButton: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-unique-values', {
|
new Choices('#choices-unique-values', {
|
||||||
|
allowHTML: true,
|
||||||
duplicateItemsAllowed: false,
|
duplicateItemsAllowed: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
new Choices('#allowhtml-undefined', {
|
||||||
|
items: [
|
||||||
|
'<b>Mason Rogers</b>'
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#allowhtml-true', {
|
||||||
|
allowHTML: true,
|
||||||
|
items: [
|
||||||
|
'<b>Mason Rogers</b>'
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#allowhtml-false', {
|
||||||
|
allowHTML: false,
|
||||||
|
items: [
|
||||||
|
'<b>Mason Rogers</b>'
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
new Choices('#choices-input-limit', {
|
new Choices('#choices-input-limit', {
|
||||||
|
allowHTML: true,
|
||||||
maxItemCount: 5,
|
maxItemCount: 5,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-add-item-filter', {
|
new Choices('#choices-add-item-filter', {
|
||||||
|
allowHTML: true,
|
||||||
addItems: true,
|
addItems: true,
|
||||||
addItemFilter: value => {
|
addItemFilter: value => {
|
||||||
const regex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
const regex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||||
|
@ -162,17 +204,22 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-adding-items-disabled', {
|
new Choices('#choices-adding-items-disabled', {
|
||||||
|
allowHTML: true,
|
||||||
addItems: false,
|
addItems: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-disabled-via-attr');
|
new Choices('#choices-disabled-via-attr', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
new Choices('#choices-prepend-append', {
|
new Choices('#choices-prepend-append', {
|
||||||
|
allowHTML: true,
|
||||||
prependValue: 'before-',
|
prependValue: 'before-',
|
||||||
appendValue: '-after',
|
appendValue: '-after',
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-prepopulated', {
|
new Choices('#choices-prepopulated', {
|
||||||
|
allowHTML: true,
|
||||||
items: [
|
items: [
|
||||||
'Josh Johnson',
|
'Josh Johnson',
|
||||||
{
|
{
|
||||||
|
@ -186,11 +233,14 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-placeholder', {
|
new Choices('#choices-placeholder', {
|
||||||
|
allowHTML: true,
|
||||||
placeholder: true,
|
placeholder: true,
|
||||||
placeholderValue: 'I am a placeholder',
|
placeholderValue: 'I am a placeholder',
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-within-form');
|
new Choices('#choices-within-form', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -26,7 +26,7 @@ describe('choices', () => {
|
||||||
passedElement.className = 'js-choices';
|
passedElement.className = 'js-choices';
|
||||||
document.body.appendChild(passedElement);
|
document.body.appendChild(passedElement);
|
||||||
|
|
||||||
instance = new Choices(passedElement);
|
instance = new Choices(passedElement, { allowHTML: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
@ -55,6 +55,7 @@ describe('choices', () => {
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
|
allowHTML: true,
|
||||||
renderChoiceLimit: 5,
|
renderChoiceLimit: 5,
|
||||||
};
|
};
|
||||||
instance = new Choices('[data-choice]', config);
|
instance = new Choices('[data-choice]', config);
|
||||||
|
@ -73,6 +74,7 @@ describe('choices', () => {
|
||||||
`;
|
`;
|
||||||
|
|
||||||
instance = new Choices('[data-choice]', {
|
instance = new Choices('[data-choice]', {
|
||||||
|
allowHTML: true,
|
||||||
searchEnabled: false,
|
searchEnabled: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -88,6 +90,7 @@ describe('choices', () => {
|
||||||
`;
|
`;
|
||||||
|
|
||||||
instance = new Choices('[data-choice]', {
|
instance = new Choices('[data-choice]', {
|
||||||
|
allowHTML: true,
|
||||||
renderSelectedChoices: 'test' as any,
|
renderSelectedChoices: 'test' as any,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -108,7 +111,7 @@ describe('choices', () => {
|
||||||
const inputs = document.querySelectorAll('[data-choice]');
|
const inputs = document.querySelectorAll('[data-choice]');
|
||||||
expect(inputs.length).to.equal(3);
|
expect(inputs.length).to.equal(3);
|
||||||
|
|
||||||
instance = new Choices();
|
instance = new Choices(undefined, { allowHTML: true });
|
||||||
|
|
||||||
expect(instance.passedElement.element.id).to.equal(inputs[0].id);
|
expect(instance.passedElement.element.id).to.equal(inputs[0].id);
|
||||||
});
|
});
|
||||||
|
@ -116,7 +119,7 @@ describe('choices', () => {
|
||||||
describe('when an element cannot be found in the DOM', () => {
|
describe('when an element cannot be found in the DOM', () => {
|
||||||
it('throws an error', () => {
|
it('throws an error', () => {
|
||||||
document.body.innerHTML = ``;
|
document.body.innerHTML = ``;
|
||||||
expect(() => new Choices()).to.throw(
|
expect(() => new Choices(undefined, { allowHTML: true })).to.throw(
|
||||||
TypeError,
|
TypeError,
|
||||||
'Expected one of the following types text|select-one|select-multiple',
|
'Expected one of the following types text|select-one|select-multiple',
|
||||||
);
|
);
|
||||||
|
@ -133,7 +136,7 @@ describe('choices', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sets the initialised flag to true', () => {
|
it('sets the initialised flag to true', () => {
|
||||||
instance = new Choices('#input-1');
|
instance = new Choices('#input-1', { allowHTML: true });
|
||||||
expect(instance.initialised).to.equal(true);
|
expect(instance.initialised).to.equal(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -141,6 +144,7 @@ describe('choices', () => {
|
||||||
const initSpy = spy();
|
const initSpy = spy();
|
||||||
// initialise with the same element
|
// initialise with the same element
|
||||||
instance = new Choices('#input-1', {
|
instance = new Choices('#input-1', {
|
||||||
|
allowHTML: true,
|
||||||
silent: true,
|
silent: true,
|
||||||
callbackOnInit: initSpy,
|
callbackOnInit: initSpy,
|
||||||
});
|
});
|
||||||
|
@ -156,12 +160,12 @@ describe('choices', () => {
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// initialise once
|
// initialise once
|
||||||
new Choices('#input-1', { silent: true });
|
new Choices('#input-1', { allowHTML: true, silent: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sets the initialised flag to true', () => {
|
it('sets the initialised flag to true', () => {
|
||||||
// initialise with the same element
|
// initialise with the same element
|
||||||
instance = new Choices('#input-1', { silent: true });
|
instance = new Choices('#input-1', { allowHTML: true, silent: true });
|
||||||
|
|
||||||
expect(instance.initialised).to.equal(true);
|
expect(instance.initialised).to.equal(true);
|
||||||
});
|
});
|
||||||
|
@ -170,6 +174,7 @@ describe('choices', () => {
|
||||||
const initSpy = spy();
|
const initSpy = spy();
|
||||||
// initialise with the same element
|
// initialise with the same element
|
||||||
instance = new Choices('#input-1', {
|
instance = new Choices('#input-1', {
|
||||||
|
allowHTML: true,
|
||||||
silent: true,
|
silent: true,
|
||||||
callbackOnInit: initSpy,
|
callbackOnInit: initSpy,
|
||||||
});
|
});
|
||||||
|
@ -185,7 +190,7 @@ describe('choices', () => {
|
||||||
<input data-choice type="text" id="input-1" />
|
<input data-choice type="text" id="input-1" />
|
||||||
`;
|
`;
|
||||||
|
|
||||||
instance = new Choices('[data-choice]');
|
instance = new Choices('[data-choice]', { allowHTML: true });
|
||||||
|
|
||||||
expect(instance.passedElement).to.be.an.instanceOf(WrappedInput);
|
expect(instance.passedElement).to.be.an.instanceOf(WrappedInput);
|
||||||
});
|
});
|
||||||
|
@ -197,7 +202,7 @@ describe('choices', () => {
|
||||||
<select data-choice id="select-1"></select>
|
<select data-choice id="select-1"></select>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
instance = new Choices('[data-choice]');
|
instance = new Choices('[data-choice]', { allowHTML: true });
|
||||||
|
|
||||||
expect(instance.passedElement).to.be.an.instanceOf(WrappedSelect);
|
expect(instance.passedElement).to.be.an.instanceOf(WrappedSelect);
|
||||||
});
|
});
|
||||||
|
@ -211,7 +216,7 @@ describe('choices', () => {
|
||||||
<input data-choice type="text" id="input-1" />
|
<input data-choice type="text" id="input-1" />
|
||||||
`;
|
`;
|
||||||
|
|
||||||
instance = new Choices('[data-choice]');
|
instance = new Choices('[data-choice]', { allowHTML: true });
|
||||||
|
|
||||||
expect(instance.passedElement).to.be.an.instanceOf(WrappedInput);
|
expect(instance.passedElement).to.be.an.instanceOf(WrappedInput);
|
||||||
});
|
});
|
||||||
|
@ -223,7 +228,7 @@ describe('choices', () => {
|
||||||
<select data-choice id="select-1"></select>
|
<select data-choice id="select-1"></select>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
instance = new Choices('[data-choice]');
|
instance = new Choices('[data-choice]', { allowHTML: true });
|
||||||
|
|
||||||
expect(instance.passedElement).to.be.an.instanceOf(WrappedSelect);
|
expect(instance.passedElement).to.be.an.instanceOf(WrappedSelect);
|
||||||
});
|
});
|
||||||
|
@ -235,7 +240,9 @@ describe('choices', () => {
|
||||||
document.body.innerHTML = `
|
document.body.innerHTML = `
|
||||||
<div data-choice id="div-1"></div>
|
<div data-choice id="div-1"></div>
|
||||||
`;
|
`;
|
||||||
expect(() => new Choices('[data-choice]')).to.throw(
|
expect(
|
||||||
|
() => new Choices('[data-choice]', { allowHTML: true }),
|
||||||
|
).to.throw(
|
||||||
TypeError,
|
TypeError,
|
||||||
'Expected one of the following types text|select-one|select-multiple',
|
'Expected one of the following types text|select-one|select-multiple',
|
||||||
);
|
);
|
||||||
|
@ -250,6 +257,7 @@ describe('choices', () => {
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
instance = new Choices(passedElement, {
|
instance = new Choices(passedElement, {
|
||||||
|
allowHTML: true,
|
||||||
callbackOnInit: callbackOnInitSpy,
|
callbackOnInit: callbackOnInitSpy,
|
||||||
silent: true,
|
silent: true,
|
||||||
});
|
});
|
||||||
|
@ -330,7 +338,7 @@ describe('choices', () => {
|
||||||
passedElement.className = 'js-choices';
|
passedElement.className = 'js-choices';
|
||||||
document.body.appendChild(passedElement);
|
document.body.appendChild(passedElement);
|
||||||
|
|
||||||
instance = new Choices(passedElement);
|
instance = new Choices(passedElement, { allowHTML: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('not already initialised', () => {
|
describe('not already initialised', () => {
|
||||||
|
@ -1188,7 +1196,7 @@ describe('choices', () => {
|
||||||
describe('select element', () => {
|
describe('select element', () => {
|
||||||
it('fetches and sets choices', async () => {
|
it('fetches and sets choices', async () => {
|
||||||
document.body.innerHTML = '<select id="test" />';
|
document.body.innerHTML = '<select id="test" />';
|
||||||
const choice = new Choices('#test');
|
const choice = new Choices('#test', { allowHTML: true });
|
||||||
const handleLoadingStateSpy = spy(choice, '_handleLoadingState');
|
const handleLoadingStateSpy = spy(choice, '_handleLoadingState');
|
||||||
|
|
||||||
let fetcherCalled = false;
|
let fetcherCalled = false;
|
||||||
|
@ -2063,7 +2071,7 @@ describe('choices', () => {
|
||||||
output = instance._getTemplate(templateKey, customArg);
|
output = instance._getTemplate(templateKey, customArg);
|
||||||
expect(output).to.deep.equal(element);
|
expect(output).to.deep.equal(element);
|
||||||
expect(instance._templates[templateKey]).to.have.been.calledOnceWith(
|
expect(instance._templates[templateKey]).to.have.been.calledOnceWith(
|
||||||
instance.config.classNames,
|
instance.config,
|
||||||
customArg,
|
customArg,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
@ -151,6 +151,12 @@ class Choices implements Choices {
|
||||||
| HTMLSelectElement = '[data-choice]',
|
| HTMLSelectElement = '[data-choice]',
|
||||||
userConfig: Partial<Options> = {},
|
userConfig: Partial<Options> = {},
|
||||||
) {
|
) {
|
||||||
|
if (userConfig.allowHTML === undefined) {
|
||||||
|
console.warn(
|
||||||
|
'Deprecation warning: allowHTML will default to false in a future release. To render HTML in Choices, you will need to set it to true. Setting allowHTML will suppress this message.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this.config = merge.all<Options>(
|
this.config = merge.all<Options>(
|
||||||
[DEFAULT_CONFIG, Choices.defaults.options, userConfig],
|
[DEFAULT_CONFIG, Choices.defaults.options, userConfig],
|
||||||
// When merging array configs, replace with a copy of the userConfig array,
|
// When merging array configs, replace with a copy of the userConfig array,
|
||||||
|
@ -2105,9 +2111,7 @@ class Choices implements Choices {
|
||||||
}
|
}
|
||||||
|
|
||||||
_getTemplate(template: string, ...args: any): any {
|
_getTemplate(template: string, ...args: any): any {
|
||||||
const { classNames } = this.config;
|
return this._templates[template].call(this, this.config, ...args);
|
||||||
|
|
||||||
return this._templates[template].call(this, classNames, ...args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_createTemplates(): void {
|
_createTemplates(): void {
|
||||||
|
|
|
@ -54,6 +54,7 @@ describe('constants', () => {
|
||||||
expect(DEFAULT_CONFIG.removeItems).to.be.a('boolean');
|
expect(DEFAULT_CONFIG.removeItems).to.be.a('boolean');
|
||||||
expect(DEFAULT_CONFIG.removeItemButton).to.be.a('boolean');
|
expect(DEFAULT_CONFIG.removeItemButton).to.be.a('boolean');
|
||||||
expect(DEFAULT_CONFIG.editItems).to.be.a('boolean');
|
expect(DEFAULT_CONFIG.editItems).to.be.a('boolean');
|
||||||
|
expect(DEFAULT_CONFIG.allowHTML).to.be.a('boolean');
|
||||||
expect(DEFAULT_CONFIG.duplicateItemsAllowed).to.be.a('boolean');
|
expect(DEFAULT_CONFIG.duplicateItemsAllowed).to.be.a('boolean');
|
||||||
expect(DEFAULT_CONFIG.delimiter).to.be.a('string');
|
expect(DEFAULT_CONFIG.delimiter).to.be.a('string');
|
||||||
expect(DEFAULT_CONFIG.paste).to.be.a('boolean');
|
expect(DEFAULT_CONFIG.paste).to.be.a('boolean');
|
||||||
|
|
|
@ -42,6 +42,7 @@ export const DEFAULT_CONFIG: Options = {
|
||||||
removeItems: true,
|
removeItems: true,
|
||||||
removeItemButton: false,
|
removeItemButton: false,
|
||||||
editItems: false,
|
editItems: false,
|
||||||
|
allowHTML: true,
|
||||||
duplicateItemsAllowed: true,
|
duplicateItemsAllowed: true,
|
||||||
delimiter: ',',
|
delimiter: ',',
|
||||||
paste: true,
|
paste: true,
|
||||||
|
|
|
@ -159,6 +159,19 @@ export interface Options {
|
||||||
*/
|
*/
|
||||||
editItems: boolean;
|
editItems: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether HTML should be rendered in all Choices elements.
|
||||||
|
* If `false`, all elements (placeholder, items, etc.) will be treated as plain text.
|
||||||
|
* If `true`, this can be used to perform XSS scripting attacks if you load choices from a remote source.
|
||||||
|
*
|
||||||
|
* **Deprecation Warning:** This will default to `false` in a future release.
|
||||||
|
*
|
||||||
|
* **Input types affected:** text, select-one, select-multiple
|
||||||
|
*
|
||||||
|
* @default true
|
||||||
|
*/
|
||||||
|
allowHTML: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether each inputted/chosen item should be unique.
|
* Whether each inputted/chosen item should be unique.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
import templates from './templates';
|
import templates from './templates';
|
||||||
import { strToEl } from './lib/utils';
|
import { strToEl } from './lib/utils';
|
||||||
|
import { DEFAULT_CLASSNAMES, DEFAULT_CONFIG } from './defaults';
|
||||||
|
import { Options } from './interfaces/options';
|
||||||
|
import { ClassNames } from './interfaces/class-names';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {HTMLElement} element1
|
* @param {HTMLElement} element1
|
||||||
|
@ -21,11 +24,25 @@ function expectEqualElements(element1, element2): void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createOptionsWithPartialClasses(
|
||||||
|
classNames: Partial<ClassNames>,
|
||||||
|
options: Partial<Options> = {},
|
||||||
|
): Options {
|
||||||
|
return {
|
||||||
|
...DEFAULT_CONFIG,
|
||||||
|
...options,
|
||||||
|
classNames: {
|
||||||
|
...DEFAULT_CLASSNAMES,
|
||||||
|
...classNames,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
describe('templates', () => {
|
describe('templates', () => {
|
||||||
describe('containerOuter', () => {
|
describe('containerOuter', () => {
|
||||||
const classes = {
|
const options = createOptionsWithPartialClasses({
|
||||||
containerOuter: 'class-1',
|
containerOuter: 'class-1',
|
||||||
};
|
});
|
||||||
const direction = 'rtl';
|
const direction = 'rtl';
|
||||||
|
|
||||||
describe('select element', () => {
|
describe('select element', () => {
|
||||||
|
@ -38,7 +55,7 @@ describe('templates', () => {
|
||||||
|
|
||||||
const expectedOutput = strToEl(`
|
const expectedOutput = strToEl(`
|
||||||
<div
|
<div
|
||||||
class="${classes.containerOuter}"
|
class="${options.classNames.containerOuter}"
|
||||||
data-type="${passedElementType}"
|
data-type="${passedElementType}"
|
||||||
role="combobox"
|
role="combobox"
|
||||||
aria-autocomplete="list"
|
aria-autocomplete="list"
|
||||||
|
@ -49,7 +66,7 @@ describe('templates', () => {
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
const actualOutput = templates.containerOuter(
|
const actualOutput = templates.containerOuter(
|
||||||
classes,
|
options,
|
||||||
direction,
|
direction,
|
||||||
isSelectElement,
|
isSelectElement,
|
||||||
isSelectOneElement,
|
isSelectOneElement,
|
||||||
|
@ -69,7 +86,7 @@ describe('templates', () => {
|
||||||
|
|
||||||
const expectedOutput = strToEl(`
|
const expectedOutput = strToEl(`
|
||||||
<div
|
<div
|
||||||
class="${classes.containerOuter}"
|
class="${options.classNames.containerOuter}"
|
||||||
data-type="${passedElementType}"
|
data-type="${passedElementType}"
|
||||||
role="listbox"
|
role="listbox"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
|
@ -79,7 +96,7 @@ describe('templates', () => {
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
const actualOutput = templates.containerOuter(
|
const actualOutput = templates.containerOuter(
|
||||||
classes,
|
options,
|
||||||
direction,
|
direction,
|
||||||
isSelectElement,
|
isSelectElement,
|
||||||
isSelectOneElement,
|
isSelectOneElement,
|
||||||
|
@ -100,7 +117,7 @@ describe('templates', () => {
|
||||||
|
|
||||||
const expectedOutput = strToEl(`
|
const expectedOutput = strToEl(`
|
||||||
<div
|
<div
|
||||||
class="${classes.containerOuter}"
|
class="${options.classNames.containerOuter}"
|
||||||
data-type="${passedElementType}"
|
data-type="${passedElementType}"
|
||||||
role="listbox"
|
role="listbox"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
|
@ -111,7 +128,7 @@ describe('templates', () => {
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
const actualOutput = templates.containerOuter(
|
const actualOutput = templates.containerOuter(
|
||||||
classes,
|
options,
|
||||||
direction,
|
direction,
|
||||||
isSelectElement,
|
isSelectElement,
|
||||||
isSelectOneElement,
|
isSelectOneElement,
|
||||||
|
@ -133,7 +150,7 @@ describe('templates', () => {
|
||||||
|
|
||||||
const expectedOutput = strToEl(`
|
const expectedOutput = strToEl(`
|
||||||
<div
|
<div
|
||||||
class="${classes.containerOuter}"
|
class="${options.classNames.containerOuter}"
|
||||||
data-type="${passedElementType}"
|
data-type="${passedElementType}"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
|
@ -142,7 +159,7 @@ describe('templates', () => {
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
const actualOutput = templates.containerOuter(
|
const actualOutput = templates.containerOuter(
|
||||||
classes,
|
options,
|
||||||
direction,
|
direction,
|
||||||
isSelectElement,
|
isSelectElement,
|
||||||
isSelectOneElement,
|
isSelectOneElement,
|
||||||
|
@ -157,31 +174,31 @@ describe('templates', () => {
|
||||||
|
|
||||||
describe('containerInner', () => {
|
describe('containerInner', () => {
|
||||||
it('returns expected html', () => {
|
it('returns expected html', () => {
|
||||||
const classes = {
|
const innerOptions = createOptionsWithPartialClasses({
|
||||||
containerInner: 'class-1',
|
containerInner: 'class-1',
|
||||||
};
|
});
|
||||||
const expectedOutput = strToEl(
|
const expectedOutput = strToEl(
|
||||||
`<div class="${classes.containerInner}"></div>`,
|
`<div class="${innerOptions.classNames.containerInner}"></div>`,
|
||||||
);
|
);
|
||||||
const actualOutput = templates.containerInner(classes);
|
const actualOutput = templates.containerInner(innerOptions);
|
||||||
|
|
||||||
expectEqualElements(actualOutput, expectedOutput);
|
expectEqualElements(actualOutput, expectedOutput);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('itemList', () => {
|
describe('itemList', () => {
|
||||||
const classes = {
|
const itemOptions = createOptionsWithPartialClasses({
|
||||||
list: 'class-1',
|
list: 'class-1',
|
||||||
listSingle: 'class-2',
|
listSingle: 'class-2',
|
||||||
listItems: 'class-3',
|
listItems: 'class-3',
|
||||||
};
|
});
|
||||||
|
|
||||||
describe('select one element', () => {
|
describe('select one element', () => {
|
||||||
it('returns expected html', () => {
|
it('returns expected html', () => {
|
||||||
const expectedOutput = strToEl(
|
const expectedOutput = strToEl(
|
||||||
`<div class="${classes.list} ${classes.listSingle}"></div>`,
|
`<div class="${itemOptions.classNames.list} ${itemOptions.classNames.listSingle}"></div>`,
|
||||||
);
|
);
|
||||||
const actualOutput = templates.itemList(classes, true);
|
const actualOutput = templates.itemList(itemOptions, true);
|
||||||
|
|
||||||
expectEqualElements(actualOutput, expectedOutput);
|
expectEqualElements(actualOutput, expectedOutput);
|
||||||
});
|
});
|
||||||
|
@ -190,9 +207,9 @@ describe('templates', () => {
|
||||||
describe('non select one element', () => {
|
describe('non select one element', () => {
|
||||||
it('returns expected html', () => {
|
it('returns expected html', () => {
|
||||||
const expectedOutput = strToEl(
|
const expectedOutput = strToEl(
|
||||||
`<div class="${classes.list} ${classes.listItems}"></div>`,
|
`<div class="${itemOptions.classNames.list} ${itemOptions.classNames.listItems}"></div>`,
|
||||||
);
|
);
|
||||||
const actualOutput = templates.itemList(classes, false);
|
const actualOutput = templates.itemList(itemOptions, false);
|
||||||
|
|
||||||
expectEqualElements(actualOutput, expectedOutput);
|
expectEqualElements(actualOutput, expectedOutput);
|
||||||
});
|
});
|
||||||
|
@ -201,33 +218,33 @@ describe('templates', () => {
|
||||||
|
|
||||||
describe('placeholder', () => {
|
describe('placeholder', () => {
|
||||||
it('returns expected html', () => {
|
it('returns expected html', () => {
|
||||||
const classes = {
|
const placeholderOptions = createOptionsWithPartialClasses({
|
||||||
placeholder: 'class-1',
|
placeholder: 'class-1',
|
||||||
};
|
});
|
||||||
const value = 'test';
|
const value = 'test';
|
||||||
const expectedOutput = strToEl(`
|
const expectedOutput = strToEl(`
|
||||||
<div class="${classes.placeholder}">${value}</div>`);
|
<div class="${placeholderOptions.classNames.placeholder}">${value}</div>`);
|
||||||
const actualOutput = templates.placeholder(classes, value);
|
const actualOutput = templates.placeholder(placeholderOptions, value);
|
||||||
|
|
||||||
expectEqualElements(actualOutput, expectedOutput);
|
expectEqualElements(actualOutput, expectedOutput);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('choiceList', () => {
|
describe('choiceList', () => {
|
||||||
const classes = {
|
const choiceListOptions = createOptionsWithPartialClasses({
|
||||||
list: 'class-1',
|
list: 'class-1',
|
||||||
};
|
});
|
||||||
|
|
||||||
describe('select one element', () => {
|
describe('select one element', () => {
|
||||||
it('returns expected html', () => {
|
it('returns expected html', () => {
|
||||||
const expectedOutput = strToEl(`
|
const expectedOutput = strToEl(`
|
||||||
<div
|
<div
|
||||||
class="${classes.list}"
|
class="${choiceListOptions.classNames.list}"
|
||||||
role="listbox"
|
role="listbox"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
const actualOutput = templates.choiceList(classes, true);
|
const actualOutput = templates.choiceList(choiceListOptions, true);
|
||||||
|
|
||||||
expectEqualElements(actualOutput, expectedOutput);
|
expectEqualElements(actualOutput, expectedOutput);
|
||||||
});
|
});
|
||||||
|
@ -237,13 +254,13 @@ describe('templates', () => {
|
||||||
it('returns expected html', () => {
|
it('returns expected html', () => {
|
||||||
const expectedOutput = strToEl(`
|
const expectedOutput = strToEl(`
|
||||||
<div
|
<div
|
||||||
class="${classes.list}"
|
class="${choiceListOptions.classNames.list}"
|
||||||
role="listbox"
|
role="listbox"
|
||||||
aria-multiselectable="true"
|
aria-multiselectable="true"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
const actualOutput = templates.choiceList(classes, false);
|
const actualOutput = templates.choiceList(choiceListOptions, false);
|
||||||
|
|
||||||
expectEqualElements(actualOutput, expectedOutput);
|
expectEqualElements(actualOutput, expectedOutput);
|
||||||
});
|
});
|
||||||
|
@ -251,11 +268,11 @@ describe('templates', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('choiceGroup', () => {
|
describe('choiceGroup', () => {
|
||||||
const classes = {
|
const groupOptions = createOptionsWithPartialClasses({
|
||||||
group: 'class-1',
|
group: 'class-1',
|
||||||
groupHeading: 'class-2',
|
groupHeading: 'class-2',
|
||||||
itemDisabled: 'class-3',
|
itemDisabled: 'class-3',
|
||||||
};
|
});
|
||||||
|
|
||||||
let data;
|
let data;
|
||||||
|
|
||||||
|
@ -271,16 +288,16 @@ describe('templates', () => {
|
||||||
it('returns expected html', () => {
|
it('returns expected html', () => {
|
||||||
const expectedOutput = strToEl(`
|
const expectedOutput = strToEl(`
|
||||||
<div
|
<div
|
||||||
class="${classes.group}"
|
class="${groupOptions.classNames.group}"
|
||||||
data-group
|
data-group
|
||||||
data-id="${data.id}"
|
data-id="${data.id}"
|
||||||
data-value="${data.value}"
|
data-value="${data.value}"
|
||||||
role="group"
|
role="group"
|
||||||
>
|
>
|
||||||
<div class="${classes.groupHeading}">${data.value}</div>
|
<div class="${groupOptions.classNames.groupHeading}">${data.value}</div>
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
const actualOutput = templates.choiceGroup(classes, data);
|
const actualOutput = templates.choiceGroup(groupOptions, data);
|
||||||
|
|
||||||
expectEqualElements(actualOutput, expectedOutput);
|
expectEqualElements(actualOutput, expectedOutput);
|
||||||
});
|
});
|
||||||
|
@ -297,17 +314,17 @@ describe('templates', () => {
|
||||||
it('returns expected html', () => {
|
it('returns expected html', () => {
|
||||||
const expectedOutput = strToEl(`
|
const expectedOutput = strToEl(`
|
||||||
<div
|
<div
|
||||||
class="${classes.group} ${classes.itemDisabled}"
|
class="${groupOptions.classNames.group} ${groupOptions.classNames.itemDisabled}"
|
||||||
data-group
|
data-group
|
||||||
data-id="${data.id}"
|
data-id="${data.id}"
|
||||||
data-value="${data.value}"
|
data-value="${data.value}"
|
||||||
role="group"
|
role="group"
|
||||||
aria-disabled="true"
|
aria-disabled="true"
|
||||||
>
|
>
|
||||||
<div class="${classes.groupHeading}">${data.value}</div>
|
<div class="${groupOptions.classNames.groupHeading}">${data.value}</div>
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
const actualOutput = templates.choiceGroup(classes, data);
|
const actualOutput = templates.choiceGroup(groupOptions, data);
|
||||||
|
|
||||||
expectEqualElements(actualOutput, expectedOutput);
|
expectEqualElements(actualOutput, expectedOutput);
|
||||||
});
|
});
|
||||||
|
@ -315,14 +332,14 @@ describe('templates', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('choice', () => {
|
describe('choice', () => {
|
||||||
const classes = {
|
const choiceOptions = createOptionsWithPartialClasses({
|
||||||
item: 'class-1',
|
item: 'class-1',
|
||||||
itemChoice: 'class-2',
|
itemChoice: 'class-2',
|
||||||
itemDisabled: 'class-3',
|
itemDisabled: 'class-3',
|
||||||
itemSelectable: 'class-4',
|
itemSelectable: 'class-4',
|
||||||
placeholder: 'class-5',
|
placeholder: 'class-5',
|
||||||
selectedState: 'class-6',
|
selectedState: 'class-6',
|
||||||
};
|
});
|
||||||
|
|
||||||
const itemSelectText = 'test 6';
|
const itemSelectText = 'test 6';
|
||||||
|
|
||||||
|
@ -344,7 +361,7 @@ describe('templates', () => {
|
||||||
it('returns expected html', () => {
|
it('returns expected html', () => {
|
||||||
const expectedOutput = strToEl(`
|
const expectedOutput = strToEl(`
|
||||||
<div
|
<div
|
||||||
class="${classes.item} ${classes.itemChoice} ${classes.itemSelectable}"
|
class="${choiceOptions.classNames.item} ${choiceOptions.classNames.itemChoice} ${choiceOptions.classNames.itemSelectable}"
|
||||||
data-select-text="${itemSelectText}"
|
data-select-text="${itemSelectText}"
|
||||||
data-choice
|
data-choice
|
||||||
data-id="${data.id}"
|
data-id="${data.id}"
|
||||||
|
@ -356,7 +373,11 @@ describe('templates', () => {
|
||||||
${data.label}
|
${data.label}
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
const actualOutput = templates.choice(classes, data, itemSelectText);
|
const actualOutput = templates.choice(
|
||||||
|
choiceOptions,
|
||||||
|
data,
|
||||||
|
itemSelectText,
|
||||||
|
);
|
||||||
|
|
||||||
expectEqualElements(actualOutput, expectedOutput);
|
expectEqualElements(actualOutput, expectedOutput);
|
||||||
});
|
});
|
||||||
|
@ -373,7 +394,7 @@ describe('templates', () => {
|
||||||
it('returns expected html', () => {
|
it('returns expected html', () => {
|
||||||
const expectedOutput = strToEl(`
|
const expectedOutput = strToEl(`
|
||||||
<div
|
<div
|
||||||
class="${classes.item} ${classes.itemChoice} ${classes.itemDisabled}"
|
class="${choiceOptions.classNames.item} ${choiceOptions.classNames.itemChoice} ${choiceOptions.classNames.itemDisabled}"
|
||||||
data-select-text="${itemSelectText}"
|
data-select-text="${itemSelectText}"
|
||||||
data-choice
|
data-choice
|
||||||
data-id="${data.id}"
|
data-id="${data.id}"
|
||||||
|
@ -386,7 +407,11 @@ describe('templates', () => {
|
||||||
${data.label}
|
${data.label}
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
const actualOutput = templates.choice(classes, data, itemSelectText);
|
const actualOutput = templates.choice(
|
||||||
|
choiceOptions,
|
||||||
|
data,
|
||||||
|
itemSelectText,
|
||||||
|
);
|
||||||
|
|
||||||
expectEqualElements(actualOutput, expectedOutput);
|
expectEqualElements(actualOutput, expectedOutput);
|
||||||
});
|
});
|
||||||
|
@ -403,7 +428,7 @@ describe('templates', () => {
|
||||||
it('returns expected html', () => {
|
it('returns expected html', () => {
|
||||||
const expectedOutput = strToEl(`
|
const expectedOutput = strToEl(`
|
||||||
<div
|
<div
|
||||||
class="${classes.item} ${classes.itemChoice} ${classes.selectedState} ${classes.itemSelectable}"
|
class="${choiceOptions.classNames.item} ${choiceOptions.classNames.itemChoice} ${choiceOptions.classNames.selectedState} ${choiceOptions.classNames.itemSelectable}"
|
||||||
data-select-text="${itemSelectText}"
|
data-select-text="${itemSelectText}"
|
||||||
data-choice
|
data-choice
|
||||||
data-id="${data.id}"
|
data-id="${data.id}"
|
||||||
|
@ -415,7 +440,11 @@ describe('templates', () => {
|
||||||
${data.label}
|
${data.label}
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
const actualOutput = templates.choice(classes, data, itemSelectText);
|
const actualOutput = templates.choice(
|
||||||
|
choiceOptions,
|
||||||
|
data,
|
||||||
|
itemSelectText,
|
||||||
|
);
|
||||||
|
|
||||||
expectEqualElements(actualOutput, expectedOutput);
|
expectEqualElements(actualOutput, expectedOutput);
|
||||||
});
|
});
|
||||||
|
@ -432,7 +461,7 @@ describe('templates', () => {
|
||||||
it('returns expected html', () => {
|
it('returns expected html', () => {
|
||||||
const expectedOutput = strToEl(`
|
const expectedOutput = strToEl(`
|
||||||
<div
|
<div
|
||||||
class="${classes.item} ${classes.itemChoice} ${classes.placeholder} ${classes.itemSelectable}"
|
class="${choiceOptions.classNames.item} ${choiceOptions.classNames.itemChoice} ${choiceOptions.classNames.placeholder} ${choiceOptions.classNames.itemSelectable}"
|
||||||
data-select-text="${itemSelectText}"
|
data-select-text="${itemSelectText}"
|
||||||
data-choice
|
data-choice
|
||||||
data-id="${data.id}"
|
data-id="${data.id}"
|
||||||
|
@ -444,7 +473,11 @@ describe('templates', () => {
|
||||||
${data.label}
|
${data.label}
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
const actualOutput = templates.choice(classes, data, itemSelectText);
|
const actualOutput = templates.choice(
|
||||||
|
choiceOptions,
|
||||||
|
data,
|
||||||
|
itemSelectText,
|
||||||
|
);
|
||||||
|
|
||||||
expectEqualElements(actualOutput, expectedOutput);
|
expectEqualElements(actualOutput, expectedOutput);
|
||||||
});
|
});
|
||||||
|
@ -461,7 +494,7 @@ describe('templates', () => {
|
||||||
it('returns expected html', () => {
|
it('returns expected html', () => {
|
||||||
const expectedOutput = strToEl(`
|
const expectedOutput = strToEl(`
|
||||||
<div
|
<div
|
||||||
class="${classes.item} ${classes.itemChoice} ${classes.itemSelectable}"
|
class="${choiceOptions.classNames.item} ${choiceOptions.classNames.itemChoice} ${choiceOptions.classNames.itemSelectable}"
|
||||||
data-select-text="${itemSelectText}"
|
data-select-text="${itemSelectText}"
|
||||||
data-choice
|
data-choice
|
||||||
data-id="${data.id}"
|
data-id="${data.id}"
|
||||||
|
@ -473,7 +506,11 @@ describe('templates', () => {
|
||||||
${data.label}
|
${data.label}
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
const actualOutput = templates.choice(classes, data, itemSelectText);
|
const actualOutput = templates.choice(
|
||||||
|
choiceOptions,
|
||||||
|
data,
|
||||||
|
itemSelectText,
|
||||||
|
);
|
||||||
|
|
||||||
expectEqualElements(actualOutput, expectedOutput);
|
expectEqualElements(actualOutput, expectedOutput);
|
||||||
});
|
});
|
||||||
|
@ -481,10 +518,10 @@ describe('templates', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('input', () => {
|
describe('input', () => {
|
||||||
const classes = {
|
const inputOptions = createOptionsWithPartialClasses({
|
||||||
input: 'class-1',
|
input: 'class-1',
|
||||||
inputCloned: 'class-2',
|
inputCloned: 'class-2',
|
||||||
};
|
});
|
||||||
|
|
||||||
it('returns expected html', () => {
|
it('returns expected html', () => {
|
||||||
/*
|
/*
|
||||||
|
@ -496,52 +533,52 @@ describe('templates', () => {
|
||||||
<input
|
<input
|
||||||
type="search"
|
type="search"
|
||||||
name="search_terms"
|
name="search_terms"
|
||||||
class="${classes.input} ${classes.inputCloned}"
|
class="${inputOptions.classNames.input} ${inputOptions.classNames.inputCloned}"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
role="textbox"
|
role="textbox"
|
||||||
aria-autocomplete="list"
|
aria-autocomplete="list"
|
||||||
aria-label="test placeholder"
|
aria-label="test placeholder"
|
||||||
>
|
>
|
||||||
`);
|
`);
|
||||||
const actualOutput = templates.input(classes, 'test placeholder');
|
const actualOutput = templates.input(inputOptions, 'test placeholder');
|
||||||
|
|
||||||
expectEqualElements(actualOutput, expectedOutput);
|
expectEqualElements(actualOutput, expectedOutput);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('dropdown', () => {
|
describe('dropdown', () => {
|
||||||
const classes = {
|
const dropdownOptions = createOptionsWithPartialClasses({
|
||||||
list: 'class-1',
|
list: 'class-1',
|
||||||
listDropdown: 'class-2',
|
listDropdown: 'class-2',
|
||||||
};
|
});
|
||||||
|
|
||||||
it('returns expected html', () => {
|
it('returns expected html', () => {
|
||||||
const expectedOutput = strToEl(
|
const expectedOutput = strToEl(
|
||||||
`<div class="${classes.list} ${classes.listDropdown}" aria-expanded="false"></div>`,
|
`<div class="${dropdownOptions.classNames.list} ${dropdownOptions.classNames.listDropdown}" aria-expanded="false"></div>`,
|
||||||
);
|
);
|
||||||
const actualOutput = templates.dropdown(classes);
|
const actualOutput = templates.dropdown(dropdownOptions);
|
||||||
|
|
||||||
expectEqualElements(actualOutput, expectedOutput);
|
expectEqualElements(actualOutput, expectedOutput);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('notice', () => {
|
describe('notice', () => {
|
||||||
const classes = {
|
const noticeOptions = createOptionsWithPartialClasses({
|
||||||
item: 'class-1',
|
item: 'class-1',
|
||||||
itemChoice: 'class-2',
|
itemChoice: 'class-2',
|
||||||
noResults: 'class-3',
|
noResults: 'class-3',
|
||||||
noChoices: 'class-4',
|
noChoices: 'class-4',
|
||||||
};
|
});
|
||||||
|
|
||||||
const label = 'test';
|
const label = 'test';
|
||||||
|
|
||||||
it('returns expected html', () => {
|
it('returns expected html', () => {
|
||||||
const expectedOutput = strToEl(`
|
const expectedOutput = strToEl(`
|
||||||
<div class="${classes.item} ${classes.itemChoice}">
|
<div class="${noticeOptions.classNames.item} ${noticeOptions.classNames.itemChoice}">
|
||||||
${label}
|
${label}
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
const actualOutput = templates.notice(classes, label);
|
const actualOutput = templates.notice(noticeOptions, label);
|
||||||
|
|
||||||
expectEqualElements(actualOutput, expectedOutput);
|
expectEqualElements(actualOutput, expectedOutput);
|
||||||
});
|
});
|
||||||
|
@ -550,11 +587,15 @@ describe('templates', () => {
|
||||||
describe('no results', () => {
|
describe('no results', () => {
|
||||||
it('adds no results classname', () => {
|
it('adds no results classname', () => {
|
||||||
const expectedOutput = strToEl(`
|
const expectedOutput = strToEl(`
|
||||||
<div class="${classes.item} ${classes.itemChoice} ${classes.noResults}">
|
<div class="${noticeOptions.classNames.item} ${noticeOptions.classNames.itemChoice} ${noticeOptions.classNames.noResults}">
|
||||||
${label}
|
${label}
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
const actualOutput = templates.notice(classes, label, 'no-results');
|
const actualOutput = templates.notice(
|
||||||
|
noticeOptions,
|
||||||
|
label,
|
||||||
|
'no-results',
|
||||||
|
);
|
||||||
|
|
||||||
expectEqualElements(actualOutput, expectedOutput);
|
expectEqualElements(actualOutput, expectedOutput);
|
||||||
});
|
});
|
||||||
|
@ -563,11 +604,15 @@ describe('templates', () => {
|
||||||
describe('no choices', () => {
|
describe('no choices', () => {
|
||||||
it('adds no choices classname', () => {
|
it('adds no choices classname', () => {
|
||||||
const expectedOutput = strToEl(`
|
const expectedOutput = strToEl(`
|
||||||
<div class="${classes.item} ${classes.itemChoice} ${classes.noChoices}">
|
<div class="${noticeOptions.classNames.item} ${noticeOptions.classNames.itemChoice} ${noticeOptions.classNames.noChoices}">
|
||||||
${label}
|
${label}
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
const actualOutput = templates.notice(classes, label, 'no-choices');
|
const actualOutput = templates.notice(
|
||||||
|
noticeOptions,
|
||||||
|
label,
|
||||||
|
'no-choices',
|
||||||
|
);
|
||||||
|
|
||||||
expectEqualElements(actualOutput, expectedOutput);
|
expectEqualElements(actualOutput, expectedOutput);
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,14 +4,16 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Choice } from './interfaces/choice';
|
import { Choice } from './interfaces/choice';
|
||||||
import { ClassNames } from './interfaces/class-names';
|
|
||||||
import { Group } from './interfaces/group';
|
import { Group } from './interfaces/group';
|
||||||
import { Item } from './interfaces/item';
|
import { Item } from './interfaces/item';
|
||||||
import { PassedElementType } from './interfaces/passed-element-type';
|
import { PassedElementType } from './interfaces/passed-element-type';
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
type TemplateOptions = Record<'classNames' | 'allowHTML', any>;
|
||||||
|
|
||||||
const templates = {
|
const templates = {
|
||||||
containerOuter(
|
containerOuter(
|
||||||
{ containerOuter }: Pick<ClassNames, 'containerOuter'>,
|
{ classNames: { containerOuter } }: TemplateOptions,
|
||||||
dir: HTMLElement['dir'],
|
dir: HTMLElement['dir'],
|
||||||
isSelectElement: boolean,
|
isSelectElement: boolean,
|
||||||
isSelectOneElement: boolean,
|
isSelectOneElement: boolean,
|
||||||
|
@ -46,19 +48,15 @@ const templates = {
|
||||||
},
|
},
|
||||||
|
|
||||||
containerInner({
|
containerInner({
|
||||||
containerInner,
|
classNames: { containerInner },
|
||||||
}: Pick<ClassNames, 'containerInner'>): HTMLDivElement {
|
}: TemplateOptions): HTMLDivElement {
|
||||||
return Object.assign(document.createElement('div'), {
|
return Object.assign(document.createElement('div'), {
|
||||||
className: containerInner,
|
className: containerInner,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
itemList(
|
itemList(
|
||||||
{
|
{ classNames: { list, listSingle, listItems } }: TemplateOptions,
|
||||||
list,
|
|
||||||
listSingle,
|
|
||||||
listItems,
|
|
||||||
}: Pick<ClassNames, 'list' | 'listSingle' | 'listItems'>,
|
|
||||||
isSelectOneElement: boolean,
|
isSelectOneElement: boolean,
|
||||||
): HTMLDivElement {
|
): HTMLDivElement {
|
||||||
return Object.assign(document.createElement('div'), {
|
return Object.assign(document.createElement('div'), {
|
||||||
|
@ -67,26 +65,26 @@ const templates = {
|
||||||
},
|
},
|
||||||
|
|
||||||
placeholder(
|
placeholder(
|
||||||
{ placeholder }: Pick<ClassNames, 'placeholder'>,
|
{ allowHTML, classNames: { placeholder } }: TemplateOptions,
|
||||||
value: string,
|
value: string,
|
||||||
): HTMLDivElement {
|
): HTMLDivElement {
|
||||||
return Object.assign(document.createElement('div'), {
|
return Object.assign(document.createElement('div'), {
|
||||||
className: placeholder,
|
className: placeholder,
|
||||||
innerHTML: value,
|
[allowHTML ? 'innerHTML' : 'innerText']: value,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
item(
|
item(
|
||||||
{
|
{
|
||||||
|
allowHTML,
|
||||||
|
classNames: {
|
||||||
item,
|
item,
|
||||||
button,
|
button,
|
||||||
highlightedState,
|
highlightedState,
|
||||||
itemSelectable,
|
itemSelectable,
|
||||||
placeholder,
|
placeholder,
|
||||||
}: Pick<
|
},
|
||||||
ClassNames,
|
}: TemplateOptions,
|
||||||
'item' | 'button' | 'highlightedState' | 'itemSelectable' | 'placeholder'
|
|
||||||
>,
|
|
||||||
{
|
{
|
||||||
id,
|
id,
|
||||||
value,
|
value,
|
||||||
|
@ -101,7 +99,7 @@ const templates = {
|
||||||
): HTMLDivElement {
|
): HTMLDivElement {
|
||||||
const div = Object.assign(document.createElement('div'), {
|
const div = Object.assign(document.createElement('div'), {
|
||||||
className: item,
|
className: item,
|
||||||
innerHTML: label,
|
[allowHTML ? 'innerHTML' : 'innerText']: label,
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.assign(div.dataset, {
|
Object.assign(div.dataset, {
|
||||||
|
@ -135,7 +133,7 @@ const templates = {
|
||||||
const removeButton = Object.assign(document.createElement('button'), {
|
const removeButton = Object.assign(document.createElement('button'), {
|
||||||
type: 'button',
|
type: 'button',
|
||||||
className: button,
|
className: button,
|
||||||
innerHTML: REMOVE_ITEM_TEXT,
|
[allowHTML ? 'innerHTML' : 'innerText']: REMOVE_ITEM_TEXT,
|
||||||
});
|
});
|
||||||
removeButton.setAttribute(
|
removeButton.setAttribute(
|
||||||
'aria-label',
|
'aria-label',
|
||||||
|
@ -149,7 +147,7 @@ const templates = {
|
||||||
},
|
},
|
||||||
|
|
||||||
choiceList(
|
choiceList(
|
||||||
{ list }: Pick<ClassNames, 'list'>,
|
{ classNames: { list } }: TemplateOptions,
|
||||||
isSelectOneElement: boolean,
|
isSelectOneElement: boolean,
|
||||||
): HTMLDivElement {
|
): HTMLDivElement {
|
||||||
const div = Object.assign(document.createElement('div'), {
|
const div = Object.assign(document.createElement('div'), {
|
||||||
|
@ -166,10 +164,9 @@ const templates = {
|
||||||
|
|
||||||
choiceGroup(
|
choiceGroup(
|
||||||
{
|
{
|
||||||
group,
|
allowHTML,
|
||||||
groupHeading,
|
classNames: { group, groupHeading, itemDisabled },
|
||||||
itemDisabled,
|
}: TemplateOptions,
|
||||||
}: Pick<ClassNames, 'group' | 'groupHeading' | 'itemDisabled'>,
|
|
||||||
{ id, value, disabled }: Group,
|
{ id, value, disabled }: Group,
|
||||||
): HTMLDivElement {
|
): HTMLDivElement {
|
||||||
const div = Object.assign(document.createElement('div'), {
|
const div = Object.assign(document.createElement('div'), {
|
||||||
|
@ -191,7 +188,7 @@ const templates = {
|
||||||
div.appendChild(
|
div.appendChild(
|
||||||
Object.assign(document.createElement('div'), {
|
Object.assign(document.createElement('div'), {
|
||||||
className: groupHeading,
|
className: groupHeading,
|
||||||
innerHTML: value,
|
[allowHTML ? 'innerHTML' : 'innerText']: value,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -200,21 +197,16 @@ const templates = {
|
||||||
|
|
||||||
choice(
|
choice(
|
||||||
{
|
{
|
||||||
|
allowHTML,
|
||||||
|
classNames: {
|
||||||
item,
|
item,
|
||||||
itemChoice,
|
itemChoice,
|
||||||
itemSelectable,
|
itemSelectable,
|
||||||
selectedState,
|
selectedState,
|
||||||
itemDisabled,
|
itemDisabled,
|
||||||
placeholder,
|
placeholder,
|
||||||
}: Pick<
|
},
|
||||||
ClassNames,
|
}: TemplateOptions,
|
||||||
| 'item'
|
|
||||||
| 'itemChoice'
|
|
||||||
| 'itemSelectable'
|
|
||||||
| 'selectedState'
|
|
||||||
| 'itemDisabled'
|
|
||||||
| 'placeholder'
|
|
||||||
>,
|
|
||||||
{
|
{
|
||||||
id,
|
id,
|
||||||
value,
|
value,
|
||||||
|
@ -229,7 +221,7 @@ const templates = {
|
||||||
): HTMLDivElement {
|
): HTMLDivElement {
|
||||||
const div = Object.assign(document.createElement('div'), {
|
const div = Object.assign(document.createElement('div'), {
|
||||||
id: elementId,
|
id: elementId,
|
||||||
innerHTML: label,
|
[allowHTML ? 'innerHTML' : 'innerText']: label,
|
||||||
className: `${item} ${itemChoice}`,
|
className: `${item} ${itemChoice}`,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -263,7 +255,7 @@ const templates = {
|
||||||
},
|
},
|
||||||
|
|
||||||
input(
|
input(
|
||||||
{ input, inputCloned }: Pick<ClassNames, 'input' | 'inputCloned'>,
|
{ classNames: { input, inputCloned } }: TemplateOptions,
|
||||||
placeholderValue: string,
|
placeholderValue: string,
|
||||||
): HTMLInputElement {
|
): HTMLInputElement {
|
||||||
const inp = Object.assign(document.createElement('input'), {
|
const inp = Object.assign(document.createElement('input'), {
|
||||||
|
@ -283,9 +275,8 @@ const templates = {
|
||||||
},
|
},
|
||||||
|
|
||||||
dropdown({
|
dropdown({
|
||||||
list,
|
classNames: { list, listDropdown },
|
||||||
listDropdown,
|
}: TemplateOptions): HTMLDivElement {
|
||||||
}: Pick<ClassNames, 'list' | 'listDropdown'>): HTMLDivElement {
|
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
|
|
||||||
div.classList.add(list, listDropdown);
|
div.classList.add(list, listDropdown);
|
||||||
|
@ -296,12 +287,10 @@ const templates = {
|
||||||
|
|
||||||
notice(
|
notice(
|
||||||
{
|
{
|
||||||
item,
|
allowHTML,
|
||||||
itemChoice,
|
classNames: { item, itemChoice, noResults, noChoices },
|
||||||
noResults,
|
}: TemplateOptions,
|
||||||
noChoices,
|
innerText: string,
|
||||||
}: Pick<ClassNames, 'item' | 'itemChoice' | 'noResults' | 'noChoices'>,
|
|
||||||
innerHTML: string,
|
|
||||||
type: 'no-choices' | 'no-results' | '' = '',
|
type: 'no-choices' | 'no-results' | '' = '',
|
||||||
): HTMLDivElement {
|
): HTMLDivElement {
|
||||||
const classes = [item, itemChoice];
|
const classes = [item, itemChoice];
|
||||||
|
@ -313,7 +302,7 @@ const templates = {
|
||||||
}
|
}
|
||||||
|
|
||||||
return Object.assign(document.createElement('div'), {
|
return Object.assign(document.createElement('div'), {
|
||||||
innerHTML,
|
[allowHTML ? 'innerHTML' : 'innerText']: innerText,
|
||||||
className: classes.join(' '),
|
className: classes.join(' '),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue