chore: enhanced docs and enabled integration test forms

This commit is contained in:
Thijs Louisse 2020-02-20 14:47:45 +01:00
parent ffa4da9649
commit d81764e9fd
6 changed files with 100 additions and 88 deletions

View file

@ -4,6 +4,7 @@ import '@lion/fieldset/lion-fieldset.js';
import '@lion/form/lion-form.js'; import '@lion/form/lion-form.js';
import '@lion/input-amount/lion-input-amount.js'; import '@lion/input-amount/lion-input-amount.js';
import '@lion/input-date/lion-input-date.js'; import '@lion/input-date/lion-input-date.js';
import '@lion/input-datepicker/lion-input-datepicker.js';
import '@lion/input-email/lion-input-email.js'; import '@lion/input-email/lion-input-email.js';
import '@lion/input-iban/lion-input-iban.js'; import '@lion/input-iban/lion-input-iban.js';
import '@lion/input-range/lion-input-range.js'; import '@lion/input-range/lion-input-range.js';
@ -28,9 +29,12 @@ For usage and installation please see the appropriate packages.
<Preview> <Preview>
<Story name="Example"> <Story name="Example">
{html` {() => {
Required.getMessage = () => 'Please enter a value';
return html`
<lion-form> <lion-form>
<form> <form>
<lion-fieldset name="full_name">
<lion-input <lion-input
name="first_name" name="first_name"
label="First Name" label="First Name"
@ -41,12 +45,19 @@ For usage and installation please see the appropriate packages.
label="Last Name" label="Last Name"
.validators="${[new Required()]}" .validators="${[new Required()]}"
></lion-input> ></lion-input>
</lion-fieldset>
<lion-input-date <lion-input-date
name="date" name="date"
label="Date of application" label="Date of application"
.modelValue="${new Date('2000-12-12')}" .modelValue="${new Date('2000-12-12')}"
.validators="${[new Required()]}" .validators="${[new Required()]}"
></lion-input-date> ></lion-input-date>
<lion-input-datepicker
name="datepicker"
label="Date to be picked"
.modelValue="${new Date('2020-12-12')}"
.validators="${[new Required()]}"
></lion-input-datepicker>
<lion-textarea <lion-textarea
name="bio" name="bio"
label="Biography" label="Biography"
@ -58,7 +69,7 @@ For usage and installation please see the appropriate packages.
<lion-input-email name="email" label="Email"></lion-input-email> <lion-input-email name="email" label="Email"></lion-input-email>
<lion-checkbox-group <lion-checkbox-group
label="What do you like?" label="What do you like?"
name="checkers[]" name="checkers"
.validators="${[new Required()]}" .validators="${[new Required()]}"
> >
<lion-checkbox .choiceValue=${'foo'} label="I like foo"></lion-checkbox> <lion-checkbox .choiceValue=${'foo'} label="I like foo"></lion-checkbox>
@ -101,7 +112,7 @@ For usage and installation please see the appropriate packages.
step="0.1" step="0.1"
label="Input range" label="Input range"
></lion-input-range> ></lion-input-range>
<lion-checkbox-group name="terms" .validators="${[new Required()]}"> <lion-checkbox-group .mulipleChoice="${false}" name="terms" .validators="${[new Required()]}">
<lion-checkbox <lion-checkbox
label="I blindly accept all terms and conditions" label="I blindly accept all terms and conditions"
></lion-checkbox> ></lion-checkbox>
@ -118,7 +129,7 @@ For usage and installation please see the appropriate packages.
</div> </div>
</form> </form>
</lion-form> </lion-form>
`} `;}}
</Story> </Story>
</Preview> </Preview>
@ -129,6 +140,7 @@ import '@lion/fieldset/lion-fieldset.js';
import '@lion/form/lion-form.js'; import '@lion/form/lion-form.js';
import '@lion/input-amount/lion-input-amount.js'; import '@lion/input-amount/lion-input-amount.js';
import '@lion/input-date/lion-input-date.js'; import '@lion/input-date/lion-input-date.js';
import '@lion/input-datepicker/lion-input-datepicker.js';
import '@lion/input-email/lion-input-email.js'; import '@lion/input-email/lion-input-email.js';
import '@lion/input-iban/lion-input-iban.js'; import '@lion/input-iban/lion-input-iban.js';
import '@lion/input-range/lion-input-range.js'; import '@lion/input-range/lion-input-range.js';

View file

