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.js'; import './helpers/demo-fieldset-child.js'; # Fieldset `lion-fieldset` groups multiple input fields or other fieldsets together. We have three specific fieldset implementations: - [lion-form](?path=/docs/forms-form) - [lion-checkbox-group](?path=/docs/forms-checkbox-group) - [lion-radio-group](?path=/docs/forms-radio-group) {html` `} ```html ``` A native fieldset element should always have a legend-element for a11y purposes. However, our fieldset element is not native and should not have a legend-element. Our fieldset instead has a label attribute or you can add a label with a div- or heading-element using `slot="label"`. ## Features - Easy retrieval of form data based on field names - Advanced user interaction scenarios via [interaction states](?path=/docs/forms-system-interaction-states) - Can have [validate](?path=/docs/forms-system-validate-system) on fieldset level and shows the validation feedback below the fieldset - Can disable input fields on fieldset level - Accessible out of the box ## Examples ### 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. {html` `} ```html ``` ### Disabled Disabling a fieldset disables all its child fields. When enabling a fieldset, fields that have disabled explicitly set will stay disabled. {() => { function toggleDisabled() { const fieldset = document.querySelector('#fieldset'); fieldset.disabled = !fieldset.disabled; } return html` `; }} ```js function toggleDisabled() { const fieldset = document.querySelector('#fieldset'); fieldset.disabled = !fieldset.disabled; } ``` ```html ``` ### Nesting fieldsets Fieldsets can also be nested. The level of nesting will correspond one to one with the `modelValue` object. {html`
Personal data

`}
```html
Personal data

``` ## 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. {() => { 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` `; }} ```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 ``` ### Validating multiple inputs in a fieldset You can have your fieldset validator take into consideration multiple 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` `; }} ```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 ``` 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. {() => { 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`
`; }}
```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
```