fix(form-core): add clear() to choice-group; test integratoons
This commit is contained in:
parent
0fa222c21b
commit
6ae7a5e352
11 changed files with 316 additions and 242 deletions
6
.changeset/thirty-eagles-prove.md
Normal file
6
.changeset/thirty-eagles-prove.md
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
'@lion/form-core': patch
|
||||||
|
'@lion/form-integrations': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Add `clear()` interface to choiceGroups
|
||||||
|
|
@ -187,6 +187,14 @@ const ChoiceGroupMixinImplementation = superclass =>
|
||||||
super.addFormElement(child, indexToInsertAt);
|
super.addFormElement(child, indexToInsertAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
if (this.multipleChoice) {
|
||||||
|
this.modelValue = [];
|
||||||
|
} else {
|
||||||
|
this.modelValue = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @override from FormControlMixin
|
* @override from FormControlMixin
|
||||||
* @protected
|
* @protected
|
||||||
|
|
|
||||||
|
|
@ -507,6 +507,23 @@ export function runChoiceGroupMixinSuite({ parentTagString, childTagString, choi
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('can be cleared', async () => {
|
||||||
|
const el = /** @type {ChoiceInputGroup} */ (await fixture(html`
|
||||||
|
<${parentTag} name="gender[]">
|
||||||
|
<${childTag} .choiceValue=${'male'}></${childTag}>
|
||||||
|
<${childTag} .choiceValue=${'female'}></${childTag}>
|
||||||
|
</${parentTag}>
|
||||||
|
`));
|
||||||
|
el.formElements[0].checked = true;
|
||||||
|
el.clear();
|
||||||
|
|
||||||
|
if (cfg.choiceType === 'single') {
|
||||||
|
expect(el.serializedValue).to.deep.equal('');
|
||||||
|
} else {
|
||||||
|
expect(el.serializedValue).to.deep.equal([]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
describe('multipleChoice', () => {
|
describe('multipleChoice', () => {
|
||||||
it('has a single modelValue representing all currently checked values', async () => {
|
it('has a single modelValue representing all currently checked values', async () => {
|
||||||
const el = /** @type {ChoiceInputGroup} */ (await fixture(html`
|
const el = /** @type {ChoiceInputGroup} */ (await fixture(html`
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@ export declare class ChoiceGroupHost {
|
||||||
|
|
||||||
addFormElement(child: FormControlHost, indexToInsertAt: number): void;
|
addFormElement(child: FormControlHost, indexToInsertAt: number): void;
|
||||||
|
|
||||||
|
clear(): void;
|
||||||
|
|
||||||
protected _triggerInitialModelValueChangedEvent(): void;
|
protected _triggerInitialModelValueChangedEvent(): void;
|
||||||
|
|
||||||
_getFromAllFormElements(property: string, filterCondition: Function): void;
|
_getFromAllFormElements(property: string, filterCondition: Function): void;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { expect, fixture, html } from '@open-wc/testing';
|
import { expect, fixture, html } from '@open-wc/testing';
|
||||||
|
import { getAllTagNames } from './helpers/helpers.js';
|
||||||
import './helpers/umbrella-form.js';
|
import './helpers/umbrella-form.js';
|
||||||
import '@lion/dialog/define';
|
import '@lion/dialog/define';
|
||||||
|
|
||||||
|
|
@ -10,7 +11,7 @@ import '@lion/dialog/define';
|
||||||
|
|
||||||
// Test umbrella form inside dialog
|
// Test umbrella form inside dialog
|
||||||
describe('Form inside dialog Integrations', () => {
|
describe('Form inside dialog Integrations', () => {
|
||||||
it('"Successfully registers all form components inside a dialog', async () => {
|
it('Successfully registers all form components inside a dialog', async () => {
|
||||||
const el = /** @type {LionDialog} */ await fixture(html` <lion-dialog>
|
const el = /** @type {LionDialog} */ await fixture(html` <lion-dialog>
|
||||||
<button slot="invoker">Open Dialog</button>
|
<button slot="invoker">Open Dialog</button>
|
||||||
<umbrella-form slot="content"></umbrella-form>
|
<umbrella-form slot="content"></umbrella-form>
|
||||||
|
|
@ -18,68 +19,54 @@ describe('Form inside dialog Integrations', () => {
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const formEl = /** @type {LionForm} */ (el._overlayCtrl.contentNode._lionFormNode);
|
const formEl = /** @type {LionForm} */ (el._overlayCtrl.contentNode._lionFormNode);
|
||||||
const getTagNames = (/** @type {HTMLElement} */ elm) => [
|
await formEl.registrationComplete;
|
||||||
elm.tagName.toLowerCase(),
|
const registeredEls = getAllTagNames(formEl);
|
||||||
// @ts-ignore
|
|
||||||
...(elm.formElements ? elm.formElements.map(getTagNames).flat() : []),
|
|
||||||
];
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
const registeredEls = formEl.formElements.map(getTagNames).flat();
|
|
||||||
|
|
||||||
// TODO: fix registration of lion-switch and lion-input-stepper
|
|
||||||
expect(registeredEls).to.eql([
|
expect(registeredEls).to.eql([
|
||||||
|
// [1] In a dialog, these are registered before the rest (which is in chronological dom order)
|
||||||
|
// Ideally, this should be the same. It would be once the platform allows to create dialogs
|
||||||
|
// that don't need to move content to the body
|
||||||
|
'lion-checkbox-group',
|
||||||
|
' lion-checkbox',
|
||||||
|
'lion-switch',
|
||||||
|
// [2] 'the rest' (chronologically ordered registrations)
|
||||||
'lion-fieldset',
|
'lion-fieldset',
|
||||||
'lion-input',
|
' lion-input',
|
||||||
'lion-input',
|
' lion-input',
|
||||||
|
|
||||||
'lion-input-date',
|
'lion-input-date',
|
||||||
|
|
||||||
'lion-input-datepicker',
|
'lion-input-datepicker',
|
||||||
|
|
||||||
'lion-textarea',
|
'lion-textarea',
|
||||||
|
|
||||||
'lion-input-amount',
|
'lion-input-amount',
|
||||||
|
|
||||||
'lion-input-iban',
|
'lion-input-iban',
|
||||||
|
|
||||||
'lion-input-email',
|
'lion-input-email',
|
||||||
|
|
||||||
'lion-checkbox-group',
|
'lion-checkbox-group',
|
||||||
'lion-checkbox',
|
' lion-checkbox',
|
||||||
'lion-checkbox',
|
' lion-checkbox',
|
||||||
'lion-checkbox',
|
' lion-checkbox',
|
||||||
|
|
||||||
'lion-radio-group',
|
'lion-radio-group',
|
||||||
'lion-radio',
|
' lion-radio',
|
||||||
'lion-radio',
|
' lion-radio',
|
||||||
'lion-radio',
|
' lion-radio',
|
||||||
|
|
||||||
'lion-listbox',
|
'lion-listbox',
|
||||||
'lion-option',
|
' lion-option',
|
||||||
'lion-option',
|
' lion-option',
|
||||||
'lion-option',
|
' lion-option',
|
||||||
|
|
||||||
'lion-combobox',
|
'lion-combobox',
|
||||||
'lion-option',
|
' lion-option',
|
||||||
'lion-option',
|
' lion-option',
|
||||||
'lion-option',
|
' lion-option',
|
||||||
'lion-option',
|
' lion-option',
|
||||||
'lion-option',
|
' lion-option',
|
||||||
'lion-option',
|
' lion-option',
|
||||||
|
|
||||||
'lion-select-rich',
|
'lion-select-rich',
|
||||||
'lion-option',
|
' lion-option',
|
||||||
'lion-option',
|
' lion-option',
|
||||||
'lion-option',
|
' lion-option',
|
||||||
'lion-select',
|
'lion-select',
|
||||||
|
|
||||||
'lion-input-range',
|
'lion-input-range',
|
||||||
|
// [3] this is where [1] should have been inserted
|
||||||
'lion-checkbox-group',
|
// [4] more of 'the rest' (chronologically ordered registrations)
|
||||||
'lion-checkbox',
|
'lion-input-stepper',
|
||||||
// 'lion-switch',
|
|
||||||
// 'lion-input-stepper',
|
|
||||||
'lion-textarea',
|
'lion-textarea',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
161
packages/form-integrations/test/form-group-methods.test.js
Normal file
161
packages/form-integrations/test/form-group-methods.test.js
Normal file
|
|
@ -0,0 +1,161 @@
|
||||||
|
import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
|
||||||
|
import './helpers/umbrella-form.js';
|
||||||
|
import { getAllFieldsAndFormGroups } from './helpers/helpers.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {import('@lion/form-core').LionField} LionField
|
||||||
|
* @typedef {import('@lion/button').LionButton} LionButton
|
||||||
|
* @typedef {import('./helpers/umbrella-form.js').UmbrellaForm} UmbrellaForm
|
||||||
|
*/
|
||||||
|
|
||||||
|
const fullyPrefilledSerializedValue = {
|
||||||
|
full_name: { first_name: 'Lorem', last_name: 'Ipsum' },
|
||||||
|
date: '2000-12-12',
|
||||||
|
datepicker: '2020-12-12',
|
||||||
|
bio: 'Lorem',
|
||||||
|
money: '12313.12',
|
||||||
|
iban: '123456',
|
||||||
|
email: 'a@b.com',
|
||||||
|
checkers: ['foo', 'bar'],
|
||||||
|
dinosaurs: 'brontosaurus',
|
||||||
|
favoriteFruit: 'Banana',
|
||||||
|
favoriteMovie: 'Rocky',
|
||||||
|
favoriteColor: 'hotpink',
|
||||||
|
lyrics: '1',
|
||||||
|
notifications: {
|
||||||
|
checked: true,
|
||||||
|
value: 'Lorem',
|
||||||
|
},
|
||||||
|
range: 2.3,
|
||||||
|
rsvp: 'Lorem',
|
||||||
|
terms: ['agreed'],
|
||||||
|
comments: 'Lorem',
|
||||||
|
};
|
||||||
|
|
||||||
|
const fullyChangedSerializedValue = {
|
||||||
|
full_name: { first_name: 'LoremChanged', last_name: 'IpsumChanged' },
|
||||||
|
date: '1999-12-12',
|
||||||
|
datepicker: '1986-12-12',
|
||||||
|
bio: 'LoremChanged',
|
||||||
|
money: '9912313.12',
|
||||||
|
iban: '99123456',
|
||||||
|
email: 'aChanged@b.com',
|
||||||
|
checkers: ['foo'],
|
||||||
|
dinosaurs: '',
|
||||||
|
favoriteFruit: '',
|
||||||
|
favoriteMovie: '',
|
||||||
|
favoriteColor: '',
|
||||||
|
lyrics: '2',
|
||||||
|
notifications: {
|
||||||
|
checked: false,
|
||||||
|
value: 'Lorem',
|
||||||
|
},
|
||||||
|
range: 3.3,
|
||||||
|
rsvp: 'LoremChanged',
|
||||||
|
terms: [],
|
||||||
|
comments: 'LoremChanged',
|
||||||
|
};
|
||||||
|
|
||||||
|
describe(`Submitting/Resetting/Clearing Form`, async () => {
|
||||||
|
it('pressing submit button of a form should make submitted true for all fields', async () => {
|
||||||
|
const el = /** @type {UmbrellaForm} */ (await fixture(html`<umbrella-form></umbrella-form>`));
|
||||||
|
await el.updateComplete;
|
||||||
|
const formEl = el._lionFormNode;
|
||||||
|
|
||||||
|
const allElements = getAllFieldsAndFormGroups(formEl);
|
||||||
|
|
||||||
|
allElements.forEach((/** @type {LionField} */ field) => {
|
||||||
|
if (field.tagName === 'LION-SWITCH') {
|
||||||
|
// TODO: remove this when this is fixed: https://github.com/ing-bank/lion/issues/1204
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// TODO: prefer submitted 'false' over 'undefined'
|
||||||
|
expect(Boolean(field.submitted)).to.be.false;
|
||||||
|
});
|
||||||
|
/** @type {LionButton} */ (formEl.querySelector('#submit_button')).click();
|
||||||
|
await elementUpdated(formEl);
|
||||||
|
await el.updateComplete;
|
||||||
|
allElements.forEach((/** @type {LionField} */ field) => {
|
||||||
|
expect(field.submitted).to.be.true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('calling resetGroup() should reset all metadata (interaction states and initial values)', async () => {
|
||||||
|
const el = /** @type {UmbrellaForm} */ (await fixture(
|
||||||
|
html`<umbrella-form .serializedValue="${fullyPrefilledSerializedValue}"></umbrella-form>`,
|
||||||
|
));
|
||||||
|
await el.updateComplete;
|
||||||
|
const formEl = el._lionFormNode;
|
||||||
|
|
||||||
|
/** @type {LionButton} */ (formEl.querySelector('#submit_button')).click();
|
||||||
|
await elementUpdated(formEl);
|
||||||
|
await formEl.updateComplete;
|
||||||
|
|
||||||
|
const allElements = getAllFieldsAndFormGroups(formEl);
|
||||||
|
|
||||||
|
allElements.forEach((/** @type {LionField} */ field) => {
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
|
field.touched = true;
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
|
field.dirty = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
formEl.serializedValue = fullyChangedSerializedValue;
|
||||||
|
|
||||||
|
allElements.forEach((/** @type {LionField} */ field) => {
|
||||||
|
expect(field.submitted).to.be.true;
|
||||||
|
expect(field.touched).to.be.true;
|
||||||
|
expect(field.dirty).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
/** @type {LionButton} */ (formEl.querySelector('#reset_button')).click();
|
||||||
|
await elementUpdated(formEl);
|
||||||
|
await formEl.updateComplete;
|
||||||
|
expect(formEl.submitted).to.be.false;
|
||||||
|
|
||||||
|
allElements.forEach((/** @type {LionField} */ field) => {
|
||||||
|
expect(field.submitted).to.be.false;
|
||||||
|
expect(field.touched).to.be.false;
|
||||||
|
expect(field.dirty).to.be.false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO: investigate why this doesn't work
|
||||||
|
// expect(formEl.serializedValue).to.eql(fullyPrefilledSerializedValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Wait till ListboxMixin properly clears
|
||||||
|
it('calling clearGroup() should clear all fields', async () => {
|
||||||
|
const el = /** @type {UmbrellaForm} */ (await fixture(
|
||||||
|
html`<umbrella-form .serializedValue="${fullyPrefilledSerializedValue}"></umbrella-form>`,
|
||||||
|
));
|
||||||
|
await el.updateComplete;
|
||||||
|
const formEl = el._lionFormNode;
|
||||||
|
|
||||||
|
formEl.clearGroup();
|
||||||
|
await elementUpdated(formEl);
|
||||||
|
await formEl.updateComplete;
|
||||||
|
expect(formEl.serializedValue).to.eql({
|
||||||
|
full_name: { first_name: '', last_name: '' },
|
||||||
|
date: '',
|
||||||
|
datepicker: '',
|
||||||
|
bio: '',
|
||||||
|
money: '',
|
||||||
|
iban: '',
|
||||||
|
email: '',
|
||||||
|
checkers: [],
|
||||||
|
dinosaurs: '',
|
||||||
|
favoriteFruit: '',
|
||||||
|
favoriteMovie: '',
|
||||||
|
favoriteColor: '',
|
||||||
|
lyrics: '',
|
||||||
|
notifications: {
|
||||||
|
checked: false,
|
||||||
|
value: 'Lorem',
|
||||||
|
},
|
||||||
|
range: '',
|
||||||
|
rsvp: '',
|
||||||
|
terms: [],
|
||||||
|
comments: '',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { expect, fixture, html } from '@open-wc/testing';
|
import { expect, fixture, html } from '@open-wc/testing';
|
||||||
|
import { getAllTagNames } from './helpers/helpers.js';
|
||||||
import './helpers/umbrella-form.js';
|
import './helpers/umbrella-form.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -28,6 +29,8 @@ describe('Form Integrations', () => {
|
||||||
lyrics: '1',
|
lyrics: '1',
|
||||||
range: 2.3,
|
range: 2.3,
|
||||||
terms: [],
|
terms: [],
|
||||||
|
notifications: { value: '', checked: false },
|
||||||
|
rsvp: '',
|
||||||
comments: '',
|
comments: '',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -36,6 +39,7 @@ describe('Form Integrations', () => {
|
||||||
const el = /** @type {UmbrellaForm} */ (await fixture(html`<umbrella-form></umbrella-form>`));
|
const el = /** @type {UmbrellaForm} */ (await fixture(html`<umbrella-form></umbrella-form>`));
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
const formEl = el._lionFormNode;
|
const formEl = el._lionFormNode;
|
||||||
|
|
||||||
expect(formEl.formattedValue).to.eql({
|
expect(formEl.formattedValue).to.eql({
|
||||||
full_name: { first_name: '', last_name: '' },
|
full_name: { first_name: '', last_name: '' },
|
||||||
date: '12/12/2000',
|
date: '12/12/2000',
|
||||||
|
|
@ -52,6 +56,8 @@ describe('Form Integrations', () => {
|
||||||
lyrics: '1',
|
lyrics: '1',
|
||||||
range: 2.3,
|
range: 2.3,
|
||||||
terms: [],
|
terms: [],
|
||||||
|
notifications: '',
|
||||||
|
rsvp: '',
|
||||||
comments: '',
|
comments: '',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -86,73 +92,52 @@ describe('Form Integrations', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('"Successfully registers all form components', async () => {
|
it('Successfully registers all form components', async () => {
|
||||||
const el = /** @type {UmbrellaForm} */ await fixture(html`<umbrella-form></umbrella-form>`);
|
const el = /** @type {UmbrellaForm} */ await fixture(html`<umbrella-form></umbrella-form>`);
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const formEl = /** @type {LionForm} */ (el._lionFormNode);
|
const formEl = /** @type {LionForm} */ (el._lionFormNode);
|
||||||
const getTagNames = (/** @type {HTMLElement} */ elm) => [
|
await formEl.registrationComplete;
|
||||||
elm.tagName.toLowerCase(),
|
const registeredEls = getAllTagNames(formEl);
|
||||||
// @ts-ignore
|
|
||||||
...(elm.formElements ? elm.formElements.map(getTagNames).flat() : []),
|
|
||||||
];
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
const registeredEls = formEl.formElements.map(getTagNames).flat();
|
|
||||||
|
|
||||||
// TODO: fix registration of lion-switch and lion-input-stepper
|
|
||||||
expect(registeredEls).to.eql([
|
expect(registeredEls).to.eql([
|
||||||
'lion-fieldset',
|
'lion-fieldset',
|
||||||
'lion-input',
|
' lion-input',
|
||||||
'lion-input',
|
' lion-input',
|
||||||
|
|
||||||
'lion-input-date',
|
'lion-input-date',
|
||||||
|
|
||||||
'lion-input-datepicker',
|
'lion-input-datepicker',
|
||||||
|
|
||||||
'lion-textarea',
|
'lion-textarea',
|
||||||
|
|
||||||
'lion-input-amount',
|
'lion-input-amount',
|
||||||
|
|
||||||
'lion-input-iban',
|
'lion-input-iban',
|
||||||
|
|
||||||
'lion-input-email',
|
'lion-input-email',
|
||||||
|
|
||||||
'lion-checkbox-group',
|
'lion-checkbox-group',
|
||||||
'lion-checkbox',
|
' lion-checkbox',
|
||||||
'lion-checkbox',
|
' lion-checkbox',
|
||||||
'lion-checkbox',
|
' lion-checkbox',
|
||||||
|
|
||||||
'lion-radio-group',
|
'lion-radio-group',
|
||||||
'lion-radio',
|
' lion-radio',
|
||||||
'lion-radio',
|
' lion-radio',
|
||||||
'lion-radio',
|
' lion-radio',
|
||||||
|
|
||||||
'lion-listbox',
|
'lion-listbox',
|
||||||
'lion-option',
|
' lion-option',
|
||||||
'lion-option',
|
' lion-option',
|
||||||
'lion-option',
|
' lion-option',
|
||||||
|
|
||||||
'lion-combobox',
|
'lion-combobox',
|
||||||
'lion-option',
|
' lion-option',
|
||||||
'lion-option',
|
' lion-option',
|
||||||
'lion-option',
|
' lion-option',
|
||||||
'lion-option',
|
' lion-option',
|
||||||
'lion-option',
|
' lion-option',
|
||||||
'lion-option',
|
' lion-option',
|
||||||
|
|
||||||
'lion-select-rich',
|
'lion-select-rich',
|
||||||
'lion-option',
|
' lion-option',
|
||||||
'lion-option',
|
' lion-option',
|
||||||
'lion-option',
|
' lion-option',
|
||||||
'lion-select',
|
'lion-select',
|
||||||
|
|
||||||
'lion-input-range',
|
'lion-input-range',
|
||||||
|
|
||||||
'lion-checkbox-group',
|
'lion-checkbox-group',
|
||||||
'lion-checkbox',
|
' lion-checkbox',
|
||||||
// 'lion-switch',
|
'lion-switch',
|
||||||
// 'lion-input-stepper',
|
'lion-input-stepper',
|
||||||
'lion-textarea',
|
'lion-textarea',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,143 +0,0 @@
|
||||||
import '@lion/button/define';
|
|
||||||
import '@lion/checkbox-group/define';
|
|
||||||
import { MinLength, Required } from '@lion/form-core';
|
|
||||||
import '@lion/form/define';
|
|
||||||
import '@lion/input-amount/define';
|
|
||||||
import '@lion/input-date/define';
|
|
||||||
import '@lion/input-datepicker/define';
|
|
||||||
import '@lion/input-email/define';
|
|
||||||
import '@lion/input-iban/define';
|
|
||||||
import '@lion/input-range/define';
|
|
||||||
import '@lion/input/define';
|
|
||||||
import '@lion/radio-group/define';
|
|
||||||
import '@lion/select/define';
|
|
||||||
import '@lion/switch/define';
|
|
||||||
import '@lion/textarea/define';
|
|
||||||
import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
|
|
||||||
|
|
||||||
describe(`Submitting/Resetting Form`, async () => {
|
|
||||||
/** @type {import('@lion/form').LionForm} */
|
|
||||||
let el;
|
|
||||||
beforeEach(async () => {
|
|
||||||
el = await fixture(html`
|
|
||||||
<lion-form id="form_test" responsive>
|
|
||||||
<form>
|
|
||||||
<lion-input
|
|
||||||
name="first_name"
|
|
||||||
label="First Name"
|
|
||||||
.validators="${[new Required()]}"
|
|
||||||
></lion-input>
|
|
||||||
<lion-input
|
|
||||||
name="last_name"
|
|
||||||
label="Last Name"
|
|
||||||
.validators="${[new Required()]}"
|
|
||||||
></lion-input>
|
|
||||||
<lion-input-date
|
|
||||||
name="start-date"
|
|
||||||
label="Start date"
|
|
||||||
.validators="${[new Required()]}"
|
|
||||||
></lion-input-date>
|
|
||||||
<lion-input-datepicker
|
|
||||||
name="end-date"
|
|
||||||
label="End date"
|
|
||||||
.validators="${[new Required()]}"
|
|
||||||
></lion-input-datepicker>
|
|
||||||
<lion-textarea
|
|
||||||
name="bio"
|
|
||||||
label="Biography"
|
|
||||||
.validators="${[new Required(), new MinLength(10)]}"
|
|
||||||
help-text="Please enter at least 10 characters"
|
|
||||||
></lion-textarea>
|
|
||||||
<lion-input-amount
|
|
||||||
.validators="${[new Required()]}"
|
|
||||||
name="money"
|
|
||||||
label="Money"
|
|
||||||
></lion-input-amount>
|
|
||||||
<lion-input-iban
|
|
||||||
.validators="${[new Required()]}"
|
|
||||||
name="iban"
|
|
||||||
label="Iban"
|
|
||||||
></lion-input-iban>
|
|
||||||
<lion-input-email
|
|
||||||
.validators="${[new Required()]}"
|
|
||||||
name="email"
|
|
||||||
label="Email"
|
|
||||||
></lion-input-email>
|
|
||||||
<lion-checkbox-group
|
|
||||||
label="What do you like?"
|
|
||||||
name="checkers[]"
|
|
||||||
.validators="${[new Required()]}"
|
|
||||||
>
|
|
||||||
<lion-checkbox .choiceValue=${'foo'} label="I like foo"></lion-checkbox>
|
|
||||||
<lion-checkbox .choiceValue=${'bar'} label="I like bar"></lion-checkbox>
|
|
||||||
<lion-checkbox .choiceValue=${'baz'} label="I like baz"></lion-checkbox>
|
|
||||||
</lion-checkbox-group>
|
|
||||||
<lion-radio-group
|
|
||||||
name="dinosaurs"
|
|
||||||
label="Favorite dinosaur"
|
|
||||||
.validators="${[new Required()]}"
|
|
||||||
>
|
|
||||||
<lion-radio .choiceValue=${'allosaurus'} label="allosaurus"></lion-radio>
|
|
||||||
<lion-radio .choiceValue=${'brontosaurus'} label="brontosaurus"></lion-radio>
|
|
||||||
<lion-radio .choiceValue=${'diplodocus'} label="diplodocus"></lion-radio>
|
|
||||||
</lion-radio-group>
|
|
||||||
<lion-select label="Lyrics" name="lyrics" .validators="${[new Required()]}">
|
|
||||||
<select slot="input">
|
|
||||||
<option value="1">Fire up that loud</option>
|
|
||||||
<option value="2">Another round of shots...</option>
|
|
||||||
<option value="3">Drop down for what?</option>
|
|
||||||
</select>
|
|
||||||
</lion-select>
|
|
||||||
<lion-input-range
|
|
||||||
.validators="${[new Required()]}"
|
|
||||||
name="range"
|
|
||||||
min="1"
|
|
||||||
max="5"
|
|
||||||
unit="%"
|
|
||||||
step="0.1"
|
|
||||||
label="Input range"
|
|
||||||
></lion-input-range>
|
|
||||||
<lion-checkbox-group
|
|
||||||
name="terms[]"
|
|
||||||
.validators="${[
|
|
||||||
new Required(null, { getMessage: () => 'You are not allowed to read them' }),
|
|
||||||
]}"
|
|
||||||
>
|
|
||||||
<lion-checkbox label="I blindly accept all terms and conditions"></lion-checkbox>
|
|
||||||
</lion-checkbox-group>
|
|
||||||
<lion-textarea
|
|
||||||
.validators="${[new Required()]}"
|
|
||||||
name="comments"
|
|
||||||
label="Comments"
|
|
||||||
></lion-textarea>
|
|
||||||
<div class="buttons">
|
|
||||||
<lion-button id="submit_button" type="submit" raised>Submit</lion-button>
|
|
||||||
<lion-button id="reset_button" type="reset" raised> Reset </lion-button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</lion-form>
|
|
||||||
`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Submitting a form should make submitted true for all fields', async () => {
|
|
||||||
/** @type {import('@lion/button').LionButton} */ (el.querySelector('#submit_button')).click();
|
|
||||||
await elementUpdated(el);
|
|
||||||
await el.updateComplete;
|
|
||||||
el.formElements.forEach(field => {
|
|
||||||
expect(field.submitted).to.be.true;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Resetting a form should reset metadata of all fields', async () => {
|
|
||||||
/** @type {import('@lion/button').LionButton} */ (el.querySelector('#submit_button')).click();
|
|
||||||
/** @type {import('@lion/button').LionButton} */ (el.querySelector('#reset_button')).click();
|
|
||||||
await elementUpdated(el);
|
|
||||||
await el.updateComplete;
|
|
||||||
expect(el.submitted).to.be.false;
|
|
||||||
el.formElements.forEach(field => {
|
|
||||||
expect(field.submitted).to.be.false;
|
|
||||||
expect(field.touched).to.be.false;
|
|
||||||
expect(field.dirty).to.be.false;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
40
packages/form-integrations/test/helpers/helpers.js
Normal file
40
packages/form-integrations/test/helpers/helpers.js
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
/**
|
||||||
|
* @typedef {import('@lion/form').LionForm} LionForm
|
||||||
|
* @typedef {import('@lion/form-core').LionField} LionField
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {LionForm} formGroupEl
|
||||||
|
*/
|
||||||
|
export function getAllFormElements(formGroupEl) {
|
||||||
|
const getElms = (/** @type {HTMLElement} */ elm) => [
|
||||||
|
elm,
|
||||||
|
// @ts-ignore
|
||||||
|
...(elm.formElements ? elm.formElements.map(getElms).flat() : []),
|
||||||
|
];
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
return formGroupEl.formElements.map(elem => getElms(elem)).flat();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {LionForm} formGroupEl
|
||||||
|
*/
|
||||||
|
export function getAllTagNames(formGroupEl) {
|
||||||
|
const getTagNames = (/** @type {HTMLElement} */ elm, lvl = 0) => [
|
||||||
|
` `.repeat(lvl) + elm.tagName.toLowerCase(),
|
||||||
|
// @ts-ignore
|
||||||
|
...(elm.formElements ? elm.formElements.map(elem => getTagNames(elem, lvl + 1)).flat() : []),
|
||||||
|
];
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
return formGroupEl.formElements.map(elem => getTagNames(elem)).flat();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {LionForm} formGroupEl
|
||||||
|
*/
|
||||||
|
export function getAllFieldsAndFormGroups(formGroupEl) {
|
||||||
|
const allElements = getAllFormElements(formGroupEl);
|
||||||
|
return allElements.filter((/** @type {LionField} */ elm) => elm.tagName !== 'LION-OPTION');
|
||||||
|
}
|
||||||
|
|
@ -17,6 +17,8 @@ import '@lion/combobox/define';
|
||||||
import '@lion/input-range/define';
|
import '@lion/input-range/define';
|
||||||
import '@lion/textarea/define';
|
import '@lion/textarea/define';
|
||||||
import '@lion/button/define';
|
import '@lion/button/define';
|
||||||
|
import '@lion/switch/define';
|
||||||
|
import '@lion/input-stepper/define';
|
||||||
|
|
||||||
export class UmbrellaForm extends LitElement {
|
export class UmbrellaForm extends LitElement {
|
||||||
get _lionFormNode() {
|
get _lionFormNode() {
|
||||||
|
|
@ -131,7 +133,10 @@ export class UmbrellaForm extends LitElement {
|
||||||
name="terms"
|
name="terms"
|
||||||
.validators="${[new Required()]}"
|
.validators="${[new Required()]}"
|
||||||
>
|
>
|
||||||
<lion-checkbox label="I blindly accept all terms and conditions"></lion-checkbox>
|
<lion-checkbox
|
||||||
|
.choiceValue="agreed"
|
||||||
|
label="I blindly accept all terms and conditions"
|
||||||
|
></lion-checkbox>
|
||||||
</lion-checkbox-group>
|
</lion-checkbox-group>
|
||||||
<lion-switch name="notifications" label="Notifications"></lion-switch>
|
<lion-switch name="notifications" label="Notifications"></lion-switch>
|
||||||
<lion-input-stepper max="5" min="0" name="rsvp">
|
<lion-input-stepper max="5" min="0" name="rsvp">
|
||||||
|
|
@ -140,13 +145,14 @@ export class UmbrellaForm extends LitElement {
|
||||||
</lion-input-stepper>
|
</lion-input-stepper>
|
||||||
<lion-textarea name="comments" label="Comments"></lion-textarea>
|
<lion-textarea name="comments" label="Comments"></lion-textarea>
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<lion-button raised>Submit</lion-button>
|
<lion-button id="submit_button" raised>Submit</lion-button>
|
||||||
<lion-button
|
<lion-button
|
||||||
|
id="reset_button"
|
||||||
type="button"
|
type="button"
|
||||||
raised
|
raised
|
||||||
@click=${(/** @type {Event} */ ev) =>
|
@click="${() => {
|
||||||
// @ts-ignore
|
this._lionFormNode.resetGroup();
|
||||||
ev.currentTarget.parentElement.parentElement.parentElement.resetGroup()}
|
}}"
|
||||||
>Reset</lion-button
|
>Reset</lion-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,14 @@ import '@lion/input-datepicker/define';
|
||||||
import '@lion/input-email/define';
|
import '@lion/input-email/define';
|
||||||
import '@lion/input-iban/define';
|
import '@lion/input-iban/define';
|
||||||
import '@lion/input-range/define';
|
import '@lion/input-range/define';
|
||||||
|
import '@lion/input-stepper/define';
|
||||||
|
|
||||||
import '@lion/textarea/define';
|
import '@lion/textarea/define';
|
||||||
|
|
||||||
import '@lion/checkbox-group/define';
|
import '@lion/checkbox-group/define';
|
||||||
|
|
||||||
import '@lion/radio-group/define';
|
import '@lion/radio-group/define';
|
||||||
|
import '@lion/switch/define';
|
||||||
|
|
||||||
import '@lion/select/define';
|
import '@lion/select/define';
|
||||||
|
|
||||||
|
|
@ -343,11 +346,13 @@ describe('detail.isTriggeredByUser', () => {
|
||||||
'input-email',
|
'input-email',
|
||||||
'input-iban',
|
'input-iban',
|
||||||
'input-range',
|
'input-range',
|
||||||
|
'input-stepper',
|
||||||
'textarea',
|
'textarea',
|
||||||
// 1b) Choice Fields
|
// 1b) Choice Fields
|
||||||
'option',
|
'option',
|
||||||
'checkbox',
|
'checkbox',
|
||||||
'radio',
|
'radio',
|
||||||
|
'switch',
|
||||||
// 1c) Choice Group Fields
|
// 1c) Choice Group Fields
|
||||||
'select',
|
'select',
|
||||||
'listbox',
|
'listbox',
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue