diff --git a/src/components/select/Select.js b/src/components/select/Select.js
index 068b2dd29e..b7f4bbe5ba 100644
--- a/src/components/select/Select.js
+++ b/src/components/select/Select.js
@@ -905,8 +905,8 @@ export default class SelectComponent extends ListComponent {
removeItemButton: this.component.disabled ? false : _.get(this.component, 'removeItemButton', true),
itemSelectText: '',
classNames: {
- containerOuter: 'choices form-group formio-choices',
- containerInner: this.transform('class', 'form-control ui fluid selection dropdown')
+ containerOuter: ['choices', 'form-group', 'formio-choices'],
+ containerInner: this.transform('class', 'form-control ui fluid selection dropdown').split(' '),
},
addItemText: false,
allowHTML: true,
@@ -1097,14 +1097,6 @@ export default class SelectComponent extends ListComponent {
});
}
- if (this.choices && choicesOptions.placeholderValue && this.choices._isSelectOneElement) {
- this.addPlaceholderItem(choicesOptions.placeholderValue);
-
- this.addEventListener(input, 'removeItem', () => {
- this.addPlaceholderItem(choicesOptions.placeholderValue);
- });
- }
-
// Add value options.
this.addValueOptions();
this.setChoicesValue(this.dataValue);
@@ -1208,21 +1200,6 @@ export default class SelectComponent extends ListComponent {
}
}
- addPlaceholderItem(placeholderValue) {
- const items = this.choices._store.activeItems;
- if (!items.length) {
- this.choices._addItem({
- value: '',
- label: placeholderValue,
- choiceId: 0,
- groupId: -1,
- customProperties: null,
- placeholder: true,
- keyCode: null
- });
- }
- }
-
/* eslint-enable max-statements */
update() {
if (this.component.dataSrc === 'custom') {
diff --git a/src/utils/ChoicesWrapper.js b/src/utils/ChoicesWrapper.js
index 9ae4d9829c..6cfc8b7ece 100644
--- a/src/utils/ChoicesWrapper.js
+++ b/src/utils/ChoicesWrapper.js
@@ -1,48 +1,8 @@
-import Choices from '@formio/choices.js';
-
-/**
- * TODO: REMOVE THIS ONCE THE PULL REQUEST HAS BEEN RESOLVED.
- *
- * https://github.com/jshjohnson/Choices/pull/788
- *
- * This is intentionally not part of the extended class, since other components use Choices and need this fix as well.
- * @type {Choices._generatePlaceholderValue}
- * @private
- */
-Choices.prototype._generatePlaceholderValue = function() {
- if (this._isSelectElement && this.passedElement.placeholderOption) {
- const { placeholderOption } = this.passedElement;
- return placeholderOption ? placeholderOption.text : false;
- }
- const { placeholder, placeholderValue } = this.config;
- const {
- element: { dataset },
- } = this.passedElement;
-
- if (placeholder) {
- if (placeholderValue) {
- return placeholderValue;
- }
-
- if (dataset.placeholder) {
- return dataset.placeholder;
- }
- }
+import Choices, { KeyCodeMap } from '@formio/choices.js';
- return false;
-};
-
-export const KEY_CODES = {
- BACK_KEY: 46,
- DELETE_KEY: 8,
+const ExtendedKeyCodeMap = {
+ ...KeyCodeMap,
TAB_KEY: 9,
- ENTER_KEY: 13,
- A_KEY: 65,
- ESC_KEY: 27,
- UP_KEY: 38,
- DOWN_KEY: 40,
- PAGE_UP_KEY: 33,
- PAGE_DOWN_KEY: 34,
};
class ChoicesWrapper extends Choices {
@@ -74,29 +34,13 @@ class ChoicesWrapper extends Choices {
this._wasTap = true;
}
- _handleButtonAction(activeItems, element) {
- if (!this._isSelectOneElement) {
- return super._handleButtonAction(activeItems, element);
- }
-
- if (
- !activeItems ||
- !element ||
- !this.config.removeItems ||
- !this.config.removeItemButton
- ) {
- return;
- }
-
- super._handleButtonAction(activeItems, element);
- }
-
- _onEnterKey(args) {
+ _onEnterKey(...args) {
+ const [event] = args;
// Prevent dropdown form opening when removeItemButton was pressed using 'Enter' on keyboard
- if (args.event.target.className === 'choices__button') {
+ if (event.target.className === 'choices__button') {
this.shouldOpenDropDown = false;
}
- super._onEnterKey(args);
+ super._onEnterKey(...args);
}
_onDirectionKey(...args) {
@@ -116,21 +60,22 @@ class ChoicesWrapper extends Choices {
}, 250);
}
- _onTabKey({ activeItems, hasActiveDropdown }) {
- if (hasActiveDropdown) {
- this._selectHighlightedChoice(activeItems);
+ _onTabKey() {
+ if (this.dropdown.isActive) {
+ this._selectHighlightedChoice();
}
}
_selectHighlightedChoice() {
- const highlightedChoice = this.dropdown.getChild(
+ const highlightedChoice = this.dropdown.element.querySelector(
`.${this.config.classNames.highlightedState}`,
);
if (highlightedChoice) {
const id = highlightedChoice.dataset.id;
- const choice = id && this._store.getChoiceById(id);
+ const choice = id && this._store.getChoiceById(Number(id));
this._addItem({
+ id: choice.id,
value: choice.value,
label: choice.label,
choiceId: choice.id,
@@ -141,84 +86,18 @@ class ChoicesWrapper extends Choices {
});
this._triggerChange(choice.value);
}
-
- event.preventDefault();
}
_onKeyDown(event) {
- if (!this._isSelectOneElement) {
- return super._onKeyDown(event);
- }
-
- const { target, keyCode, ctrlKey, metaKey } = event;
-
- if (
- target !== this.input.element &&
- !this.containerOuter.element.contains(target)
- ) {
- return;
- }
-
- const activeItems = this._store.activeItems;
- const hasFocusedInput = this.input.isFocussed;
- const hasActiveDropdown = this.dropdown.isActive;
- const hasItems = this.itemList.hasChildren;
- const keyString = String.fromCharCode(keyCode);
-
- const {
- BACK_KEY,
- DELETE_KEY,
- TAB_KEY,
- ENTER_KEY,
- A_KEY,
- ESC_KEY,
- UP_KEY,
- DOWN_KEY,
- PAGE_UP_KEY,
- PAGE_DOWN_KEY,
- } = KEY_CODES;
- const hasCtrlDownKeyPressed = ctrlKey || metaKey;
-
- // If a user is typing and the dropdown is not active
- if (!hasActiveDropdown && !this._isTextElement && /[a-zA-Z0-9-_ ]/.test(keyString)) {
- const currentValue = this.input.element.value;
- this.input.element.value = currentValue ? `${currentValue}${keyString}` : keyString;
- this.showDropdown();
- }
-
- // Map keys to key actions
- const keyDownActions = {
- [A_KEY]: this._onAKey,
- [TAB_KEY]: this._onTabKey,
- [ENTER_KEY]: this._onEnterKey,
- [ESC_KEY]: this._onEscapeKey,
- [UP_KEY]: this._onDirectionKey,
- [PAGE_UP_KEY]: this._onDirectionKey,
- [DOWN_KEY]: this._onDirectionKey,
- [PAGE_DOWN_KEY]: this._onDirectionKey,
- [DELETE_KEY]: this._onDeleteKey,
- [BACK_KEY]: this._onDeleteKey,
- };
-
- // If keycode has a function, run it
- if (keyDownActions[keyCode]) {
- keyDownActions[keyCode]({
- event,
- target,
- keyCode,
- metaKey,
- activeItems,
- hasFocusedInput,
- hasActiveDropdown,
- hasItems,
- hasCtrlDownKeyPressed,
- });
- }
+ const keyCode = event.keyCode;
+ return this._isSelectOneElement && keyCode === ExtendedKeyCodeMap.TAB_KEY
+ ? this._onTabKey()
+ : super._onKeyDown(event);
}
- onSelectValue({ event, activeItems, hasActiveDropdown }) {
+ onSelectValue(event, hasActiveDropdown) {
if (hasActiveDropdown) {
- this._selectHighlightedChoice(activeItems);
+ this._selectHighlightedChoice();
}
else if (this._isSelectOneElement) {
this.showDropdown();
@@ -227,12 +106,14 @@ class ChoicesWrapper extends Choices {
}
showDropdown(...args) {
- if (!this.shouldOpenDropDown) {
- this.shouldOpenDropDown = true;
- return;
- }
+ setTimeout(() => {
+ if (!this.shouldOpenDropDown) {
+ this.shouldOpenDropDown = true;
+ return;
+ }
- super.showDropdown(...args);
+ super.showDropdown(...args);
+ }, 0);
}
hideDropdown(...args) {
@@ -242,13 +123,6 @@ class ChoicesWrapper extends Choices {
super.hideDropdown(...args);
}
-
- _onBlur(...args) {
- if (this._isScrollingOnIe) {
- return;
- }
- super._onBlur(...args);
- }
}
export default ChoicesWrapper;
diff --git a/test/unit/Radio.unit.js b/test/unit/Radio.unit.js
index a4fd032280..e37800eddd 100644
--- a/test/unit/Radio.unit.js
+++ b/test/unit/Radio.unit.js
@@ -343,9 +343,7 @@ describe('Radio Component', () => {
}, 350);
}).catch(done);
});
-});
-describe('Radio Component', () => {
it('should have red asterisk left hand side to the options labels if component is required and label is hidden', () => {
return Harness.testCreate(RadioComponent, comp7).then(component => {
const options = component.element.querySelectorAll('.form-check-label');
diff --git a/test/unit/Select.unit.js b/test/unit/Select.unit.js
index 40b7d4eb18..2266cdf732 100644
--- a/test/unit/Select.unit.js
+++ b/test/unit/Select.unit.js
@@ -41,834 +41,703 @@ import {
comp28
} from './fixtures/select';
+global.requestAnimationFrame = cb => cb();
+window.matchMedia = window.matchMedia || function() {
+ return {
+ matches : false,
+ addListener : function() {},
+ removeListener: function() {}
+ };
+};
+window.scrollTo = () => {};
+
+const timeout = (delay) => new Promise((resolve) => setTimeout(resolve, delay));
+const mockDebounce = (timeout, cb) => {
+ const originalDebounce = _.debounce;
+
+ _.debounce = (fn, wait, opts) => {
+ cb?.(wait);
+ return originalDebounce(fn, timeout, opts);
+ }
+
+ return () => {
+ _.debounce = originalDebounce;
+ }
+};
+const mockMakeRequest = (func) => {
+ const originalMakeRequest = Formio.makeRequest;
+ Formio.makeRequest = func;
+
+ return () => {
+ Formio.makeRequest = originalMakeRequest;
+ }
+}
+
+
// eslint-disable-next-line max-statements
describe('Select Component', () => {
- it('should not stringify select option value', function(done) {
- Harness.testCreate(SelectComponent, comp6).then((component) => {
- component.setValue({ value:'a', label:'A' });
- setTimeout(()=> {
- assert.equal(component.choices._currentState.items[0].value.value, 'a');
- assert.equal(typeof component.choices._currentState.items[0].value , 'object');
- assert.equal(component.dataValue.value, 'a');
- assert.equal(typeof component.dataValue , 'object');
- done();
- }, 200);
- });
+ it('Should not stringify select option value', async () => {
+ const component = await Harness.testCreate(SelectComponent, comp6);
+ await component.itemsLoaded;
+ component.setValue({ value:'a', label:'A' });
+
+ await component.itemsLoaded;
+ assert.equal(typeof component.choices._store.items[0].value , 'object');
+ assert.equal(component.choices._store.items[0].value.value, 'a');
+ assert.equal(component.dataValue.value, 'a');
+ assert.equal(typeof component.dataValue , 'object');
});
- it('should return string value for different value types', function(done) {
- Harness.testCreate(SelectComponent, comp4).then((component) => {
- const stringValue = component.asString(true);
- const stringValue1 = component.asString(11);
- const stringValue2 = component.asString('test');
- const stringValue3 = component.asString(12);
- const stringValue4 = component.asString([1, 2, 3]);
- assert.equal(stringValue, 'true');
- assert.equal(stringValue1, '11');
- assert.equal(stringValue2, 'test');
- assert.equal(stringValue3, '1.2');
- assert.equal(stringValue4, '1,2,3');
- done();
- });
+ it('Should return string value for different value types', async () => {
+ const component = await Harness.testCreate(SelectComponent, comp4);
+ const stringValue = component.asString(true);
+ const stringValue1 = component.asString(11);
+ const stringValue2 = component.asString('test');
+ const stringValue3 = component.asString(12);
+ const stringValue4 = component.asString([1, 2, 3]);
+ assert.equal(stringValue, 'true');
+ assert.equal(stringValue1, '11');
+ assert.equal(stringValue2, 'test');
+ assert.equal(stringValue3, '1.2');
+ assert.equal(stringValue4, '1,2,3');
});
- it('should return string value if dataSrc set as custom', function(done) {
- Harness.testCreate(SelectComponent, comp27).then((component) => {
- const stringValue = component.asString('California');
- assert.equal(stringValue, 'California');
- done();
- });
- })
+ it('Should return string value if dataSrc set as custom', async () => {
+ const component = await Harness.testCreate(SelectComponent, comp27);
+ const stringValue = component.asString('California');
+ assert.equal(stringValue, 'California');
+ });
- it('Should return plain text when csv option is provided', () => {
- return Harness.testCreate(SelectComponent, comp1).then((component) => {
- assert.equal(component.getView('red', { csv:true }), 'Red');
- });
+ it('Should return plain text when csv option is provided', async () => {
+ const component = await Harness.testCreate(SelectComponent, comp1);
+ assert.equal(component.getView('red', { csv: true }), 'Red');
});
- it('should correctly determine storage type when dataType is auto', function(done) {
- Harness.testCreate(SelectComponent, comp4).then((component) => {
- const value = component.normalizeSingleValue('true');
- const value1 = component.normalizeSingleValue('11');
- const value2 = component.normalizeSingleValue('test');
- const value3 = component.normalizeSingleValue('11test11test');
- const value4 = component.normalizeSingleValue('test11');
- const value5 = component.normalizeSingleValue('0');
- const value6 = component.normalizeSingleValue('');
- assert.equal(typeof value, 'boolean');
- assert.equal(typeof value1, 'number');
- assert.equal(typeof value2, 'string');
- assert.equal(typeof value3, 'string');
- assert.equal(typeof value4, 'string');
- assert.equal(typeof value5, 'number');
- assert.equal(typeof value6, 'string');
- done();
- });
+ it('Should correctly determine storage type when dataType is auto', async () => {
+ const component = await Harness.testCreate(SelectComponent, comp4);
+ const value = component.normalizeSingleValue('true');
+ const value1 = component.normalizeSingleValue('11');
+ const value2 = component.normalizeSingleValue('test');
+ const value3 = component.normalizeSingleValue('11test11test');
+ const value4 = component.normalizeSingleValue('test11');
+ const value5 = component.normalizeSingleValue('0');
+ const value6 = component.normalizeSingleValue('');
+ assert.equal(typeof value, 'boolean');
+ assert.equal(typeof value1, 'number');
+ assert.equal(typeof value2, 'string');
+ assert.equal(typeof value3, 'string');
+ assert.equal(typeof value4, 'string');
+ assert.equal(typeof value5, 'number');
+ assert.equal(typeof value6, 'string');
});
- it('should not stringify default empty values', function(done) {
- Harness.testCreate(SelectComponent, comp4).then((component) => {
- const value = component.normalizeSingleValue({});
- const value1 = component.normalizeSingleValue([]);
- assert.equal(typeof value, 'object');
- assert.equal(typeof value1, 'object');
- done();
- });
+ it('Should not stringify default empty values', async () => {
+ const component = await Harness.testCreate(SelectComponent, comp4);
+ const value = component.normalizeSingleValue({});
+ const value1 = component.normalizeSingleValue([]);
+ assert.deepEqual(value, {});
+ assert.deepEqual(value1, []);
});
- it('should not change value letter case', function(done) {
- Harness.testCreate(SelectComponent, comp4).then((component) => {
- const value = component.normalizeSingleValue('data.textArea');
- const value1 = component.normalizeSingleValue('ECMAScript');
- const value2 = component.normalizeSingleValue('JS');
- assert.equal(value, 'data.textArea');
- assert.equal(value1, 'ECMAScript');
- assert.equal(value2, 'JS');
- done();
- });
+ it('Should not change value letter case', async () => {
+ const component = await Harness.testCreate(SelectComponent, comp4);
+ const value = component.normalizeSingleValue('data.textArea');
+ const value1 = component.normalizeSingleValue('ECMAScript');
+ const value2 = component.normalizeSingleValue('JS');
+ assert.equal(value, 'data.textArea');
+ assert.equal(value1, 'ECMAScript');
+ assert.equal(value2, 'JS');
});
- it('should define boolean value', function(done) {
- Harness.testCreate(SelectComponent, comp4).then((component) => {
- const value = component.normalizeSingleValue('TRUE');
- const value1 = component.normalizeSingleValue('False');
- const value2 = component.normalizeSingleValue('true');
- assert.equal(value, true);
- assert.equal(value1, false);
- assert.equal(value2, true);
- done();
- });
+ it('Should define boolean value', async () => {
+ const component = await Harness.testCreate(SelectComponent, comp4);
+ const value = component.normalizeSingleValue('TRUE');
+ const value1 = component.normalizeSingleValue('False');
+ const value2 = component.normalizeSingleValue('true');
+ assert.equal(value, true);
+ assert.equal(value1, false);
+ assert.equal(value2, true);
});
- it('1/2 should not display empty choice options if property value is not defined', function(done) {
- Harness.testCreate(SelectComponent, comp5).then((component) => {
- component.setItems([{
- 'label': '111',
- 'value': '111'
- }, {
- 'label': '222',
- 'value': '222'
- }, {
- 'label': '333',
- 'value': '333'
- }], false);
- assert.equal(component.selectOptions.length, 0);
- done();
- });
+ it('Should not display empty choice options if property value is not defined', async () => {
+ const component = await Harness.testCreate(SelectComponent, comp5);
+ component.setItems([{
+ 'label': '111',
+ 'value': '111'
+ }, {
+ 'label': '222',
+ 'value': '222'
+ }, {
+ 'label': '333',
+ 'value': '333'
+ }], false);
+ assert.equal(component.selectOptions.length, 0);
});
- it('2/2 should display choice option if property value is set', function(done) {
+ it('Should display choice option if property value is set', async () => {
comp5.template = '{{ item.label }}';
- Harness.testCreate(SelectComponent, comp5).then((component) => {
- component.setItems([{
- 'label': '111',
- 'value': '111'
- }, {
- 'label': '222',
- 'value': '222'
- }, {
- 'label': '333',
- 'value': '333'
- }], false);
- assert.equal(component.selectOptions.length, 3);
- done();
- });
+ const component = await Harness.testCreate(SelectComponent, comp5);
+ component.setItems([{
+ 'label': '111',
+ 'value': '111'
+ }, {
+ 'label': '222',
+ 'value': '222'
+ }, {
+ 'label': '333',
+ 'value': '333'
+ }], false);
+ assert.equal(component.selectOptions.length, 3);
});
- it('should have only unique dropdown options', function(done) {
+ it('Should have only unique dropdown options', async () => {
comp5.template = '{{ item.label }}';
comp5.uniqueOptions = true;
- Harness.testCreate(SelectComponent, comp5).then((component) => {
- component.setItems([{
- 'label': 'Label 1',
- 'value': 'value1'
- }, {
- 'label': 'Label 2',
- 'value': 'value2'
- }, {
- 'label': 'Label 3',
- 'value': 'value3'
- }, {
- 'label': 'Label 4',
- 'value': 'value3'
- }], false);
-
- assert.equal(component.selectOptions.length, 3);
- done();
- });
+ const component = await Harness.testCreate(SelectComponent, comp5);
+ component.setItems([{
+ 'label': 'Label 1',
+ 'value': 'value1'
+ }, {
+ 'label': 'Label 2',
+ 'value': 'value2'
+ }, {
+ 'label': 'Label 3',
+ 'value': 'value3'
+ }, {
+ 'label': 'Label 4',
+ 'value': 'value3'
+ }], false);
+ assert.equal(component.selectOptions.length, 3);
});
- it('should format unlisted values', function(done) {
+ it('Should format unlisted values', async () => {
comp5.template = '{{ item.label }}';
- Harness.testCreate(SelectComponent, comp5).then((component) => {
- const formattedValue1 = component.getView('Unlisted value');
- const formattedValue2 = component.getView(0);
-
- assert.equal(formattedValue1, 'Unlisted value');
- assert.equal(formattedValue2, '0');
- done();
- });
- });
-
- it('should set multiple selected values not repeating them', function(done) {
- Harness.testCreate(SelectComponent, multiSelect).then((component) => {
- component.setItems(multiSelectOptions, false);
- component.setChoicesValue(['Cheers']);
- component.setChoicesValue(['Cheers', 'Cyberdyne Systems'], 1);
- component.setChoicesValue(['Cheers', 'Cyberdyne Systems', 'Massive Dynamic'], 2);
- const choices = component.element.querySelector('.choices__list--multiple').children;
- assert.equal(choices.length, 3);
- done();
- });
+ const component = await Harness.testCreate(SelectComponent, comp5);
+ assert.equal(component.getView('Unlisted value'), 'Unlisted value');
+ assert.equal(component.getView(0), '0');
});
- it('should not show selected values in dropdown when searching', function(done) {
- Harness.testCreate(SelectComponent, multiSelect).then((component) => {
- component.setItems(multiSelectOptions, false);
- component.setChoicesValue(['Cheers']);
- component.setChoicesValue(['Cheers', 'Cyberdyne Systems'], 1);
- component.setItems([], true);
- const itemsInDropdown = component.element.querySelectorAll('.choices__item--choice');
- const choices = component.element.querySelector('.choices__list--multiple').children;
- assert.equal(choices.length, 2);
- assert.equal(itemsInDropdown.length, 1);
- done();
- });
+ it('Should set multiple selected values not repeating them', async () => {
+ const component = await Harness.testCreate(SelectComponent, multiSelect);
+ component.setItems(multiSelectOptions, false);
+ component.setChoicesValue(['Cheers']);
+ component.setChoicesValue(['Cheers', 'Cyberdyne Systems'], 1);
+ component.setChoicesValue(['Cheers', 'Cyberdyne Systems', 'Massive Dynamic'], 2);
+ const choices = component.element.querySelector('.choices__list--multiple').children;
+ assert.equal(choices.length, 3);
});
- it('Should build a Select component', () => {
- return Harness.testCreate(SelectComponent, comp1).then((component) => {
- Harness.testElements(component, 'select', 1);
- });
+ it('Should not show selected values in dropdown when searching', async () => {
+ const component = await Harness.testCreate(SelectComponent, multiSelect);
+ component.setItems(multiSelectOptions, false);
+ component.setChoicesValue(['Cheers']);
+ component.setChoicesValue(['Cheers', 'Cyberdyne Systems'], 1);
+ component.setItems([], true);
+ const itemsInDropdown = component.element.querySelectorAll('.choices__item--choice');
+ const choices = component.element.querySelector('.choices__list--multiple').children;
+ assert.equal(choices.length, 2);
+ assert.equal(itemsInDropdown.length, 1);
});
- it('Should preserve the tabindex', () => {
- return Harness.testCreate(SelectComponent, comp2).then((component) => {
- const element = component.element.getElementsByClassName('choices__list choices__list--single')[0];
- Harness.testElementAttribute(element, 'tabindex', '10');
- });
+ it('Should build a Select component', async () => {
+ const component = await Harness.testCreate(SelectComponent, comp1);
+ Harness.testElements(component, 'select', 1);
});
- it('Should default to 0 when tabindex is not specified', () => {
- return Harness.testCreate(SelectComponent, comp1).then((component) => {
- const element = component.element.getElementsByClassName('choices__list choices__list--single')[0];
- Harness.testElementAttribute(element, 'tabindex', '0');
- });
+ it('Should preserve the tabindex', async () => {
+ const component = await Harness.testCreate(SelectComponent, comp2);
+ Harness.testElementAttribute(component.focusableElement, 'tabindex', '10');
});
- it('Should allow to override threshold option of fuzzy search', () => {
- try {
- const c1 = Object.assign(cloneDeep(comp1), { selectThreshold: 0.2 });
- const c2 = Object.assign(cloneDeep(comp1), { selectThreshold: 0.4 });
- const c3 = Object.assign(cloneDeep(comp1), { selectThreshold: 0.8 });
- const comps = [
- Harness.testCreate(SelectComponent, c1),
- Harness.testCreate(SelectComponent, c2),
- Harness.testCreate(SelectComponent, c3),
- ];
-
- return Promise
- .all(comps)
- .then(([a, b, c]) => {
- expect(a.choices.config.fuseOptions.threshold).to.equal(0.2);
- expect(b.choices.config.fuseOptions.threshold).to.equal(0.4);
- expect(c.choices.config.fuseOptions.threshold).to.equal(0.8);
- });
- }
- catch (error) {
- return Promise.reject(error);
- }
+ it('Should default to 0 when tabindex is not specified', async () => {
+ const component = await Harness.testCreate(SelectComponent, comp1);
+ Harness.testElementAttribute(component.focusableElement, 'tabindex', '0');
});
- it('should set component value', () => {
- return Harness.testCreate(SelectComponent, comp1).then((component) => {
- assert.deepEqual(component.dataValue, '');
- component.setValue('red');
- assert.equal(component.dataValue, 'red');
- });
+ it('Should allow to override threshold option of fuzzy search', async () => {
+ const c1 = Object.assign(cloneDeep(comp1), { selectThreshold: 0.2 });
+ const c2 = Object.assign(cloneDeep(comp1), { selectThreshold: 0.4 });
+ const c3 = Object.assign(cloneDeep(comp1), { selectThreshold: 0.8 });
+
+ const [a, b, c] = await Promise.all([
+ Harness.testCreate(SelectComponent, c1),
+ Harness.testCreate(SelectComponent, c2),
+ Harness.testCreate(SelectComponent, c3),
+ ]);
+ expect(a.choices.config.fuseOptions.threshold).to.equal(0.2);
+ expect(b.choices.config.fuseOptions.threshold).to.equal(0.4);
+ expect(c.choices.config.fuseOptions.threshold).to.equal(0.8);
});
- it('should remove selected item', () => {
- return Harness.testCreate(SelectComponent, comp1).then((component) => {
- assert.deepEqual(component.dataValue, '');
- component.setValue('red');
- assert.equal(component.dataValue, 'red');
-
- const element = component.element.getElementsByClassName('choices__button')[0];
- component.choices._handleButtonAction(component.choices._store.activeItems, element);
+ it('Should set component value', async () => {
+ const component = await Harness.testCreate(SelectComponent, comp1);
+ await component.itemsLoaded;
+ assert.equal(component.dataValue, '');
+ component.setValue('red');
- assert.equal(component.dataValue, '');
- });
+ await component.itemsLoaded;
+ assert.equal(component.dataValue, 'red');
+ assert.equal(component.choices._store.items[0]?.value, 'red');
});
- it('should open dropdown after item has been removed', () => {
- global.requestAnimationFrame = cb => cb();
- window.matchMedia = window.matchMedia || function() {
- return {
- matches : false,
- addListener : function() {},
- removeListener: function() {}
- };
- };
-
- return Harness.testCreate(SelectComponent, comp1).then((component) => {
- component.setValue('red');
-
- const element = component.element.getElementsByClassName('choices__button')[0];
- component.choices._handleButtonAction(component.choices._store.activeItems, element);
-
- component.choices.showDropdown(true);
-
- assert.equal(component.choices.dropdown.isActive, true);
- });
+ it('Should remove selected item', async () => {
+ const component = await Harness.testCreate(SelectComponent, comp1);
+ await component.itemsLoaded;
+ assert.deepEqual(component.dataValue, '');
+ component.setValue('red');
+
+ await component.itemsLoaded;
+ assert.equal(component.dataValue, 'red');
+ const element = component.element.querySelector('.choices__button');
+ component.choices._handleButtonAction(element);
+ assert.equal(component.dataValue, '');
});
- it('should keep dropdown closed after item has been removed by keypress', () => {
- return Harness.testCreate(SelectComponent, comp1).then((component) => {
- component.setValue('red');
-
- const element = component.element.querySelector('.choices__button');
- const ke = new KeyboardEvent('keydown', {
- bubbles: true, cancelable: true, keyCode: 13
- });
-
- element.dispatchEvent(ke);
-
- assert.equal(component.dataValue, '');
- assert.equal(component.choices.dropdown.isActive, false);
+ it('Should keep dropdown closed after item has been removed by keypress', async () => {
+ const component = await Harness.testCreate(SelectComponent, comp1);
+ await component.itemsLoaded;
+ component.setValue('red');
+
+ await component.itemsLoaded;
+ assert.equal(component.dataValue, 'red');
+ assert.equal(component.choices._store.items.length, 1);
+ const element = component.element.querySelector('.choices__button');
+ const event = new KeyboardEvent('keydown', {
+ bubbles: true, cancelable: true, keyCode: 13
});
- });
+ element.dispatchEvent(event);
- it('Should render and set values in selects with different widget types', (done) => {
- const form = _.cloneDeep(comp7);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const selectHTML = form.getComponent('selectHtml');
- const selectChoices = form.getComponent('selectChoices');
- assert.equal(!!selectHTML.choices, false);
- assert.equal(!!selectChoices.choices, true);
-
- setTimeout(() => {
- assert.equal(selectChoices.element.querySelectorAll('.choices__item--choice').length, 3);
- const value = 'b';
- selectHTML.setValue(value);
- selectChoices.setValue(value);
-
- setTimeout(() => {
- assert.equal(selectHTML.dataValue, value);
- assert.equal(selectChoices.dataValue, value);
- assert.equal(selectHTML.getValue(), value);
- assert.equal(selectChoices.getValue(), value);
-
- done();
- }, 200);
- }, 200);
- }).catch(done);
+ await timeout(0);
+ assert.equal(component.choices._store.items.length, 0);
+ assert.equal(component.dataValue, '');
+ assert.equal(component.choices.dropdown.isActive, false);
});
- it('Should clear select value when "clear value on refresh options" and "refresh options on" is enable and number component is changed ', (done) => {
- const form = _.cloneDeep(comp8);
+ it('Should render and set values in selects with different widget types', async () => {
const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- const numberComp = form.getComponent('number');
- const value = 'b';
- select.setValue(value);
-
- setTimeout(() => {
- assert.equal(select.dataValue, value);
- assert.equal(select.getValue(), value);
- const numberInput = numberComp.refs.input[0];
- const numberValue = 5;
- const inputEvent = new Event('input');
- numberInput.value = numberValue;
- numberInput.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- assert.equal(numberComp.dataValue, numberValue);
- assert.equal(numberComp.getValue(), numberValue);
- assert.equal(select.dataValue, '');
- assert.equal(select.getValue(), '');
-
- done();
- }, 400);
- }, 200);
- }).catch(done);
+ const form = await Formio.createForm(element, _.cloneDeep(comp7));
+ const selectHtml = form.getComponent('selectHtml');
+ const selectChoices = form.getComponent('selectChoices');
+ assert.equal(!!selectHtml.choices, false);
+ assert.equal(!!selectChoices.choices, true);
+
+ await Promise.all([selectHtml.itemsLoaded, selectChoices.itemsLoaded]);
+ await timeout(0);
+ assert.equal(selectHtml.selectOptions.length, 3);
+ assert.equal(selectChoices.selectOptions.length, 3);
+ assert.equal(selectChoices.choices._store.choices.length, 3);
+ assert.equal(selectChoices.choices._store.items.length, 0);
+ assert.equal(selectChoices.element.querySelectorAll('.choices__item--choice').length, 3);
+ const value = 'b';
+ selectHtml.setValue(value);
+ selectChoices.setValue(value);
+
+ await Promise.all([selectHtml.itemsLoaded, selectChoices.itemsLoaded]);
+ assert.equal(selectHtml.dataValue, value);
+ assert.equal(selectChoices.dataValue, value);
+ assert.equal(selectChoices.choices._store.items.length, 1);
+ assert.equal(selectHtml.getValue(), value);
+ assert.equal(selectChoices.getValue(), value);
});
- it('Should update select items when "refresh options on" is enable and number component is changed', (done) => {
- const form = _.cloneDeep(comp9);
- const element = document.createElement('div');
- const originalMakeRequest = Formio.makeRequest;
- Formio.makeRequest = function(formio, type, url) {
- return new Promise(resolve => {
- let values =[{ name: 'Ivan' }, { name: 'Mike' }];
-
- if (url.endsWith('5')) {
- values = [{ name: 'Kate' }, { name: 'Ann' }, { name: 'Lana' }];
- }
- resolve(values);
- });
- };
+ it('Should clear select value when "clear value on refresh options" and "refresh options on" is enable and number component is changed', async () => {
+ const restoreDebounce = mockDebounce(0);
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- const numberComp = form.getComponent('number');
- setTimeout(() => {
- assert.equal(select.selectOptions.length, 2);
- assert.deepEqual(select.selectOptions[0].value, { name: 'Ivan' });
-
- const numberValue = 5;
- const inputEvent = new Event('input');
- const numberInput = numberComp.refs.input[0];
-
- numberInput.value = numberValue;
- numberInput.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- assert.equal(numberComp.dataValue, numberValue);
- assert.equal(numberComp.getValue(), numberValue);
- assert.equal(select.selectOptions.length, 3);
- assert.deepEqual(select.selectOptions[0].value, { name: 'Kate' });
-
- Formio.makeRequest = originalMakeRequest;
- done();
- }, 500);
- }, 200);
- }).catch(done);
+ const element = document.createElement('div');
+ const form = await Formio.createForm(element, _.cloneDeep(comp8));
+ const select = form.getComponent('select');
+ const numberComp = form.getComponent('number');
+
+ await select.itemsLoaded;
+ const value = 'b';
+ select.setValue(value);
+
+ // timeout(0) need to complete triggerChange
+ await Promise.all([select.itemsLoaded, timeout(0)]);
+ assert.equal(select.dataValue, value);
+ assert.equal(select.getValue(), value);
+
+ const numberInput = numberComp.refs.input[0];
+ const numberValue = 5;
+ const inputEvent = new Event('input');
+ numberInput.value = numberValue;
+ numberInput.dispatchEvent(inputEvent);
+
+ await timeout(50);
+ assert.equal(numberComp.dataValue, numberValue);
+ assert.equal(numberComp.getValue(), numberValue);
+ assert.equal(select.dataValue, '');
+ assert.equal(select.getValue(), '');
+ assert.equal(select.choices._store.items.length, 0);
+
+ restoreDebounce();
});
- it('Should update select items when "refresh options on blur" is enable and number component is changed', (done) => {
- const form = _.cloneDeep(comp9);
- form.components[1].refreshOn = null;
- form.components[1].refreshOnBlur = 'number';
+ it('Should update select items when "refresh options on" is enable and number component is changed', async () => {
+ const restoreDebounce = mockDebounce(0);
+ const restoreMakeRequest = mockMakeRequest((formio, type, url) => new Promise((resolve) => {
+ let values = [{ name: 'Ivan' }, { name: 'Mike' }];
+ if (url.endsWith('5')) {
+ values = [{ name: 'Kate' }, { name: 'Ann' }, { name: 'Lana' }];
+ }
+ resolve(values);
+ }));
const element = document.createElement('div');
- const originalMakeRequest = Formio.makeRequest;
- Formio.makeRequest = function(formio, type, url) {
- return new Promise(resolve => {
- let values =[{ name: 'Ivan' }, { name: 'Mike' }];
-
- if (url.endsWith('5')) {
- values = [{ name: 'Kate' }, { name: 'Ann' }, { name: 'Lana' }];
- }
- resolve(values);
- });
- };
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- const numberComp = form.getComponent('number');
- setTimeout(() => {
- assert.equal(select.selectOptions.length, 2);
- assert.deepEqual(select.selectOptions[0].value, { name: 'Ivan' });
-
- const numberValue = 5;
- const inputEvent = new Event('input');
- const focusEvent = new Event('focus');
- const blurEvent = new Event('blur');
- const numberInput = numberComp.refs.input[0];
- numberInput.dispatchEvent(focusEvent);
- numberInput.value = numberValue;
- numberInput.dispatchEvent(inputEvent);
- numberInput.dispatchEvent(blurEvent);
-
- setTimeout(() => {
- assert.equal(numberComp.dataValue, numberValue);
- assert.equal(numberComp.getValue(), numberValue);
- assert.equal(select.selectOptions.length, 3);
- assert.deepEqual(select.selectOptions[0].value, { name: 'Kate' });
-
- Formio.makeRequest = originalMakeRequest;
- done();
- }, 500);
- }, 200);
- }).catch(done);
+ const form = await Formio.createForm(element, _.cloneDeep(comp9));
+ const select = form.getComponent('select');
+ const numberComp = form.getComponent('number');
+
+ await select.itemsLoaded;
+ assert.equal(select.selectOptions.length, 2);
+ assert.deepEqual(select.selectOptions[0].value, { name: 'Ivan' });
+
+ const numberValue = 5;
+ const inputEvent = new Event('input');
+ const numberInput = numberComp.refs.input[0];
+ numberInput.value = numberValue;
+ numberInput.dispatchEvent(inputEvent);
+
+ await timeout(50);
+ assert.equal(numberComp.dataValue, numberValue);
+ assert.equal(numberComp.getValue(), numberValue);
+ assert.equal(select.selectOptions.length, 3);
+ assert.deepEqual(select.selectOptions[0].value, { name: 'Kate' });
+
+ restoreDebounce();
+ restoreMakeRequest();
});
- it('Should be able to search if static search is enable', (done) => {
- const form = _.cloneDeep(comp10);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
-
- const searchField = select.element.querySelector('.choices__input.choices__input--cloned');
- const focusEvent = new Event('focus');
- searchField.dispatchEvent(focusEvent);
+ it('Should update select items when "refresh options on blur" is enable and number component is changed', async () => {
+ const restoreDebounce = mockDebounce(0);
+ const restoreMakeRequest = mockMakeRequest((formio, type, url) => new Promise((resolve) => {
+ let values =[{ name: 'Ivan' }, { name: 'Mike' }];
+ if (url.endsWith('5')) {
+ values = [{ name: 'Kate' }, { name: 'Ann' }, { name: 'Lana' }];
+ }
+ resolve(values);
+ }));
- setTimeout(() => {
- assert.equal(select.choices.dropdown.isActive, true);
- const items = select.choices.choiceList.element.children;
- assert.equal(items.length, 5);
+ const formSchema = _.cloneDeep(comp9);
+ formSchema.components[1].refreshOn = null;
+ formSchema.components[1].refreshOnBlur = 'number';
- const keyupEvent = new Event('keyup');
- const searchField = select.element.querySelector('.choices__input.choices__input--cloned');
- searchField.value = 'par';
- searchField.dispatchEvent(keyupEvent);
-
- setTimeout(() => {
- const items = select.choices.choiceList.element.children;
- assert.equal(items.length, 1);
-
- done();
- }, 400);
- }, 200);
- }).catch(done);
+ const element = document.createElement('div');
+ const form = await Formio.createForm(element, formSchema);
+ const select = form.getComponent('select');
+ const numberComp = form.getComponent('number');
+
+ await select.itemsLoaded;
+ assert.equal(select.selectOptions.length, 2);
+ assert.deepEqual(select.selectOptions[0].value, { name: 'Ivan' });
+
+ const numberValue = 5;
+ const inputEvent = new Event('input');
+ const focusEvent = new Event('focus');
+ const blurEvent = new Event('blur');
+ const numberInput = numberComp.refs.input[0];
+ numberInput.dispatchEvent(focusEvent);
+ numberInput.value = numberValue;
+ numberInput.dispatchEvent(inputEvent);
+ numberInput.dispatchEvent(blurEvent);
+
+ await timeout(50);
+ assert.equal(numberComp.dataValue, numberValue);
+ assert.equal(numberComp.getValue(), numberValue);
+ assert.equal(select.selectOptions.length, 3);
+ assert.deepEqual(select.selectOptions[0].value, { name: 'Kate' });
+
+ restoreDebounce();
+ restoreMakeRequest();
});
- it('Should not be able to search if static search is disable', (done) => {
- const form = _.cloneDeep(comp10);
- form.components[0].searchEnabled = false;
+ it('Should be able to search if static search is enable', async () => {
const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- const searchField = select.element.querySelector('.choices__input.choices__input--cloned');
- assert.equal(searchField, null);
-
- done();
- }).catch(done);
+ const form = await Formio.createForm(element, _.cloneDeep(comp10));
+ const select = form.getComponent('select');
+
+ await select.itemsLoaded;
+ const searchField = select.element.querySelector('.choices__input.choices__input--cloned');
+ const focusEvent = new Event('focus');
+ searchField.dispatchEvent(focusEvent);
+
+ await timeout(0);
+ await select.itemsLoaded;
+ assert.equal(select.choices.dropdown.isActive, true);
+ let items = select.choices.choiceList.element.children;
+ assert.equal(items.length, 5);
+
+ const event = new Event('input');
+ searchField.value = 'par';
+ searchField.dispatchEvent(event);
+ items = select.choices.choiceList.element.children;
+ assert.equal(items.length, 1);
});
- it('Should save correct value if value property and item template property are different', (done) => {
- const form = _.cloneDeep(comp9);
- form.components[1].refreshOn = null;
- form.components[1].valueProperty = 'age';
- form.components[1].lazyLoad = true;
-
+ it('Should not be able to search if static search is disable', async () => {
+ const formSchema = _.cloneDeep(comp10);
+ formSchema.components[0].searchEnabled = false;
const element = document.createElement('div');
- const originalMakeRequest = Formio.makeRequest;
-
- Formio.makeRequest = function() {
- return new Promise(resolve => {
- const values =[{ name: 'Ivan', age: 35 }, { name: 'Mike', age: 41 }];
- resolve(values);
- });
- };
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- assert.equal(select.selectOptions.length, 0);
- select.choices.showDropdown();
-
- setTimeout(() => {
- assert.equal(select.selectOptions.length, 2);
- assert.deepEqual(select.selectOptions[0].value, 35);
- assert.deepEqual(select.selectOptions[0].label, 'Ivan');
-
- const items = select.choices.choiceList.element.children;
- assert.equal(items.length, 2);
- assert.equal(items[0].textContent.trim(), 'Ivan');
-
- select.setValue(41);
-
- setTimeout(() => {
- assert.equal(select.getValue(), 41);
- assert.equal(select.choices.containerInner.element.children[1].children[0].children[0].textContent, 'Mike');
-
- Formio.makeRequest = originalMakeRequest;
-
- done();
- }, 400);
- }, 200);
- }).catch(done);
+ const form = await Formio.createForm(element, formSchema);
+ const select = form.getComponent('select');
+ const searchField = select.element.querySelector('.choices__input.choices__input--cloned');
+ assert.equal(searchField, null);
});
- it('Should set custom header when sending request in select url', (done) => {
- const form = _.cloneDeep(comp9);
- form.components[1].refreshOn = null;
- form.components[1].lazyLoad = true;
- form.components[1].data.headers = [{ key:'testHeader', value:'test' }];
+ it('Should save correct value if value property and item template property are different', async () => {
+ const restoreMakeRequest = mockMakeRequest(() => new Promise((resolve) => {
+ resolve([{ name: 'Ivan', age: 35 }, { name: 'Mike', age: 41 }]);
+ }));
+
+ const formSchema = _.cloneDeep(comp9);
+ formSchema.components[1].refreshOn = null;
+ formSchema.components[1].valueProperty = 'age';
+ formSchema.components[1].lazyLoad = true;
const element = document.createElement('div');
- const originalMakeRequest = Formio.makeRequest;
+ const form = await Formio.createForm(element, formSchema);
+ const select = form.getComponent('select');
+
+ await select.itemsLoaded;
+ assert.equal(select.selectOptions.length, 0);
+ select.choices.showDropdown();
+
+ // trigger change
+ await timeout(0);
+ await select.itemsLoaded;
+ assert.equal(select.selectOptions.length, 2);
+ assert.deepEqual(select.selectOptions[0].value, 35);
+ assert.deepEqual(select.selectOptions[0].label, 'Ivan');
+
+ const items = select.choices.choiceList.element.children;
+ assert.equal(items.length, 2);
+ assert.equal(items[0].textContent.trim(), 'Ivan');
+ select.setValue(41);
+
+ await select.itemsLoaded;
+ assert.equal(select.getValue(), 41);
+ assert.equal(select.choices.containerInner.element.children[1].children[0].children[0].textContent, 'Mike');
+
+ restoreMakeRequest();
+ });
- Formio.makeRequest = function(formio, type, url, method, data, opts) {
+ it('Should set custom header when sending request in select url', async () => {
+ const restoreMakeRequest = mockMakeRequest((formio, type, url, method, data, opts) => {
assert.equal(opts.header.get('testHeader'), 'test');
- return new Promise(resolve => {
+ return new Promise((resolve) => {
const values = [{ name: 'Ivan', age: 35 }, { name: 'Mike', age: 41 }];
resolve(values);
});
- };
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- assert.equal(select.selectOptions.length, 0);
- select.choices.showDropdown();
-
- setTimeout(() => {
- Formio.makeRequest = originalMakeRequest;
- done();
- }, 200);
- }).catch(done);
- });
+ });
- it('Should set value in select url with lazy load option', (done) => {
- const form = _.cloneDeep(comp9);
- form.components[1].refreshOn = null;
- form.components[1].lazyLoad = true;
+ const formSchema = _.cloneDeep(comp9);
+ formSchema.components[1].refreshOn = null;
+ formSchema.components[1].lazyLoad = true;
+ formSchema.components[1].data.headers = [{ key:'testHeader', value:'test' }];
const element = document.createElement('div');
- const originalMakeRequest = Formio.makeRequest;
+ const form = await Formio.createForm(element, formSchema);
+ const select = form.getComponent('select');
- Formio.makeRequest = function() {
- return new Promise(resolve => {
- const values = [{ name: 'Ivan' }, { name: 'Mike' }];
- resolve(values);
- });
- };
+ await select.itemsLoaded;
+ assert.equal(select.selectOptions.length, 0);
+ select.choices.showDropdown();
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- select.setValue({ name: 'Ivan' });
- setTimeout(() => {
- assert.deepEqual(select.getValue(), { name: 'Ivan' });
- assert.deepEqual(select.dataValue, { name: 'Ivan' });
- assert.equal(select.choices.containerInner.element.children[1].children[0].children[0].textContent, 'Ivan');
+ // trigger change
+ await timeout(0);
+ await select.itemsLoaded;
+ restoreMakeRequest();
+ });
- Formio.makeRequest = originalMakeRequest;
+ it('Should set value in select url with lazy load option', async () => {
+ const restoreMakeRequest = mockMakeRequest(() => new Promise((resolve) => {
+ const values = [{ name: 'Ivan' }, { name: 'Mike' }];
+ resolve(values);
+ }));
- done();
- }, 200);
- }).catch(done);
- });
+ const formSchema = _.cloneDeep(comp9);
+ formSchema.components[1].refreshOn = null;
+ formSchema.components[1].lazyLoad = true;
- it('Should set value in select url with lazy load option when value property is defined', (done) => {
- const form = _.cloneDeep(comp9);
- form.components[1].refreshOn = null;
- form.components[1].lazyLoad = true;
- form.components[1].valueProperty = 'name';
const element = document.createElement('div');
- const originalMakeRequest = Formio.makeRequest;
+ const form = await Formio.createForm(element, formSchema);
+ const select = form.getComponent('select');
+ select.setValue({ name: 'Ivan' });
- Formio.makeRequest = function() {
- return new Promise(resolve => {
- const values = [{ name: 'Ivan' }, { name: 'Mike' }];
- resolve(values);
- });
- };
+ await select.itemsLoaded;
+ assert.deepEqual(select.getValue(), { name: 'Ivan' });
+ assert.deepEqual(select.dataValue, { name: 'Ivan' });
+ assert.equal(select.choices.containerInner.element.children[1].children[0].children[0].textContent, 'Ivan');
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- select.setValue('Ivan');
- setTimeout(() => {
- assert.equal(select.getValue(), 'Ivan');
- assert.equal(select.dataValue, 'Ivan');
- assert.equal(select.choices.containerInner.element.children[1].children[0].children[0].textContent, 'Ivan');
+ restoreMakeRequest();
+ });
- Formio.makeRequest = originalMakeRequest;
+ it('Should set value in select url with lazy load option when value property is defined', async () => {
+ const restoreDebounce = mockDebounce(0);
+ const restoreMakeRequest = mockMakeRequest(() => new Promise((resolve) => {
+ const values = [{ name: 'Ivan' }, { name: 'Mike' }];
+ resolve(values);
+ }));
- done();
- }, 200);
- }).catch(done);
- });
+ const formSchema = _.cloneDeep(comp9);
+ formSchema.components[1].refreshOn = null;
+ formSchema.components[1].lazyLoad = true;
+ formSchema.components[1].valueProperty = 'name';
- it('Should be able to search if static search is enable', (done) => {
- const form = _.cloneDeep(comp10);
const element = document.createElement('div');
+ const form = await Formio.createForm(element, formSchema);
+ const select = form.getComponent('select');
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
+ await select.itemsLoaded;
+ select.setValue('Ivan');
- const searchField = select.element.querySelector('.choices__input.choices__input--cloned');
- const focusEvent = new Event('focus');
- searchField.dispatchEvent(focusEvent);
+ await timeout(0);
+ await select.itemsLoaded;
+ assert.equal(select.getValue(), 'Ivan');
+ assert.equal(select.dataValue, 'Ivan');
+ assert.equal(select.choices.containerInner.element.children[1].children[0].children[0].textContent, 'Ivan');
- setTimeout(() => {
- assert.equal(select.choices.dropdown.isActive, true);
- const items = select.choices.choiceList.element.children;
- assert.equal(items.length, 5);
-
- const keyupEvent = new Event('keyup');
- const searchField = select.element.querySelector('.choices__input.choices__input--cloned');
- searchField.value = 'par';
- searchField.dispatchEvent(keyupEvent);
+ restoreDebounce();
+ restoreMakeRequest();
+ });
- setTimeout(() => {
- const items = select.choices.choiceList.element.children;
- assert.equal(items.length, 1);
+ it('Server side search is debounced with the correct timeout', async () => {
+ let searchHasBeenDebounced = false;
+ const restoreDebounce = mockDebounce(0, (wait) => {
+ if (wait === 700) {
+ searchHasBeenDebounced = true;
+ }
+ });
- done();
- }, 400);
- }, 200);
- }).catch(done);
- });
+ const formSchema = _.cloneDeep(comp9);
+ formSchema.components[1].searchDebounce = 0.7;
+ formSchema.components[1].searchField = 'name';
- it('Server side search is debounced with the correct timeout', (done) => {
- const form = _.cloneDeep(comp9);
- form.components[1].lazyLoad = false;
- form.components[1].searchDebounce = 0.7;
- form.components[1].disableLimit = false;
- form.components[1].searchField = 'name';
const element = document.createElement('div');
+ await Formio.createForm(element, formSchema);
- const originalMakeRequest = Formio.makeRequest;
- Formio.makeRequest = function() {
- return new Promise(resolve => {
- resolve([]);
- });
- };
-
- var searchHasBeenDebounced = false;
- var originalDebounce = _.debounce;
- _.debounce = (fn, timeout, opts) => {
- searchHasBeenDebounced = true;
- return originalDebounce(fn, 0, opts);
- };
+ assert.equal(searchHasBeenDebounced, true);
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- const searchField = select.element.querySelector('.choices__input.choices__input--cloned');
- const focusEvent = new Event('focus');
- searchField.dispatchEvent(focusEvent);
-
- setTimeout(() => {
- const keyupEvent = new Event('keyup');
- searchField.value = 'the_name';
- searchField.dispatchEvent(keyupEvent);
-
- setTimeout(() => {
- _.debounce = originalDebounce;
- Formio.makeRequest = originalMakeRequest;
-
- assert.equal(searchHasBeenDebounced, true);
- done();
- }, 500);
- }, 300);
- }).catch(done);
+ restoreDebounce();
});
- it('Should provide "Allow only available values" validation', (done) => {
- const form = _.cloneDeep(comp10);
- form.components[0].validate.onlyAvailableItems = true;
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- const value = 'Dallas';
- select.setValue(value);
-
- setTimeout(() => {
- assert.equal(select.getValue(), value);
- assert.equal(select.dataValue, value);
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(form.errors.length, 1);
- assert.equal(select.errors[0].message, 'Select is an invalid value.');
- document.innerHTML = '';
- done();
- }, 400);
- }, 200);
- }).catch(done);
- });
+ it('Should provide "Allow only available values" validation', async () => {
+ const formSchema = _.cloneDeep(comp10);
+ formSchema.components[0].validate.onlyAvailableItems = true;
- it('Should render and set value in select json', (done) => {
- const formObj = _.cloneDeep(comp11);
const element = document.createElement('div');
+ const form = await Formio.createForm(element, formSchema);
+ const select = form.getComponent('select');
- Formio.createForm(element, formObj).then(form => {
- const select = form.getComponent('select');
- assert.equal(select.choices.containerInner.element.children[1].children[0].dataset.value, '');
- select.choices.showDropdown();
+ await select.itemsLoaded;
+ const value = 'Dallas';
+ select.setValue(value);
- setTimeout(() => {
- const items = select.choices.choiceList.element.children;
- assert.equal(items.length, 4);
+ await select.itemsLoaded;
+ assert.equal(select.getValue(), value);
+ assert.equal(select.dataValue, value);
- const value = { value: 'a', label:'A' };
- select.setValue(value);
+ const submit = form.getComponent('submit');
+ const clickEvent = new Event('click');
+ const submitBtn = submit.refs.button;
+ submitBtn.dispatchEvent(clickEvent);
- setTimeout(() => {
- assert.deepEqual(select.getValue(), value);
- assert.deepEqual(select.dataValue, value);
- assert.equal(select.choices.containerInner.element.children[1].children[0].children[0].textContent, 'A');
-
- done();
- }, 400);
- }, 200);
- }).catch(done);
+ await new Promise((resolve, reject) => {
+ form.on('submit', () => reject('Shouldn\'t submit the form with a validation error.'));
+ form.on('submitError', () => resolve());
+ });
+ assert.equal(form.errors.length, 1);
+ assert.equal(select.errors[0].message, 'Select is an invalid value.');
});
- it('Should load and set items in select resource and set value', (done) => {
- const form = _.cloneDeep(comp12);
+ it('Should render and set value in select json', async () => {
+ const formObj = _.cloneDeep(comp11);
const element = document.createElement('div');
- const originalMakeRequest = Formio.makeRequest;
+ const form = await Formio.createForm(element, formObj);
+ const select = form.getComponent('select');
+
+ await select.itemsLoaded;
+ assert.equal(select.choices.containerInner.element.children[1].children[0].dataset.value, '');
+ select.choices.showDropdown();
+
+ // trigger change
+ await timeout(0);
+ await select.itemsLoaded;
+ const items = select.choices.choiceList.element.children;
+ assert.equal(items.length, 4);
+ const value = { value: 'a', label:'A' };
+ select.setValue(value);
+
+ await select.itemsLoaded;
+ assert.deepEqual(select.getValue(), value);
+ assert.deepEqual(select.dataValue, value);
+ assert.equal(select.choices.containerInner.element.children[1].children[0].children[0].textContent, 'A');
+ });
- Formio.makeRequest = function(formio, type, url) {
- return new Promise(resolve => {
- let values = [{ data: { name: 'Ivan' } }, { data: { name: 'Mike' } }];
+ it('Should load and set items in select resource and set value', async () => {
+ const restoreDebounce = mockDebounce(0);
+ const restoreMakeRequest = mockMakeRequest((formio, type, url) => new Promise((resolve) => {
+ let values = [{ data: { name: 'Ivan' } }, { data: { name: 'Mike' } }];
- if (url.endsWith('Ivan')) {
- assert.equal(url.endsWith('/form/60114dd32cab36ad94ac4f94/submission?limit=100&skip=0&data.name__regex=Ivan'), true);
- values = [{ data: { name: 'Ivan' } }];
- }
- else {
- assert.equal(url.endsWith('/form/60114dd32cab36ad94ac4f94/submission?limit=100&skip=0'), true);
- }
+ if (url.endsWith('Ivan')) {
+ assert.equal(url.endsWith('/form/60114dd32cab36ad94ac4f94/submission?limit=100&skip=0&data.name__regex=Ivan'), true);
+ values = [{ data: { name: 'Ivan' } }];
+ }
+ else {
+ assert.equal(url.endsWith('/form/60114dd32cab36ad94ac4f94/submission?limit=100&skip=0'), true);
+ }
- resolve(values);
- });
- };
+ resolve(values);
+ }));
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- const items = select.choices.choiceList.element.children;
- assert.equal(items.length, 1);
- select.setValue('Ivan');
-
- setTimeout(() => {
- assert.equal(select.getValue(), 'Ivan');
- assert.equal(select.dataValue, 'Ivan');
- assert.equal(select.choices.containerInner.element.children[1].children[0].children[0].textContent, 'Ivan');
- select.choices.showDropdown();
-
- setTimeout(() => {
- const items = select.choices.choiceList.element.children;
-
- assert.equal(items.length, 2);
- assert.equal(items[0].textContent, 'Ivan');
-
- Formio.makeRequest = originalMakeRequest;
- done();
- }, 400);
- }, 200);
- }).catch(done);
+ const element = document.createElement('div');
+ const form = await Formio.createForm(element, _.cloneDeep(comp12));
+ const select = form.getComponent('select');
+
+ let items = select.choices.choiceList.element.children;
+ assert.equal(items.length, 1);
+ select.setValue('Ivan');
+
+ await timeout(0);
+ await select.itemsLoaded;
+ assert.equal(select.getValue(), 'Ivan');
+ assert.equal(select.dataValue, 'Ivan');
+ assert.equal(select.choices.containerInner.element.children[1].children[0].children[0].textContent, 'Ivan');
+ select.choices.showDropdown();
+
+ await timeout(0);
+ await select.itemsLoaded;
+ items = select.choices.choiceList.element.children;
+ assert.equal(items.length, 2);
+ assert.equal(items[0].textContent, 'Ivan');
+
+ restoreDebounce();
+ restoreMakeRequest();
});
- it('Should not have "limit" and "skip" query params when "Disable limit" option checked', (done) => {
- const form = _.cloneDeep(comp9);
- const element = document.createElement('div');
- const originalMakeRequest = Formio.makeRequest;
- Formio.makeRequest = (_, __, url) => {
+ it('Should not have "limit" and "skip" query params when "Disable limit" option checked', async () => {
+ const restoreMakeRequest = mockMakeRequest((_, __, url) => {
assert.equal(url, 'https://test.com/');
return Promise.resolve({});
- };
+ });
+
+ const element = document.createElement('div');
+ const form = await Formio.createForm(element, _.cloneDeep(comp9));
+ const select = form.getComponent('select');
- Formio.createForm(element, form).then(() => {
- setTimeout(() => {
- Formio.makeRequest = originalMakeRequest;
- done();
- }, 200);
- }).catch(done);
+ await select.itemsLoaded;
+ restoreMakeRequest();
});
- it('The empty option in html5 shouldn\'t have the [Object Object] value', () => {
- return Harness.testCreate(SelectComponent, comp13).then((component) => {
- const emptyOption = component.element.querySelectorAll('option')[0];
- assert.notEqual(emptyOption.value, '[object Object]');
- assert.equal(emptyOption.value, '');
- });
+ it('The empty option in html5 Shouldn\'t have the [Object Object] value', async () => {
+ const component = await Harness.testCreate(SelectComponent, comp13);
+ await component.itemsLoaded;
+ const emptyOption = component.element.querySelectorAll('option')[0];
+ assert.notEqual(emptyOption.value, '[object Object]');
+ assert.equal(emptyOption.value, '');
});
- it('Should not have default values in schema', (done) => {
- const form = _.cloneDeep(comp14);
+ it('Should not have default values in schema', async () => {
const element = document.createElement('div');
const requiredSchema = {
@@ -879,398 +748,401 @@ describe('Select Component', () => {
input: true
};
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- assert.deepEqual(requiredSchema, select.schema);
- done();
- }).catch(done);
+ const form = await Formio.createForm(element, _.cloneDeep(comp14));
+ const select = form.getComponent('select');
+ assert.deepEqual(requiredSchema, select.schema);
});
- it('Should show async custom values and be able to set submission', (done) => {
- const formObj = _.cloneDeep(comp16);
+ it('Should show async custom values and be able to set submission', async () => {
const element = document.createElement('div');
-
- Formio.createForm(element, formObj).then(form => {
- const select = form.getComponent('select');
- select.choices.showDropdown();
-
- setTimeout(() => {
- const items = select.choices.choiceList.element.children;
- assert.equal(items.length, 3);
- const value = 'bb';
- form.submission = { data: { select: value } };
-
- setTimeout(() => {
- assert.deepEqual(select.getValue(), value);
- assert.deepEqual(select.dataValue, value);
- assert.equal(select.choices.containerInner.element.children[1].children[0].children[0].textContent, 'B');
-
- done();
- }, 400);
- }, 200);
- }).catch(done);
+ const form = await Formio.createForm(element, _.cloneDeep(comp16));
+ const select = form.getComponent('select');
+ select.choices.showDropdown();
+
+ await timeout(0);
+ await select.itemsLoaded;
+ assert.equal(select.dataValue, '');
+ const items = select.choices.choiceList.element.children;
+ assert.equal(items.length, 3);
+ const value = 'bb';
+ form.submission = { data: { select: value } };
+
+ await form.submissionReady;
+ assert.deepEqual(select.getValue(), value);
+ assert.deepEqual(select.dataValue, value);
+ assert.equal(select.choices.containerInner.element.children[1].children[0].children[0].textContent, 'B');
});
- it('Should provide metadata.selectData for Select component pointed to a resource where value property is set to a field', (done) => {
- const form = _.cloneDeep(comp17);
+ it('Should provide metadata.selectData for Select component pointed to a resource where value property is set to a field', async () => {
const testItems = [
- { textField: 'John' },
- { textField: 'Mary' },
- { textField: 'Sally' }
+ { data: { textField: 'John' }},
+ { data: { textField: 'Mary' }},
+ { data: { textField: 'Sally' }},
];
+ const restoreMakeRequest = mockMakeRequest(() => new Promise((resolve) => {
+ resolve(testItems);
+ }));
+
const element = document.createElement('div');
+ const form = await Formio.createForm(element, _.cloneDeep(comp17));
+ const select = form.getComponent('select');
+
+ const value = 'John';
+ select.setValue(value);
+
+ await select.itemsLoaded;
+ assert.equal(select.dataValue, value);
+ const submit = form.getComponent('submit');
+ const clickEvent = new Event('click');
+ const submitBtn = submit.refs.button;
+ submitBtn.dispatchEvent(clickEvent);
+
+ await new Promise((resolve, reject) => {
+ form.on('submit', () => resolve());
+ form.on('submitError', () => reject('Should submit the form.'));
+ });
+ assert.equal(_.isEqual(form.submission.metadata.selectData.select.data, testItems[0].data), true);
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- select.setItems(testItems.map(item => ({ data: item })));
- const value = 'John';
- select.setValue(value);
-
- setTimeout(() => {
- assert.equal(select.dataValue, value);
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(_.isEqual(form.submission.metadata.selectData.select.data, testItems[0]), true);
- done();
- }, 200);
- }, 200);
- }).catch(done);
+ restoreMakeRequest();
});
- it('Should provide correct metadata.selectData for multiple Select', (done) => {
- const form = _.cloneDeep(comp20);
+ it('Should provide correct metadata.selectData for multiple Select', async () => {
const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- const values = ['apple', 'orange'];
- select.setValue(values);
-
- setTimeout(()=> {
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- const metadata = form.submission.metadata.selectData.select;
- assert.equal(_.keys(metadata).length, 2);
- values.forEach((value) => {
- assert.equal(_.find(select.component.data.values, { value }).label, metadata[value].label);
- });
- done();
- }, 200);
- }, 200);
- }).catch(done);
+ const form = await Formio.createForm(element, _.cloneDeep(comp20));
+ const select = form.getComponent('select');
+ const values = ['apple', 'orange'];
+ select.setValue(values);
+
+ await select.itemsLoaded;
+ const submit = form.getComponent('submit');
+ const clickEvent = new Event('click');
+ const submitBtn = submit.refs.button;
+ submitBtn.dispatchEvent(clickEvent);
+
+ await new Promise((resolve, reject) => {
+ form.on('submit', () => resolve());
+ form.on('submitError', () => reject('Should submit the form.'));
+ });
+ const metadata = form.submission.metadata.selectData.select;
+ assert.equal(_.keys(metadata).length, 2);
+ values.forEach((value) => {
+ assert.equal(_.find(select.component.data.values, { value }).label, metadata[value].label);
+ });
});
- it('Should provide correct metadata.selectData for HTML5 Select', (done) => {
+ it('Should provide correct metadata.selectData for HTML5 Select', async () => {
+ const restoreDebounce = mockDebounce(0);
+
const element = document.createElement('div');
+ const form = await Formio.createForm(element, _.cloneDeep(comp21));
+ const select = form.getComponent('animals');
+ const checkbox = form.getComponent('checkbox');
+ const value = 'dog';
+ select.setValue(value);
+
+ await select.itemsLoaded;
+ checkbox.setValue(true);
+
+ await timeout(50);
+ const submit = form.getComponent('submit');
+ const clickEvent = new Event('click');
+ const submitBtn = submit.refs.button;
+ submitBtn.dispatchEvent(clickEvent);
+
+ await new Promise((resolve, reject) => {
+ form.on('submit', () => resolve());
+ form.on('submitError', () => reject('Should submit the form.'));
+ });
+ const metadata = form.submission.metadata.selectData.animals2;
+ assert.equal(metadata.label, 'Dog');
- Formio.createForm(element, comp21).then(form => {
- const select = form.getComponent('animals');
- const checkbox = form.getComponent('checkbox');
- const value = 'dog';
- select.setValue(value);
-
- setTimeout(()=> {
- checkbox.setValue(true);
- setTimeout(() => {
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- const metadata = form.submission.metadata.selectData.animals2;
- assert.equal(metadata.label, 'Dog');
- done();
- }, 200);
- }, 300);
- }, 200);
- }).catch(done);
+ restoreDebounce();
});
- it('Should provide correct metadata.selectData for HTML5 Select with default value', (done) => {
- const form = _.cloneDeep(comp22);
+ it('Should provide correct metadata.selectData for HTML5 Select with default value', async () => {
+ const restoreMakeRequest = mockMakeRequest(() => new Promise((resolve) => {
+ resolve([]);
+ }));
+
const element = document.createElement('div');
+ const form = await Formio.createForm(element, _.cloneDeep(comp22));
+ const select = form.getComponent('select');
+ await select.itemsLoaded;
+
+ const submit = form.getComponent('submit');
+ const clickEvent = new Event('click');
+ const submitBtn = submit.refs.button;
+ submitBtn.dispatchEvent(clickEvent);
+
+ await new Promise((resolve, reject) => {
+ form.on('submit', () => resolve());
+ form.on('submitError', () => reject('Should submit the form.'));
+ });
+
+ const metadata = form.submission.metadata.selectData.select;
+ assert.equal(metadata.label, 'Label 1');
- Formio.createForm(element, form).then(form => {
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(()=> {
- const metadata = form.submission.metadata.selectData.select;
- assert.equal(metadata.label, 'Label 1');
- done();
- }, 200);
- }).catch(done);
+ restoreMakeRequest();
});
- it('Should provide correct metadata.selectData for ChoicesJS Select with default value', (done) => {
- const form = _.cloneDeep(comp22);
- form.components[0].widget='choicesjs';
+ it('Should provide correct metadata.selectData for ChoicesJS Select with default value', async () => {
+ const restoreMakeRequest = mockMakeRequest(() => new Promise((resolve) => {
+ resolve([]);
+ }));
+
+ const formSchema = _.cloneDeep(comp22);
+ formSchema.components[0].widget='choicesjs';
const element = document.createElement('div');
+ const form = await Formio.createForm(element, formSchema);
+
+ const submit = form.getComponent('submit');
+ const clickEvent = new Event('click');
+ const submitBtn = submit.refs.button;
+ submitBtn.dispatchEvent(clickEvent);
- Formio.createForm(element, form).then(form => {
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(()=> {
- const metadata = form.submission.metadata.selectData.select;
- assert.equal(metadata.label, 'Label 1');
- done();
- }, 200);
- }).catch(done);
+ await new Promise((resolve, reject) => {
+ form.on('submit', () => resolve());
+ form.on('submitError', () => reject('Should submit the form.'));
+ });
+
+ const metadata = form.submission.metadata.selectData.select;
+ assert.equal(metadata.label, 'Label 1');
+
+ restoreMakeRequest();
});
- it('Should set correct label from metadata for ChoicesJS Select with default value', (done) => {
- const form = _.cloneDeep(comp22);
- form.components[0].widget='choicesjs';
+ it('Should set correct label from metadata for ChoicesJS Select with default value', async () => {
+ const formSchema = _.cloneDeep(comp22);
+ formSchema.components[0].widget='choicesjs';
const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- form.submission = {
- data: {
- select: 'value2',
- },
- metadata: {
- selectData: {
- select: {
- label: 'Label 2',
- },
+ const form = await Formio.createForm(element, formSchema);
+ const select = form.getComponent('select');
+ form.submission = {
+ data: {
+ select: 'value2',
+ },
+ metadata: {
+ selectData: {
+ select: {
+ label: 'Label 2',
},
},
- };
+ },
+ };
- setTimeout(()=> {
- assert.equal(select.templateData['value2'].label, 'Label 2');
- done();
- }, 200);
- }).catch(done);
+ await form.submissionReady;
+ await select.itemsLoaded;
+ assert.equal(select.templateData['value2'].label, 'Label 2');
});
- it('Should provide correct metadata.selectData for multiple Select with default value', (done) => {
- const form = _.cloneDeep(comp23);
+ it('Should provide correct metadata.selectData for multiple Select with default value', async () => {
const element = document.createElement('div');
+ const form = await Formio.createForm(element, _.cloneDeep(comp23));
+ const submit = form.getComponent('submit');
+ const clickEvent = new Event('click');
+ const submitBtn = submit.refs.button;
+ submitBtn.dispatchEvent(clickEvent);
+
+ await new Promise((resolve, reject) => {
+ form.on('submit', () => resolve());
+ form.on('submitError', () => reject('Should submit the form.'));
+ });
- Formio.createForm(element, form).then(form => {
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(()=> {
- const metadata = form.submission.metadata.selectData.select;
- assert.deepEqual(metadata, {
- value1: {
- label: 'Label 1',
- },
- value3: {
- label: 'Label 3',
- },
- });
- done();
- }, 200);
- }).catch(done);
+ const metadata = form.submission.metadata.selectData.select;
+ assert.deepEqual(metadata, {
+ value1: {
+ label: 'Label 1',
+ },
+ value3: {
+ label: 'Label 3',
+ },
+ });
});
- it('Should set correct label from metadata for multiple Select with default value', (done) => {
- const form = _.cloneDeep(comp23);
+ it('Should set correct label from metadata for multiple Select with default value', async () => {
const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- form.submission = {
- data: {
- select: ['value1', 'value2'],
- },
- metadata: {
- selectData: {
- select: {
- value1: {
- label: 'Label 1',
- },
- value2: {
- label: 'Label 2',
- },
+ const form = await Formio.createForm(element, _.cloneDeep(comp23));
+ const select = form.getComponent('select');
+ form.submission = {
+ data: {
+ select: ['value1', 'value2'],
+ },
+ metadata: {
+ selectData: {
+ select: {
+ value1: {
+ label: 'Label 1',
+ },
+ value2: {
+ label: 'Label 2',
},
},
},
- };
-
- setTimeout(()=> {
- assert.equal(select.templateData['value1'].label, 'Label 1');
- assert.equal(select.templateData['value2'].label, 'Label 2');
- done();
- }, 200);
- }).catch(done);
- });
-
- it('OnBlur validation should work properly with Select component', function(done) {
- this.timeout(0);
- const element = document.createElement('div');
+ },
+ };
- Formio.createForm(element, comp19).then(form => {
- const select = form.components[0];
- select.setValue('banana');
- select.choices.input.element.focus();
- select.pristine = false;
-
- setTimeout(() => {
- assert(!select.visibleErrors.length, 'Select should be valid while changing');
- select.choices.input.element.dispatchEvent(new Event('blur'));
-
- setTimeout(() => {
- assert(select.visibleErrors.length, 'Should set error after Select component was blurred');
- done();
- }, 300);
- }, 300);
- }).catch(done);
+ await form.submissionReady;
+ await select.itemsLoaded;
+ assert.equal(select.templateData['value1'].label, 'Label 1');
+ assert.equal(select.templateData['value2'].label, 'Label 2');
});
- it('Should escape special characters in regex search field', done => {
- const form = _.cloneDeep(comp17);
+ it('OnBlur validation Should work properly with Select component', async () => {
+ const restoreDebounce = mockDebounce(0);
+
const element = document.createElement('div');
- Formio.setProjectUrl('https://formio.form.io');
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- const searchField = select.element.querySelector('.choices__input.choices__input--cloned');
- const focusEvent = new Event('focus');
- searchField.dispatchEvent(focusEvent);
+ const form = await Formio.createForm(element, comp19);
+ const select = form.components[0];
+ select.setValue('banana');
- setTimeout(() => {
- const keyupEvent = new Event('keyup');
- searchField.value = '^$.*+?()[]{}|';
- searchField.dispatchEvent(keyupEvent);
+ await select.itemsLoaded;
+ select.choices.input.element.focus();
+ select.pristine = false;
- const spy = sinon.spy(Formio, 'makeRequest');
+ await timeout(50);
+ assert(!select.visibleErrors.length, 'Select Should be valid while changing');
+ select.choices.input.element.dispatchEvent(new Event('blur'));
- setTimeout(() => {
- assert.equal(spy.callCount, 1);
+ await timeout(50);
+ assert(select.visibleErrors.length, 'Should set error after Select component was blurred');
- const urlArg = spy.args[0][2];
+ restoreDebounce();
+ });
- assert.ok(urlArg && typeof urlArg === 'string' && urlArg.startsWith('http'), 'A URL should be passed as the third argument to "Formio.makeRequest()"');
+ it('Should escape special characters in regex search field', async () => {
+ const restoreDebounce = mockDebounce(0);
+ const restoreMakeRequest = mockMakeRequest(() => new Promise((resolve) => {
+ resolve([]);
+ }))
- assert.ok(urlArg.includes('__regex=%5C%5E%5C%24%5C.%5C*%5C%2B%5C%3F%5C(%5C)%5C%5B%5C%5D%5C%7B%5C%7D%5C%7C'), 'The URL should contain escaped and encoded search value regex');
- done();
- }, 500);
- }, 200);
- }).catch(done);
+ const element = document.createElement('div');
+ Formio.setProjectUrl('https://formio.form.io');
+ const form = await Formio.createForm(element, _.cloneDeep(comp17));
+ const select = form.getComponent('select');
+ const searchField = select.element.querySelector('.choices__input.choices__input--cloned');
+ const focusEvent = new Event('focus');
+ searchField.dispatchEvent(focusEvent);
+
+ await timeout(0);
+ await select.itemsLoaded;
+ const keyupEvent = new Event('input');
+ searchField.value = '^$.*+?()[]{}|';
+ searchField.dispatchEvent(keyupEvent);
+ const spy = sinon.spy(Formio, 'makeRequest');
+
+ await timeout(0);
+ await select.itemsLoaded;
+ assert.equal(spy.callCount, 1);
+ const urlArg = spy.args[0][2];
+ assert.ok(urlArg && typeof urlArg === 'string' && urlArg.startsWith('http'), 'A URL Should be passed as the third argument to "Formio.makeRequest()"');
+ assert.ok(urlArg.includes('__regex=%5C%5E%5C%24%5C.%5C*%5C%2B%5C%3F%5C(%5C)%5C%5B%5C%5D%5C%7B%5C%7D%5C%7C'), 'The URL Should contain escaped and encoded search value regex');
+
+ restoreDebounce();
+ restoreMakeRequest();
});
- it('Should perfom simple conditional logic for number data type', (done) => {
- const form = _.cloneDeep(comp26);
- const element = document.createElement('div');
+ it('Should perform simple conditional logic for number data type', async () => {
+ const restoreDebounce = mockDebounce();
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- const textfield = form.getComponent('textField');
- select.setValue('1');
-
- setTimeout(() => {
- assert.equal(select.dataValue, 1);
- assert.equal(textfield.visible, true);
- select.setValue('2');
-
- setTimeout(() => {
- assert.equal(select.dataValue, 2);
- assert.equal(textfield.visible, true);
- select.setValue('10');
-
- setTimeout(() => {
- assert.equal(select.dataValue, 10);
- assert.equal(textfield.visible, false);
- select.setValue('1d');
-
- setTimeout(() => {
- assert.equal(select.dataValue, '1d');
- assert.equal(textfield.visible, false);
- done();
- }, 300);
- }, 300);
- }, 300);
- }, 300);
- }).catch(done);
+ const element = document.createElement('div');
+ const form = await Formio.createForm(element, _.cloneDeep(comp26));
+ const select = form.getComponent('select');
+ const textfield = form.getComponent('textField');
+ select.setValue('1');
+
+ await timeout(50);
+ assert.equal(select.dataValue, 1);
+ assert.equal(textfield.visible, true);
+ select.setValue('2');
+
+ await timeout(50);
+ assert.equal(select.dataValue, 2);
+ assert.equal(textfield.visible, true);
+ select.setValue('10');
+
+ await timeout(50);
+ assert.equal(select.dataValue, 10);
+ assert.equal(textfield.visible, false);
+ select.setValue('1d');
+
+ await timeout(50);
+ assert.equal(select.dataValue, '1d');
+ assert.equal(textfield.visible, false);
+
+ restoreDebounce();
});
- it('Should open edit grid modal when clicking on validation link when editing a submission', (done) => {
- Formio.createForm(document.createElement('div'), comp25, {}).then((form) => {
- form.submission = {
- "data": {
- "editGrid": [
- {
- "notselect": "",
- "textField": ""
- }
- ],
- "draft": true,
- "submit": false
- },
- "state": "draft",
- };
- const buttonComponent = form.getComponent('submit');
- buttonComponent.refs.button.click();
- setTimeout(() => {
- form.refs.errorRef[0].click();
- setTimeout(() => {
- assert(document.querySelector('body').classList.contains('modal-open'), 'modal should be open');
- done();
- }, 200);
- }, 200);
+ it('Should open edit grid modal when clicking on validation link when editing a submission', async () => {
+ const form = await Formio.createForm(document.createElement('div'), comp25, {});
+ form.submission = {
+ "data": {
+ "editGrid": [
+ {
+ "notselect": "",
+ "textField": ""
+ }
+ ],
+ "draft": true,
+ "submit": false
+ },
+ "state": "draft",
+ };
+ const buttonComponent = form.getComponent('submit');
+ buttonComponent.refs.button.click();
+
+ await new Promise((resolve, reject) => {
+ form.on('submit', () => reject('Shouldn\'t submit the form with a validation error.'));
+ form.on('submitError', () => resolve());
});
+
+ form.refs.errorRef[0].click();
+ assert(document.querySelector('body').classList.contains('modal-open'), 'modal Should be open');
});
+ it('Should render label for multiple Select when Data Source is Resource in read only mode', async () => {
+ const restoreMakeRequest = mockMakeRequest(() => new Promise((resolve) => {
+ resolve([]);
+ }));
- it('Should render label for multiple Select when Data Source is Resource in read only mode', (done) => {
const element = document.createElement('div');
- const form = cloneDeep(comp24);
- set(form, 'components[0].multiple', true);
- Formio.createForm(element, form, { readOnly: true }).then((form) => {
- form.setSubmission({
- metadata: {
- selectData: {
- select: {
- 1: {
- data: {
- textField1: 'One'
- }
- },
- olivia: {
- data: {
- textField1: 'Olivia Miller'
- }
+ const formSchema = cloneDeep(comp24);
+ set(formSchema, 'components[0].multiple', true);
+ const form = await Formio.createForm(element, formSchema, { readOnly: true });
+ const select = form.getComponent('select');
+ form.setSubmission({
+ metadata: {
+ selectData: {
+ select: {
+ 1: {
+ data: {
+ textField1: 'One'
}
},
+ olivia: {
+ data: {
+ textField1: 'Olivia Miller'
+ }
+ }
},
},
- data: {
- select: [1, 'olivia'],
- submit: true,
- },
- state: 'submitted',
- });
+ },
+ data: {
+ select: [1, 'olivia'],
+ submit: true,
+ },
+ state: 'submitted',
+ });
+
+ await form.submissionReady;
+ await select.itemsLoaded;
+ await timeout(0);
+ const selectedItems = select.element.querySelectorAll('[aria-selected="true"] span');
+ assert.equal(selectedItems[0].innerHTML, 'One', 'Should show correct label for numeric values');
+ assert.equal(selectedItems[1].innerHTML, 'Olivia Miller', 'Should show correct label for string values');
- setTimeout(() => {
- const select = form.getComponent('select');
- const selectedItems = select.element.querySelectorAll('[aria-selected="true"] span');
- assert.equal(selectedItems[0].innerHTML, 'One', 'Should show correct label for numeric values');
- assert.equal(selectedItems[1].innerHTML, 'Olivia Miller', 'Should show correct label for string values');;
- done();
- }, 700);
- })
- .catch((err) => done(err));
+ restoreMakeRequest();
});
+
// it('should reset input value when called with empty value', () => {
// const comp = Object.assign({}, comp1);
// delete comp.placeholder;
@@ -1286,309 +1158,261 @@ describe('Select Component', () => {
// assert.equal(component.refs.input[0].value, '');
// });
// });
-});
-describe('Select Component', () => {
- it('Select Component should work correctly with the values in the form of an array', (done) => {
- const form = _.cloneDeep(comp18);
+ it('Select Component Should work correctly with the values in the form of an array', async () => {
const testItems = [
{ textField: ['one','two'] },
{ textField: ['three','four'] },
{ textField: ['five','six'] },
];
const element = document.createElement('div');
+ const form = await Formio.createForm(element, _.cloneDeep(comp18));
+ const select = form.getComponent('select');
+ select.setItems(testItems.map(item => ({ data: item })));
+ const value = ['three','four'];
+ select.setValue(value);
+
+ await select.itemsLoaded;
+ assert.equal(select.selectOptions.length, 3);
+ assert.deepEqual(select.getValue(), value);
+ assert.deepEqual(select.dataValue, value);
+ const submit = form.getComponent('submit');
+ const clickEvent = new Event('click');
+ const submitBtn = submit.refs.button;
+ submitBtn.dispatchEvent(clickEvent);
+
+ await new Promise((resolve, reject) => {
+ form.on('submit', () => resolve());
+ form.on('submitError', () => reject('Should submit the form.'));
+ });
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- select.setItems(testItems.map(item => ({ data: item })));
- const value = ['three','four'];
- select.setValue(value);
- assert.equal(select.selectOptions.length, 3);
- setTimeout(() => {
- assert.deepEqual(select.getValue(), value);
- assert.deepEqual(select.dataValue, value);
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(select.dataValue, value);
- done();
- }, 200);
- }, 200);
- }).catch(done);
+ assert.equal(select.dataValue, value);
});
});
describe('Select Component with Entire Object Value Property', () => {
- it('Should provide correct value', (done) => {
- const form = _.cloneDeep(comp15);
+ it('Should provide correct value', async () => {
+ const restoreMakeRequest = mockMakeRequest(() => new Promise((resolve) => {
+ resolve([]);
+ }));
+
const element = document.createElement('div');
+ const form = await Formio.createForm(element, _.cloneDeep(comp15));
+ const select = form.getComponent('select');
+ const value = { 'textField':'rgd','submit':true,'number':11 };
+ select.setValue(value);
+
+ await select.itemsLoaded;
+ assert.equal(select.getValue(), value);
+ assert.equal(select.dataValue, value);
+ const submit = form.getComponent('submit');
+ const clickEvent = new Event('click');
+ const submitBtn = submit.refs.button;
+ submitBtn.dispatchEvent(clickEvent);
+
+ await new Promise((resolve, reject) => {
+ form.on('submit', () => resolve());
+ form.on('submitError', () => reject('Should submit the form.'));
+ });
+ assert.equal(select.dataValue, value);
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- const value = { 'textField':'rgd','submit':true,'number':11 };
- select.setValue(value);
-
- setTimeout(() => {
- assert.equal(select.getValue(), value);
- assert.equal(select.dataValue, value);
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(select.dataValue, value);
- done();
- }, 200);
- }, 200);
- }).catch(done);
+ restoreMakeRequest();
});
- it('Should provide correct items for Resource DataSrc Type and Entire Object Value Property', (done) => {
- const form = _.cloneDeep(comp15);
+ it('Should provide correct items for Resource DataSrc Type and Entire Object Value Property', async () => {
const testItems = [
{ textField: 'Jone', number: 1 },
{ textField: 'Mary', number: 2 },
{ textField: 'Sally', number: 3 }
];
const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- select.setItems(testItems.map(item => ({ data: item })));
- const value = { textField: 'Jone', number: 1 };
- select.setValue(value);
- assert.equal(select.selectOptions.length, 3);
-
- setTimeout(() => {
- assert.equal(select.dataValue, value);
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(typeof select.dataValue, 'object');
- done();
- }, 200);
- }, 200);
- }).catch(done);
+ const form = await Formio.createForm(element, _.cloneDeep(comp15));
+ const select = form.getComponent('select');
+ select.setItems(testItems.map(item => ({ data: item })));
+ const value = { textField: 'Jone', number: 1 };
+ select.setValue(value);
+
+ await select.itemsLoaded;
+ assert.equal(select.selectOptions.length, 3);
+ assert.equal(select.dataValue, value);
+ const submit = form.getComponent('submit');
+ const clickEvent = new Event('click');
+ const submitBtn = submit.refs.button;
+ submitBtn.dispatchEvent(clickEvent);
+
+ await new Promise((resolve, reject) => {
+ form.on('submit', () => resolve());
+ form.on('submitError', () => reject('Should submit the form.'));
+ });
+ assert.equal(typeof select.dataValue, 'object');
});
- it('Should provide correct html value for Resource DataSrc Type and Entire Object Value Property', (done) => {
- const form = _.cloneDeep(comp15);
+ it('Should provide correct html value for Resource DataSrc Type and Entire Object Value Property', async () => {
const testItems = [
{ textField: 'Jone', number: 1 },
{ textField: 'Mary', number: 2 },
{ textField: 'Sally', number: 3 }
];
const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- select.setItems(testItems.map(item => ({ data: item })));
- const selectContainer = element.querySelector('[ref="selectContainer"]');
- assert.notEqual(selectContainer, null);
- const options = selectContainer.childNodes;
- assert.equal(options.length, 4);
- options.forEach((option) => {
- assert.notEqual(option.value, '[object Object]');
- });
- const value = { textField: 'Jone', number: 1 };
- select.setValue(value);
- assert.equal(select.selectOptions.length, 3);
-
- setTimeout(() => {
- assert.equal(select.dataValue, value);
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(typeof select.dataValue, 'object');
- done();
- }, 200);
- }, 200);
- }).catch(done);
+ const form = await Formio.createForm(element, _.cloneDeep(comp15));
+ const select = form.getComponent('select');
+ select.setItems(testItems.map(item => ({ data: item })));
+
+ await select.itemsLoaded;
+ const selectContainer = element.querySelector('[ref="selectContainer"]');
+ assert.notEqual(selectContainer, null);
+ const options = selectContainer.childNodes;
+ assert.equal(options.length, 4);
+ options.forEach((option) => {
+ assert.notEqual(option.value, '[object Object]');
+ });
+ const value = { textField: 'Jone', number: 1 };
+ select.setValue(value);
+
+ await select.itemsLoaded;
+ assert.equal(select.selectOptions.length, 3);
+ assert.equal(select.dataValue, value);
+ const submit = form.getComponent('submit');
+ const clickEvent = new Event('click');
+ const submitBtn = submit.refs.button;
+ submitBtn.dispatchEvent(clickEvent);
+
+ await new Promise((resolve, reject) => {
+ form.on('submit', () => resolve());
+ form.on('submitError', () => reject('Should submit the form.'));
+ });
+ assert.equal(typeof select.dataValue, 'object');
});
- it('Should set submission value for Resource DataSrc Type and Entire Object Value Property', (done) => {
- const form = _.cloneDeep(comp15);
+ // TODO: figure out why this test is working only with huge timeout
+ it('Should set submission value for Resource DataSrc Type and Entire Object Value Property', async () => {
const element = document.createElement('div');
+ const form = await Formio.createForm(element, _.cloneDeep(comp15));
+ const select = form.getComponent('select');
+ const value = { textField: 'Jone', number: 1 };
+ form.submission = {
+ data: {
+ select: value
+ }
+ };
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- const value = { textField: 'Jone', nubmer: 1 };
- form.submission = {
- data: {
- select: value
- }
- };
-
- setTimeout(() => {
- assert.equal(typeof select.dataValue, 'object');
- const selectContainer = element.querySelector('[ref="selectContainer"]');
- assert.notEqual(selectContainer, null);
- assert.notEqual(selectContainer.value, '');
- const options = selectContainer.childNodes;
- assert.equal(options.length, 2);
- done();
- }, 1000);
- }).catch(done);
+ await timeout(1000);
+ assert.equal(typeof select.dataValue, 'object');
+ const selectContainer = element.querySelector('[ref="selectContainer"]');
+ assert.notEqual(selectContainer, null);
+ assert.notEqual(selectContainer.value, '');
+ const options = selectContainer.childNodes;
+ assert.equal(options.length, 2);
});
- it('Should get string representation of value for Resource DataSrc Type and Entire Object Value Property', (done) => {
- Harness.testCreate(SelectComponent, comp15.components[0]).then((component) => {
- const entireObject = {
- a: '1',
- b: '2',
- };
- const formattedValue = component.getView(entireObject);
- assert.equal(formattedValue, JSON.stringify(entireObject));
- done();
- });
+ it('Should get string representation of value for Resource DataSrc Type and Entire Object Value Property', async () => {
+ const component = await Harness.testCreate(SelectComponent, comp15.components[0]);
+ const entireObject = {
+ a: '1',
+ b: '2',
+ };
+ const formattedValue = component.getView(entireObject);
+ assert.equal(formattedValue, JSON.stringify(entireObject));
});
- it('Should render label for Select components when Data Source is Resource in read only mode', (done) => {
+ it('Should render label for Select components when Data Source is Resource in read only mode', async () => {
const element = document.createElement('div');
- Formio.createForm(element, comp24, { readOnly: true }).then((form) => {
- const select = form.getComponent('select');
- form.setSubmission({
- metadata: {
- selectData: {
- select: {
- data: {
- textField1: 'A',
- },
+ const form =await Formio.createForm(element, comp24, { readOnly: true });
+ const select = form.getComponent('select');
+ form.setSubmission({
+ metadata: {
+ selectData: {
+ select: {
+ data: {
+ textField1: 'A',
},
},
- timezone: 'Europe/Kiev',
- offset: 180,
- origin: 'http://localhost:3001',
- referrer: '',
- browserName: 'Netscape',
- userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36',
- pathName: '/',
- onLine: true,
- headers: {
- host: 'qvecgdgwpwujbpi.localhost:3000',
- connection: 'keep-alive',
- 'content-length': '457',
- 'sec-ch-ua': '"Google Chrome";v="125", "Chromium";v="125", "Not.A/Brand";v="24"',
- accept: 'application/json',
- 'content-type': 'application/json',
- 'sec-ch-ua-mobile': '?0',
- 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36',
- 'sec-ch-ua-platform': '"Windows"',
- origin: 'http://localhost:3001',
- 'sec-fetch-site': 'cross-site',
- 'sec-fetch-mode': 'cors',
- 'sec-fetch-dest': 'empty',
- referer: 'http://localhost:3001/',
- 'accept-encoding': 'gzip, deflate, br, zstd',
- 'accept-language': 'en-US,en;q=0.9,ru-RU;q=0.8,ru;q=0.7',
- },
},
- data: {
- select: 1,
- select1: {
- textField1: 'A',
- textField2: '1',
- submit: true,
- },
+ },
+ data: {
+ select: 1,
+ select1: {
+ textField1: 'A',
+ textField2: '1',
submit: true,
},
- state: 'submitted',
- });
-
- setTimeout(() => {
- const previewSelect = select.element.querySelector('[aria-selected="true"] span');
-
- assert.equal(previewSelect.innerHTML, 'A', 'Should show label as a selected value' +
- ' for Select component');
+ submit: true,
+ },
+ state: 'submitted',
+ });
- done();
- }, 300);
- })
- .catch((err) => done(err));
+ await form.submissionReady;
+ await select.itemsLoaded;
+ const previewSelect = select.element.querySelector('[aria-selected="true"] span');
+ assert.equal(previewSelect.innerHTML, 'A', 'Should show label as a selected value' +
+ ' for Select component');
});
- it('Should render label for Select components when Data Source is Resource for modal preview', (done) => {
+ it('Should render label for Select components when Data Source is Resource for modal preview', async () => {
const element = document.createElement('div');
const comp = { ...comp24, modalEdit: true };
- Formio.createForm(element, comp).then((form) => {
- const select = form.getComponent('select');
- form.setSubmission({
- metadata: {
- selectData: {
- select: {
- data: {
- textField1: 'A',
- },
+ const form = await Formio.createForm(element, comp);
+ const select = form.getComponent('select');
+ form.setSubmission({
+ metadata: {
+ selectData: {
+ select: {
+ data: {
+ textField1: 'A',
},
},
},
- data: {
- select: 1,
- select1: {
- textField1: 'A',
- textField2: '1',
- submit: true,
- },
+ },
+ data: {
+ select: 1,
+ select1: {
+ textField1: 'A',
+ textField2: '1',
submit: true,
},
- state: 'submitted',
- });
-
- setTimeout(() => {
- const previewSelect = select.element.querySelector('[aria-selected="true"] span');
-
- assert.equal(previewSelect.innerHTML, 'A', 'Should show label as a selected value' +
- ' for Select component');
+ submit: true,
+ },
+ state: 'submitted',
+ });
- done();
- }, 300);
- })
- .catch((err) => done(err));
+ await form.submissionReady;
+ await select.itemsLoaded;
+ await timeout(0);
+ const previewSelect = select.element.querySelector('[aria-selected="true"] span');
+ assert.equal(previewSelect.innerHTML, 'A', 'Should show label as a selected value' +
+ ' for Select component');
});
- it('Should render label for Select Resource type in readOnly mode', (done) => {
+ it('Should render label for Select Resource type in readOnly mode', async () => {
const element = document.createElement('div');
- Formio.createForm(element, comp28, { readOnly: true }).then((form) => {
- const select = form.getComponent('selectResource');
- form.setSubmission({
- form: '672483c1d9abe46bcd70bca4',
- metadata: {
- selectData: {
- selectResource: {
- data: {
- textField: 'test1',
- },
+ const form = await Formio.createForm(element, comp28, { readOnly: true });
+ const select = form.getComponent('selectResource');
+ form.setSubmission({
+ form: '672483c1d9abe46bcd70bca4',
+ metadata: {
+ selectData: {
+ selectResource: {
+ data: {
+ textField: 'test1',
},
},
},
- data: {
- selectResource: 'test1',
- submit: true,
- },
- _id: '6724d15cd9abe46bcd7115d1',
- project: '67211a9aa929e4e6ebc2bf77',
- state: 'submitted',
- created: '2024-11-01T13:02:20.349Z',
- modified: '2024-11-01T13:02:20.349Z',
- });
+ },
+ data: {
+ selectResource: 'test1',
+ submit: true,
+ },
+ _id: '6724d15cd9abe46bcd7115d1',
+ project: '67211a9aa929e4e6ebc2bf77',
+ state: 'submitted',
+ created: '2024-11-01T13:02:20.349Z',
+ modified: '2024-11-01T13:02:20.349Z',
+ });
- setTimeout(() => {
- const previewSelect = select.element.querySelector('[aria-selected="true"] span');
- assert.equal(previewSelect.innerHTML, 'test1');
+ await form.submissionReady;
+ await select.itemsLoaded;
- done();
- }, 400);
- })
- .catch((err) => done(err));
+ const previewSelect = select.element.querySelector('[aria-selected="true"] span');
+ assert.equal(previewSelect.innerHTML, 'test1');
});
});
diff --git a/test/unit/Webform.unit.js b/test/unit/Webform.unit.js
index 7d51605d1f..f467730de5 100644
--- a/test/unit/Webform.unit.js
+++ b/test/unit/Webform.unit.js
@@ -975,7 +975,7 @@ describe('Webform tests', function() {
form.setForm(translationTestForm).then(() => {
setTimeout(() => {
const selectComp = form.getComponent('select');
- const options = selectComp.element.querySelector('[role="listbox"]').children;
+ const options = selectComp.choices.choiceList.element.children;
const option1 = options[0].textContent.trim();
const option2 = options[1].textContent.trim();
const label = selectComp.element.querySelector('label').textContent.trim();
@@ -2842,18 +2842,18 @@ describe('Webform tests', function() {
const field = form.components[0];
const field2 = form.components[1];
const fieldInput = field.refs.input[0];
-
+
Harness.setInputValue(field, 'data[textField]', '12');
-
+
setTimeout(() => {
assert.equal(field.errors.length, 0, 'Should be valid while changing');
const blurEvent = new Event('blur');
fieldInput.dispatchEvent(blurEvent);
-
+
setTimeout(() => {
assert.equal(field.errors.length, 1, 'Should set error after component was blurred');
Harness.setInputValue(field2, 'data[textField1]', 'ab');
-
+
setTimeout(() => {
assert.equal(field.errors.length, 1, 'Should keep error when editing another component');
done();