393 lines
11 KiB
Text
393 lines
11 KiB
Text
import { Story, Meta, html } from '@open-wc/demoing-storybook';
|
|
import '@lion/input/lion-input.js';
|
|
import { localize } from '@lion/localize';
|
|
import { loadDefaultFeedbackMessages, MinLength, Validator, Required } from '@lion/validate';
|
|
import '@lion/fieldset/lion-fieldset.js';
|
|
|
|
<Meta title="Forms/Fieldset/Examples" parameters={{ component: 'lion-fieldset' }} />
|
|
|
|
# Fieldset Examples
|
|
|
|
<Story name="Default">
|
|
{html`
|
|
<style>
|
|
lion-fieldset {
|
|
margin-top: 20px;
|
|
}
|
|
</style>
|
|
<lion-fieldset name="nameGroup" label="Name">
|
|
<lion-input name="FirstName" label="First Name"></lion-input>
|
|
<lion-input name="LastName" label="Last Name"></lion-input>
|
|
</lion-fieldset>
|
|
`}
|
|
</Story>
|
|
|
|
```html
|
|
<lion-fieldset name="nameGroup" label="Name">
|
|
<lion-input name="FirstName" label="First Name"></lion-input>
|
|
<lion-input name="LastName" label="Last Name"></lion-input>
|
|
</lion-fieldset>
|
|
```
|
|
|
|
### With Data
|
|
|
|
The fieldset's modelValue is an `Object` containing properties where the key is the `name` attribute of the field,
|
|
and the value is the `modelValue` of the field.
|
|
|
|
<Story name="Data">
|
|
{html`
|
|
<lion-fieldset name="nameGroup" label="Name">
|
|
<lion-input name="firstName" label="First Name" .modelValue=${'Foo'}></lion-input>
|
|
<lion-input name="lastName" label="Last Name" .modelValue=${'Bar'}></lion-input>
|
|
<button @click=${ev => console.log(ev.target.parentElement.modelValue)}>
|
|
Log to Action Logger
|
|
</button>
|
|
</lion-fieldset>
|
|
`}
|
|
</Story>
|
|
|
|
```html
|
|
<lion-fieldset name="nameGroup" label="Name">
|
|
<lion-input name="firstName" label="First Name" .modelValue=${'Foo'}></lion-input>
|
|
<lion-input name="lastName" label="Last Name" .modelValue=${'Bar'}></lion-input>
|
|
<button @click=${ev => console.log(ev.target.parentElement.modelValue)}>
|
|
Log to Action Logger
|
|
</button>
|
|
</lion-fieldset>
|
|
```
|
|
|
|
### Disabled
|
|
|
|
Disabling a fieldset disables all its child fields.
|
|
When enabling a fieldset, fields that have disabled explicitly set will stay disabled.
|
|
|
|
<Story name="Disabled">
|
|
{() => {
|
|
function toggleDisabled() {
|
|
const fieldset = document.querySelector('#fieldset');
|
|
fieldset.disabled = !fieldset.disabled;
|
|
}
|
|
return html`
|
|
<lion-fieldset name="nameGroup" label="Name" id="fieldset" disabled>
|
|
<lion-input name="FirstName" label="First Name" .modelValue=${'Foo'}></lion-input>
|
|
<lion-input name="LastName" label="Last Name" .modelValue=${'Bar'}></lion-input>
|
|
<lion-fieldset name="nameGroup2" label="Name">
|
|
<lion-input
|
|
name="FirstName2"
|
|
label="First Name"
|
|
.modelValue=${'Foo'}
|
|
disabled
|
|
></lion-input>
|
|
<lion-input name="LastName2" label="Last Name" .modelValue=${'Bar'}></lion-input>
|
|
</lion-fieldset>
|
|
</lion-fieldset>
|
|
<button @click=${toggleDisabled}>
|
|
Toggle disabled
|
|
</button>
|
|
`;
|
|
}}
|
|
</Story>
|
|
|
|
```js
|
|
function toggleDisabled() {
|
|
const fieldset = document.querySelector('#fieldset');
|
|
fieldset.disabled = !fieldset.disabled;
|
|
}
|
|
```
|
|
|
|
```html
|
|
<lion-fieldset name="nameGroup" label="Name" id="fieldset" disabled>
|
|
<lion-input name="FirstName" label="First Name" .modelValue=${'Foo'}></lion-input>
|
|
<lion-input name="LastName" label="Last Name" .modelValue=${'Bar'}></lion-input>
|
|
<lion-fieldset name="nameGroup2" label="Name">
|
|
<lion-input
|
|
name="FirstName2"
|
|
label="First Name"
|
|
.modelValue=${'Foo'}
|
|
disabled
|
|
></lion-input>
|
|
<lion-input name="LastName2" label="Last Name" .modelValue=${'Bar'}></lion-input>
|
|
</lion-fieldset>
|
|
</lion-fieldset>
|
|
<button @click=${toggleDisabled}>
|
|
Toggle disabled
|
|
</button>
|
|
```
|
|
|
|
### Nesting fieldsets
|
|
|
|
Fieldsets can also be nested. The level of nesting will correspond one to one with the `modelValue` object.
|
|
|
|
<Story name="Nesting fieldsets">
|
|
{html`
|
|
<lion-fieldset>
|
|
<div slot="label">Personal data</div>
|
|
<lion-fieldset name="nameGroup" label="Name">
|
|
<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 name="location" label="Location">
|
|
<lion-input name="country" label="Country" .modelValue=${'Netherlands'}></lion-input>
|
|
</lion-fieldset>
|
|
<lion-input name="age" label="Age" .modelValue=${21}></lion-input>
|
|
<button @click=${ev => console.log(ev.target.parentElement.modelValue)}>
|
|
Log everything to Action Logger
|
|
</button>
|
|
<br />
|
|
<button
|
|
@click=${ev => console.log(ev.target.parentElement.formElements.nameGroup.modelValue)}
|
|
>
|
|
Log only Name fieldset to Action Logger
|
|
</button>
|
|
</lion-fieldset>
|
|
`}
|
|
</Story>
|
|
|
|
```html
|
|
<lion-fieldset>
|
|
<div slot="label">Personal data</div>
|
|
<lion-fieldset name="nameGroup" label="Name">
|
|
<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 name="location" label="Location">
|
|
<lion-input name="country" label="Country" .modelValue=${'Netherlands'}></lion-input>
|
|
</lion-fieldset>
|
|
<lion-input name="age" label="Age" .modelValue=${21}></lion-input>
|
|
<button @click=${ev => console.log(ev.target.parentElement.modelValue)}>
|
|
Log everything to Action Logger
|
|
</button>
|
|
<br />
|
|
<button
|
|
@click=${ev => console.log(ev.target.parentElement.formElements.nameGroup.modelValue)}
|
|
>
|
|
Log only Name fieldset to Action Logger
|
|
</button>
|
|
</lion-fieldset>
|
|
```
|
|
|
|
## Validation
|
|
|
|
You can create validators that work on a fieldset level.
|
|
Below, we mimic a `required` validator, but on the fieldset.
|
|
Try it by typing something in the input, then removing it.
|
|
|
|
<Story name="Validation">
|
|
{() => {
|
|
const DemoValidator = class extends Validator {
|
|
constructor() {
|
|
super();
|
|
this.name = 'DemoValidator';
|
|
}
|
|
execute(value) {
|
|
if (value && value.input1) {
|
|
return false; // el.hasError = true
|
|
}
|
|
return true;
|
|
}
|
|
static async getMessage() {
|
|
return '[Fieldset Error] Demo error message';
|
|
}
|
|
};
|
|
return html`
|
|
<lion-fieldset id="someId" .validators="${[new DemoValidator()]}">
|
|
<lion-input name="input1" label="Label"></lion-input>
|
|
</lion-fieldset>
|
|
`;
|
|
}}
|
|
</Story>
|
|
|
|
```js
|
|
const DemoValidator = class extends Validator {
|
|
constructor() {
|
|
super();
|
|
this.name = 'DemoValidator';
|
|
}
|
|
|
|
execute(value) {
|
|
if (value && value.input1) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static async getMessage() {
|
|
return '[Fieldset Error] Demo error message';
|
|
}
|
|
};
|
|
```
|
|
|
|
```html
|
|
<lion-fieldset id="someId" .validators="${[new DemoValidator()]}">
|
|
<lion-input name="input1" label="Label"></lion-input>
|
|
</lion-fieldset>
|
|
```
|
|
|
|
### Validating multiple inputs in a fieldset
|
|
|
|
You can have your fieldset validator take into consideration multiple fields.
|
|
|
|
<Story name="Validating 2 fields">
|
|
{() => {
|
|
const IsCatsAndDogs = class extends Validator {
|
|
constructor() {
|
|
super();
|
|
this.name = 'IsCatsAndDogs';
|
|
}
|
|
execute(value) {
|
|
return !(value.input1 === 'cats' && value.input2 === 'dogs');
|
|
}
|
|
static async getMessage() {
|
|
return '[Fieldset Error] Input 1 needs to be "cats" and Input 2 needs to be "dogs"';
|
|
}
|
|
};
|
|
return html`
|
|
<lion-fieldset .validators="${[new IsCatsAndDogs()]}">
|
|
<lion-input
|
|
label="An all time YouTube favorite"
|
|
name="input1"
|
|
help-text="cats"
|
|
>
|
|
</lion-input>
|
|
<lion-input
|
|
label="Another all time YouTube favorite"
|
|
name="input2"
|
|
help-text="dogs"
|
|
>
|
|
</lion-input>
|
|
</lion-fieldset>
|
|
`;
|
|
}}
|
|
</Story>
|
|
|
|
```js
|
|
const IsCatsAndDogs = class extends Validator {
|
|
constructor() {
|
|
super();
|
|
this.name = 'IsCatsAndDogs';
|
|
}
|
|
|
|
execute(value) {
|
|
return !(value.input1 === 'cats' && value.input2 === 'dogs');
|
|
}
|
|
|
|
static async getMessage() {
|
|
return '[Fieldset Error] Input 1 needs to be "cats" and Input 2 needs to be "dogs"';
|
|
}
|
|
};
|
|
```
|
|
|
|
```html
|
|
<lion-fieldset .validators="${[new IsCatsAndDogs()]}">
|
|
<lion-input
|
|
label="An all time YouTube favorite"
|
|
name="input1"
|
|
help-text="cats"
|
|
>
|
|
</lion-input>
|
|
<lion-input
|
|
label="Another all time YouTube favorite"
|
|
name="input2"
|
|
help-text="dogs"
|
|
>
|
|
</lion-input>
|
|
</lion-fieldset>
|
|
```
|
|
|
|
Alternatively you can also let the fieldset validator be dependent on the error states of its child fields.
|
|
|
|
Simply loop over the formElements inside your Validator's `execute` method:
|
|
```js
|
|
this.formElementsArray.some(el => el.hasFeedbackFor.includes('error'));
|
|
```
|
|
|
|
### Validating multiple fieldsets
|
|
|
|
You can have your fieldset validator take into accounts multiple nested fieldsets.
|
|
|
|
<Story name="Validating 2 fieldsets">
|
|
{() => {
|
|
const IsCatsDogs = class extends Validator {
|
|
constructor() {
|
|
super();
|
|
this.name = 'IsCatsDogs';
|
|
}
|
|
execute(value) {
|
|
if ((value.inner1 && value.inner1.input1 === 'cats') &&
|
|
(value.inner2 && value.inner2.input1 === 'dogs')
|
|
) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
static async getMessage() {
|
|
return 'There is a problem with one of your fieldsets';
|
|
}
|
|
};
|
|
return html`
|
|
<lion-fieldset name="outer" .validators=${[new IsCatsDogs()]}>
|
|
<lion-fieldset name="inner1">
|
|
<label slot="label">Fieldset no. 1</label>
|
|
<lion-input
|
|
label="Write 'cats' here"
|
|
name="input1"
|
|
>
|
|
</lion-input>
|
|
</lion-fieldset>
|
|
<hr />
|
|
<lion-fieldset name="inner2">
|
|
<label slot="label">Fieldset no. 2</label>
|
|
<lion-input
|
|
label="Write 'dogs' here"
|
|
name="input1"
|
|
>
|
|
</lion-input>
|
|
</lion-fieldset>
|
|
</lion-fieldset>
|
|
`;
|
|
}}
|
|
</Story>
|
|
|
|
```js
|
|
const IsCatsDogs = class extends Validator {
|
|
constructor() {
|
|
super();
|
|
this.name = 'IsCatsDogs';
|
|
}
|
|
|
|
execute(value) {
|
|
if ((value.inner1 && value.inner1.input1 === 'cats') &&
|
|
(value.inner2 && value.inner2.input1 === 'dogs')
|
|
) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static async getMessage() {
|
|
return 'There is a problem with one of your fieldsets';
|
|
}
|
|
};
|
|
```
|
|
|
|
```html
|
|
<lion-fieldset name="outer" .validators="${[new IsCatsDogs()]}">
|
|
<lion-fieldset name="inner1">
|
|
<label slot="label">Fieldset no. 1</label>
|
|
<lion-input
|
|
label="Write 'cats' here"
|
|
name="input1"
|
|
>
|
|
</lion-input>
|
|
</lion-fieldset>
|
|
<hr />
|
|
<lion-fieldset name="inner2">
|
|
<label slot="label">Fieldset no. 2</label>
|
|
<lion-input
|
|
label="Write 'dogs' here"
|
|
name="input1"
|
|
>
|
|
</lion-input>
|
|
</lion-fieldset>
|
|
</lion-fieldset>
|
|
```
|