Skip to content

Commit 2f2083c

Browse files
committed
docs(checkbox): add helperText and errorText section
1 parent 3b0b5d1 commit 2f2083c

File tree

8 files changed

+269
-0
lines changed

8 files changed

+269
-0
lines changed

docs/api/checkbox.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,16 @@ import LabelLink from '@site/static/usage/v8/checkbox/label-link/index.md';
7474

7575
<LabelLink />
7676

77+
## Helper & Error Text
78+
79+
Helper and error text can be used inside of a checkbox with the `helperText` and `errorText` property. The error text will not be displayed unless the `ion-invalid` and `ion-touched` classes are added to the `ion-checkbox`. This ensures errors are not shown before the user has a chance to enter data.
80+
81+
In Angular, this is done automatically through form validation. In JavaScript, React and Vue, the class needs to be manually added based on your own validation.
82+
83+
import HelperError from '@site/static/usage/v8/checkbox/helper-error/index.md';
84+
85+
<HelperError />
86+
7787
## Theming
7888

7989
### CSS Custom Properties
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
```html
2+
<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
3+
<ion-checkbox formControlName="agree" helper-text="This needs to be checked" error-text="This field is required">
4+
I agree to the terms and conditions
5+
</ion-checkbox>
6+
7+
<br />
8+
9+
<ion-button type="submit" size="small">Submit</ion-button>
10+
</form>
11+
```
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
```ts
2+
import { Component } from '@angular/core';
3+
import { FormBuilder, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms';
4+
import { IonCheckbox, IonButton } from '@ionic/angular/standalone';
5+
6+
@Component({
7+
selector: 'app-example',
8+
standalone: true,
9+
imports: [IonCheckbox, IonButton, ReactiveFormsModule],
10+
templateUrl: './example.component.html',
11+
styleUrl: './example.component.css',
12+
})
13+
export class ExampleComponent {
14+
myForm: FormGroup;
15+
16+
constructor(private fb: FormBuilder) {
17+
this.myForm = this.fb.group({
18+
agree: [false, Validators.requiredTrue],
19+
});
20+
}
21+
22+
onSubmit() {
23+
// Mark the control as touched to trigger the error message.
24+
// This is needed if the user submits the form without interacting
25+
// with the checkbox.
26+
this.myForm.get('agree')!.markAsTouched();
27+
}
28+
}
29+
```
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Input</title>
7+
<link rel="stylesheet" href="../../common.css" />
8+
<script src="../../common.js"></script>
9+
<script type="module" src="https://cdn.jsdelivr.net/npm/@ionic/core@8/dist/ionic/ionic.esm.js"></script>
10+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ionic/core@8/css/ionic.bundle.css" />
11+
</head>
12+
13+
<body>
14+
<div class="container">
15+
<form id="my-form">
16+
<ion-checkbox helper-text="This needs to be checked" error-text="This field is required">
17+
I agree to the terms and conditions
18+
</ion-checkbox>
19+
20+
<br />
21+
22+
<ion-button type="submit" size="small">Submit</ion-button>
23+
</form>
24+
</div>
25+
26+
<script>
27+
const form = document.getElementById('my-form');
28+
const checkbox = form.querySelector('ion-checkbox');
29+
30+
form.addEventListener('submit', (event) => submit(event));
31+
checkbox.addEventListener('ionChange', (event) => validateCheckbox(event));
32+
33+
const validateCheckbox = (event) => {
34+
checkbox.classList.add('ion-touched');
35+
36+
if (!event.detail.checked) {
37+
checkbox.classList.add('ion-invalid');
38+
checkbox.classList.remove('ion-valid');
39+
} else {
40+
checkbox.classList.remove('ion-invalid');
41+
checkbox.classList.add('ion-valid');
42+
}
43+
};
44+
45+
const submit = (event) => {
46+
event.preventDefault();
47+
48+
validateCheckbox({ detail: { checked: checkbox.checked } });
49+
};
50+
</script>
51+
</body>
52+
</html>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import Playground from '@site/src/components/global/Playground';
2+
3+
import javascript from './javascript.md';
4+
import react from './react.md';
5+
import vue from './vue.md';
6+
7+
import angular_example_component_html from './angular/example_component_html.md';
8+
import angular_example_component_ts from './angular/example_component_ts.md';
9+
10+
<Playground
11+
version="8"
12+
code={{
13+
javascript,
14+
react,
15+
vue,
16+
angular: {
17+
files: {
18+
'src/app/example.component.html': angular_example_component_html,
19+
'src/app/example.component.ts': angular_example_component_ts,
20+
},
21+
},
22+
}}
23+
src="usage/v8/checkbox/helper-error/demo.html"
24+
/>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
```html
2+
<form id="my-form">
3+
<ion-checkbox helper-text="This needs to be checked" error-text="This field is required">
4+
I agree to the terms and conditions
5+
</ion-checkbox>
6+
7+
<br />
8+
9+
<ion-button type="submit" size="small">Submit</ion-button>
10+
</form>
11+
12+
<script>
13+
const form = document.getElementById('my-form');
14+
const checkbox = form.querySelector('ion-checkbox');
15+
16+
form.addEventListener('submit', (event) => submit(event));
17+
checkbox.addEventListener('ionChange', (event) => validateCheckbox(event));
18+
19+
const validateCheckbox = (event) => {
20+
checkbox.classList.add('ion-touched');
21+
22+
if (!event.detail.checked) {
23+
checkbox.classList.add('ion-invalid');
24+
checkbox.classList.remove('ion-valid');
25+
} else {
26+
checkbox.classList.remove('ion-invalid');
27+
checkbox.classList.add('ion-valid');
28+
}
29+
};
30+
31+
const submit = (event) => {
32+
event.preventDefault();
33+
34+
validateCheckbox({ detail: { checked: checkbox.checked } });
35+
};
36+
</script>
37+
```
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
```tsx
2+
import React, { useRef, useState } from 'react';
3+
import { IonCheckbox, IonButton, CheckboxCustomEvent } from '@ionic/react';
4+
5+
function Example() {
6+
const [isTouched, setIsTouched] = useState<boolean>(false);
7+
const [isValid, setIsValid] = useState<boolean | undefined>();
8+
9+
const checkboxRef = useRef<HTMLIonCheckboxElement>(null);
10+
11+
const validateCheckbox = (event: CheckboxCustomEvent<{ checked: boolean }>) => {
12+
setIsTouched(true);
13+
setIsValid(event.detail.checked);
14+
};
15+
16+
const submit = (event: React.FormEvent<HTMLFormElement>) => {
17+
event.preventDefault();
18+
19+
if (checkboxRef.current) {
20+
validateCheckbox({ detail: { checked: checkboxRef.current.checked } } as CheckboxCustomEvent<{
21+
checked: boolean;
22+
}>);
23+
}
24+
};
25+
26+
return (
27+
<>
28+
<form onSubmit={submit}>
29+
<IonCheckbox
30+
ref={checkboxRef}
31+
className={`${isValid ? 'ion-valid' : ''} ${isValid === false ? 'ion-invalid' : ''} ${
32+
isTouched ? 'ion-touched' : ''
33+
}`}
34+
helperText="This needs to be checked"
35+
errorText="This field is required"
36+
onIonChange={(event) => validateCheckbox(event)}
37+
>
38+
I agree to the terms and conditions
39+
</IonCheckbox>
40+
41+
<br />
42+
43+
<IonButton type="submit" size="small">
44+
Submit
45+
</IonButton>
46+
</form>
47+
</>
48+
);
49+
}
50+
51+
export default Example;
52+
```
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
```html
2+
<template>
3+
<form id="my-form" @submit.prevent="submit">
4+
<ion-checkbox
5+
v-model="isChecked"
6+
helper-text="This needs to be checked"
7+
error-text="This field is required"
8+
@ionChange="validateCheckbox"
9+
:class="{ 'ion-valid': isValid, 'ion-invalid': isValid === false, 'ion-touched': isTouched }"
10+
>
11+
I agree to the terms and conditions
12+
</ion-checkbox>
13+
14+
<br />
15+
16+
<ion-button type="submit" size="small">Submit</ion-button>
17+
</form>
18+
</template>
19+
20+
<script lang="ts">
21+
import { defineComponent, ref } from 'vue';
22+
import { IonCheckbox, IonButton, CheckboxCustomEvent } from '@ionic/vue';
23+
24+
export default defineComponent({
25+
components: {
26+
IonCheckbox,
27+
IonButton,
28+
},
29+
setup() {
30+
const isChecked = ref(false);
31+
const isTouched = ref(false);
32+
const isValid = ref<boolean | undefined>();
33+
34+
const validateCheckbox = (event: CheckboxCustomEvent<{ checked: boolean }>) => {
35+
isTouched.value = true;
36+
isValid.value = event.detail.checked;
37+
};
38+
39+
const submit = () => {
40+
isTouched.value = true;
41+
isValid.value = isChecked.value;
42+
};
43+
44+
return {
45+
isChecked,
46+
isTouched,
47+
isValid,
48+
validateCheckbox,
49+
submit,
50+
};
51+
},
52+
});
53+
</script>
54+
```

0 commit comments

Comments
 (0)