@ -29,8 +29,10 @@ import {
## Required Validator ## Required Validator
The required validator can be put onto every form field element and will make sure that element is not empty. The required validator can be put onto every form field element and will make sure that element is
For an input that may mean that it is not an empty string while for a checkbox group it means at least one checkbox needs to be checked. not empty.
For an input that may mean that it is not an empty string,
while for a checkbox group it means at least one checkbox needs to be checked.
<Story name="Required Validator"> <Story name="Required Validator">
{html` {html`

View file

@ -26,7 +26,7 @@ it has a tabindex=“0” applied.
Now we want to integrate the slider in our form framework to enrich the user interface, get Now we want to integrate the slider in our form framework to enrich the user interface, get
validation support and get all the other [benefits of LionField](/?path=/docs/forms-system-overview--page). validation support and get all the other [benefits of LionField](/?path=/docs/forms-system-overview--page).
We start of by creating a component `<lion-slider>` that extends from `LionField`. We start by creating a component `<lion-slider>` that extends from `LionField`.
Then we follow the steps below: Then we follow the steps below:
#### 1. Add your interaction element as input slot' #### 1. Add your interaction element as input slot'

View file

@ -298,7 +298,7 @@ Alternatively you can also let the fieldset validator be dependent on the error
Simply loop over the formElements inside your Validator's `execute` method: Simply loop over the formElements inside your Validator's `execute` method:
```js ```js
this.formElementsArray.some(el => el.hasFeedbackFor.includes('error')); this.formElements.some(el => el.hasFeedbackFor.includes('error'));
``` ```
### Validating multiple fieldsets ### Validating multiple fieldsets

View file

@ -1,4 +1,4 @@
import { Story, Meta, html } from '@open-wc/demoing-storybook'; import { Story, Meta, html, Preview } from '@open-wc/demoing-storybook';
import { Required, MaxLength, loadDefaultFeedbackMessages } from '@lion/validate'; import { Required, MaxLength, loadDefaultFeedbackMessages } from '@lion/validate';
import '@lion/fieldset/lion-fieldset.js'; import '@lion/fieldset/lion-fieldset.js';
import '@lion/input/lion-input.js'; import '@lion/input/lion-input.js';
@ -10,6 +10,7 @@ import '@lion/form/lion-form.js';
A form can have multiple nested fieldsets. A form can have multiple nested fieldsets.
<Preview>
<Story name="Default"> <Story name="Default">
{html` {html`
<lion-form id="form"> <lion-form id="form">
@ -25,48 +26,38 @@ A form can have multiple nested fieldsets.
</lion-fieldset> </lion-fieldset>
<lion-input name="birthdate" label="Birthdate" .modelValue=${'23-04-1991'}></lion-input> <lion-input name="birthdate" label="Birthdate" .modelValue=${'23-04-1991'}></lion-input>
</lion-fieldset> </lion-fieldset>
<button type="button" @click=${() => console.log(document.querySelector('#form').serializeGroup())}> <button type="button" @click=${() => console.log(document.querySelector('#form').serializedValue)}>
Log to Action Logger Log to Action Logger
</button> </button>
</form> </form>
</lion-form> </lion-form>
`} `}
</Story> </Story>
</Preview>
```html
<lion-form id="form">
<form>
<lion-fieldset label="Personal data" name="personalData">
<lion-fieldset label="Full Name" name="fullName">
<lion-input name="firstName" label="First Name" .modelValue=${'Foo'}></lion-input>
<lion-input name="lastName" label="Last Name" .modelValue=${'Bar'}></lion-input>
</lion-fieldset>
<lion-fieldset label="Location" name="location">
<lion-input name="country" label="Country" .modelValue=${'Netherlands'}></lion-input>
<lion-input name="city" label="City" .modelValue=${'Amsterdam'}></lion-input>
</lion-fieldset>
<lion-input name="birthdate" label="Birthdate" .modelValue=${'23-04-1991'}></lion-input>
</lion-fieldset>
<button type="button" @click=${() => console.log(document.querySelector('#form').serializeGroup())}>
Log to Action Logger
</button>
</form>
</lion-form>
```
## Form Submit / Reset ## Form Submit / Reset
You can control whether a form gets submitted based on validation states. You can control whether a form gets submitted based on validation states.
Same thing goes for resetting the inputs to the original state. Same thing goes for resetting the inputs to the original state.
Be sure to call `serializedValue` when a you want to submit a form.
This value automatically filters out disabled children and makes sure the values
that are retrieved can be transmitted over a wire. (for instance, an input-date with a modelValue
of type `Date` will be serialized to an iso formatted string).
> Note: Offering a reset button is a bad practice in terms of accessibility.
This button is only used here to demonstrate the `serializeGroup()` method.
<Preview>
<Story name="Submit/reset"> <Story name="Submit/reset">
{() => { {() => {
loadDefaultFeedbackMessages(); loadDefaultFeedbackMessages();
const submit = () => { const submit = () => {
const form = document.querySelector('#form2'); const form = document.querySelector('#form2');
if (!form.hasFeedbackFor.includes('error')) { if (!form.hasFeedbackFor.includes('error')) {
console.log(form.serializeGroup()); document.getElementById('form2_output').innerText = JSON.stringify(form.serializedValue);
form.resetGroup(); document.querySelector('#form2').resetGroup();
} }
}; };
return html` return html`
@ -85,58 +76,65 @@ Same thing goes for resetting the inputs to the original state.
.validators=${[new Required(), new MaxLength(15)]} .validators=${[new Required(), new MaxLength(15)]}
> >
</lion-input> </lion-input>
<lion-input
name="address"
disabled
label="Address"
.validators=${[new MaxLength(15)]}
>
</lion-input>
</lion-fieldset> </lion-fieldset>
<button type="submit">Submit & Reset (if successfully submitted)</button> <button type="submit">Submit & Reset (if successfully submitted)</button>
<button type="button" @click=${() => document.querySelector('#form2').resetGroup()}> <button type="button" @click=${() => {
Reset document.querySelector('#form2').resetGroup();
const form = document.querySelector('#form2');
document.getElementById('form2_output').innerText = JSON.stringify(form.serializedValue);
}}>
reset
</button> </button>
<p> <pre id="form2_output">
A reset button should never be offered to users. This button is only used here to </pre>
demonstrate the functionality.
</p>
</form></lion-form </form></lion-form
> >
`; `;
}} }}
</Story> </Story>
</Preview>
```js
import { Required, MaxLength } from '@lion/validate'
const submit = () => {
const form = document.querySelector('#form2'); ## Serialize in a multistep form
In a multistep form (consisting of multiple forms) it might be handy to wrap the serialized output
with the name of the form.
<Preview>
<Story name="Multistep">
{() => {
loadDefaultFeedbackMessages();
const serializeWithName = (formId, outputId) => {
const form = document.getElementById(formId);
if (!form.hasFeedbackFor.includes('error')) { if (!form.hasFeedbackFor.includes('error')) {
console.log(form.serializeGroup()); const output = { [form.name]: form.serializedValue };
form.resetGroup(); document.getElementById(outputId).innerText = JSON.stringify(output);
} }
}; };
``` return html`
<lion-form name="step1FormName" id="form3"><form>
```html <lion-input name="step1InputName" label="Step 1 Input"></lion-input>
<lion-form id="form2" @submit="${submit}"> <button @click="${() => serializeWithName('form3', 'form3_output')}">
<form> serialize step 1 with name
<lion-fieldset label="Name" name="name">
<lion-input
name="firstName"
label="First Name"
.validators=${[new Required(), new MaxLength(15)]}
>
</lion-input>
<lion-input
name="lastName"
label="Last Name"
.validators=${[new Required(), new MaxLength(15)]}
>
</lion-input>
</lion-fieldset>
<button type="submit">Submit & Reset (if successfully submitted)</button>
<button type="button" @click=${() => console.log(document.querySelector('#form2'))}>
Reset
</button> </button>
<p> <pre id="form3_output"></pre>
A reset button should never be offered to users. This button is only used here to </form></lion-form>
demonstrate the functionality. <lion-form name="step2FormName" id="form4"><form>
</p> <lion-input name="step2InputName" label="Step 2 Input"></lion-input>
</form> <button @click="${() => serializeWithName('form4', 'form4_output')}">
</lion-form> serialize step 2 with name
``` </button>
<pre id="form4_output"></pre>
</form></lion-form>
`;
}}
</Story>
</Preview>

View file

@ -3,7 +3,7 @@ import './helpers/umbrella-form.js';
// Test umbrella form // Test umbrella form
describe('Form Integrations', () => { describe('Form Integrations', () => {
it.skip('".serializedValue" returns all non disabled fields based on form structure', async () => { it('".serializedValue" returns all non disabled fields based on form structure', async () => {
const el = await fixture( const el = await fixture(
html` html`
<umbrella-form></umbrella-form> <umbrella-form></umbrella-form>