kopia lustrzana https://github.com/shoelace-style/shoelace
fix form validation
rodzic
85fd8a5204
commit
1cc65b145a
|
@ -86,7 +86,60 @@ const App = () => (
|
|||
);
|
||||
```
|
||||
|
||||
### Custom Validity
|
||||
### Validation
|
||||
|
||||
Setting the `required` attribute to make selecting a an option mandatory. If a value has not been selected, it will prevent the form from submitting and display an error message.
|
||||
|
||||
```html preview
|
||||
<form class="validation">
|
||||
<sl-radio-group label="Select an option" required>
|
||||
<sl-radio name="a" value="1">Not me</sl-radio>
|
||||
<sl-radio name="a" value="2">Me neither</sl-radio>
|
||||
<sl-radio name="a" value="3">Choose me</sl-radio>
|
||||
</sl-radio-group>
|
||||
<br />
|
||||
<sl-button type="submit" variant="primary">Submit</sl-button>
|
||||
</form>
|
||||
<script>
|
||||
const form = document.querySelector('.validation');
|
||||
// Handle form submit
|
||||
form.addEventListener('submit', event => {
|
||||
event.preventDefault();
|
||||
alert('All fields are valid!');
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
```jsx react
|
||||
import { SlButton, SlIcon, SlRadio, SlRadioGroup } from '@shoelace-style/shoelace/dist/react';
|
||||
const App = () => {
|
||||
function handleSubmit(event) {
|
||||
event.preventDefault();
|
||||
alert('All fields are valid!');
|
||||
}
|
||||
return (
|
||||
<form class="custom-validity" onSubmit={handleSubmit} required>
|
||||
<SlRadioGroup label="Select an option" onSlChange={handleChange}>
|
||||
<SlRadio name="a" value="1">
|
||||
Not me
|
||||
</SlRadio>
|
||||
<SlRadio name="a" value="2">
|
||||
Me neither
|
||||
</SlRadio>
|
||||
<SlRadio name="a" value="3">
|
||||
Choose me
|
||||
</SlRadio>
|
||||
</SlRadioGroup>
|
||||
<br />
|
||||
<SlButton type="submit" variant="primary">
|
||||
Submit
|
||||
</SlButton>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
#### Custom Validity
|
||||
|
||||
Use the `setCustomValidity()` method to set a custom validation message. This will prevent the form from submitting and make the browser display the error message you provide. To clear the error, call this function with an empty string.
|
||||
|
||||
|
@ -125,10 +178,10 @@ Use the `setCustomValidity()` method to set a custom validation message. This wi
|
|||
import { useEffect, useRef } from 'react';
|
||||
import { SlButton, SlIcon, SlRadio, SlRadioGroup } from '@shoelace-style/shoelace/dist/react';
|
||||
const App = () => {
|
||||
const radio = useRef(null);
|
||||
const radioGroup = useRef(null);
|
||||
const errorMessage = 'You must choose this option';
|
||||
function handleChange(event) {
|
||||
radio.current.setCustomValidity(radio.current.checked ? '' : errorMessage);
|
||||
function handleChange() {
|
||||
radioGroup.current.setCustomValidity(radioGroup.current.value === '3' ? '' : errorMessage);
|
||||
}
|
||||
function handleSubmit(event) {
|
||||
event.preventDefault();
|
||||
|
@ -139,14 +192,14 @@ const App = () => {
|
|||
}, []);
|
||||
return (
|
||||
<form class="custom-validity" onSubmit={handleSubmit}>
|
||||
<SlRadioGroup label="Select an option" value="1">
|
||||
<SlRadio name="a" value="1" onSlChange={handleChange}>
|
||||
<SlRadioGroup ref={radioGroup} label="Select an option" value="1" onSlChange={handleChange}>
|
||||
<SlRadio name="a" value="1">
|
||||
Not me
|
||||
</SlRadio>
|
||||
<SlRadio name="a" value="2" onSlChange={handleChange}>
|
||||
<SlRadio name="a" value="2">
|
||||
Me neither
|
||||
</SlRadio>
|
||||
<SlRadio ref={radio} name="a" value="3" onSlChange={handleChange}>
|
||||
<SlRadio name="a" value="3">
|
||||
Choose me
|
||||
</SlRadio>
|
||||
</SlRadioGroup>
|
||||
|
|
|
@ -35,6 +35,7 @@ export default class SlRadioGroup extends LitElement {
|
|||
@state() private hasButtonGroup = false;
|
||||
@state() private isInvalid = false;
|
||||
@state() private errorMessage = '';
|
||||
@state() private customErrorMessage = '';
|
||||
|
||||
/** The radio group label. Required for proper accessibility. Alternatively, you can use the label slot. */
|
||||
@property() label = '';
|
||||
|
@ -64,7 +65,8 @@ export default class SlRadioGroup extends LitElement {
|
|||
this.preventInvalidSubmit();
|
||||
}
|
||||
|
||||
setCustomValidity(message: string) {
|
||||
setCustomValidity(message = '') {
|
||||
this.customErrorMessage = message;
|
||||
this.errorMessage = message;
|
||||
|
||||
if (!message) {
|
||||
|
@ -77,11 +79,13 @@ export default class SlRadioGroup extends LitElement {
|
|||
}
|
||||
|
||||
get validity(): ValidityState {
|
||||
const isValid = (this.value && this.required) || !this.required;
|
||||
|
||||
const hasMissingData = !((this.value && this.required) || !this.required);
|
||||
const hasCustomError = this.customErrorMessage !== '';
|
||||
console.log(hasMissingData);
|
||||
|
||||
return {
|
||||
badInput: false,
|
||||
customError: false,
|
||||
customError: hasCustomError,
|
||||
patternMismatch: false,
|
||||
rangeOverflow: false,
|
||||
rangeUnderflow: false,
|
||||
|
@ -89,14 +93,16 @@ export default class SlRadioGroup extends LitElement {
|
|||
tooLong: false,
|
||||
tooShort: false,
|
||||
typeMismatch: false,
|
||||
valid: isValid,
|
||||
valueMissing: !isValid
|
||||
valid: hasMissingData || hasCustomError ? false : true,
|
||||
valueMissing: !hasMissingData
|
||||
};
|
||||
}
|
||||
|
||||
reportValidity() {
|
||||
const validity = this.validity;
|
||||
this.errorMessage = validity.valid ? '' : this.input.validationMessage;
|
||||
console.log(validity);
|
||||
|
||||
this.errorMessage = this.customErrorMessage || validity.valid ? '' : this.input.validationMessage;
|
||||
this.isInvalid = !validity.valid;
|
||||
|
||||
if (!validity.valid) {
|
||||
|
@ -106,8 +112,9 @@ export default class SlRadioGroup extends LitElement {
|
|||
|
||||
private preventInvalidSubmit() {
|
||||
this.closest('form')?.addEventListener('submit', e => {
|
||||
this.reportValidity();
|
||||
|
||||
if (this.isInvalid) {
|
||||
this.showNativeErrorMessage();
|
||||
e.preventDefault();
|
||||
e.stopImmediatePropagation();
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue