Skip to content

Commit b4c155d

Browse files
committed
Added Demo files and Updated Readme
1 parent 829a279 commit b4c155d

File tree

4 files changed

+257
-17
lines changed

4 files changed

+257
-17
lines changed

README.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ npm install @cloudedots/svelte-forms yup
1616
1717
## Basic Usage Example
1818

19-
_App.svelte_ :
19+
_[demo/Basic.svelte](https://github.com/cloudedots-projects/svelte-forms/blob/master/demo/Basic.svelte)_ :
2020

2121
```html
2222
<script>
@@ -27,7 +27,7 @@ _App.svelte_ :
2727
const { form, formControl, isValid } = createForm({
2828
// Initial Form Data
2929
initialValues: {
30-
email: ''
30+
email: '',
3131
password: '',
3232
},
3333
// Form Validation using Yup
@@ -63,26 +63,26 @@ _App.svelte_ :
6363

6464
## Full Usage Example
6565

66-
_App.svelte_ :
66+
_[demo/Full.svelte](https://github.com/cloudedots-projects/svelte-forms/blob/master/demo/Full.svelte)_ :
6767

6868
```html
6969
<script lang="ts">
7070
import { createForm } from "@cloudedots/svelte-forms";
7171
import * as yup from "yup";
72-
import UserForm from "./UserForm.svelte"; // Components
72+
import UserAddressForm from "./UserAddressForm.svelte"; // Components
7373
7474
// (Optional) Form's Data type will be automatically inferred from "initialValues" in "createForm" if type of Data is not specified
7575
type FormData = {
76-
title: string;
77-
description: string;
76+
title: string,
77+
description: string,
7878
users: {
79-
name: string;
80-
email: string;
79+
name: string,
80+
email: string,
8181
address: {
82-
state: string;
83-
city: string;
84-
};
85-
}[];
82+
state: string,
83+
city: string,
84+
},
85+
}[],
8686
};
8787
8888
// Create Form Instance
@@ -96,7 +96,7 @@ _App.svelte_ :
9696
setTouched, // Function() for manually setting Form state as "touched"
9797
updateForm, // Function() for updating Form's Structure after Form Controls are Added or Removed in cases like Form Arrays
9898
formControl, // Svelte Action to be used with <input>, <select>, <textarea> or similar HTML input elements
99-
} = createForm({
99+
} = createForm<FormData>({
100100
// Initial Values of Form
101101
initialValues: {
102102
title: "", // Simple String
@@ -153,7 +153,7 @@ _App.svelte_ :
153153
console.log($form); // Get Form Data
154154
};
155155
156-
$: console.log({ $form, $state }); // Log Form Data and Form State on every Change
156+
$: console.log($form, $state); // Log Form Data and Form State on every Change
157157
</script>
158158

159159
<form on:submit|preventDefault="{onSubmit}">
@@ -192,7 +192,7 @@ _App.svelte_ :
192192

193193
<input
194194
placeholder="name"
195-
name="users[{i}].name"
195+
name="users[{index}].name"
196196
bind:value="{user.name}"
197197
use:formControl
198198
/>
@@ -204,7 +204,7 @@ _App.svelte_ :
204204

205205
<input
206206
placeholder="email"
207-
name="users[{i}].email"
207+
name="users[{index}].email"
208208
bind:value="{user.email}"
209209
use:formControl
210210
/>
@@ -248,7 +248,7 @@ _App.svelte_ :
248248
</style>
249249
```
250250

251-
_UserAddressForm.svelte_ :
251+
_[demo/UserAddressForm.svelte](https://github.com/cloudedots-projects/svelte-forms/blob/master/demo/UserAddressForm.svelte)_ :
252252

253253
```html
254254
<script lang="ts">

demo/Basic.svelte

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<script>
2+
import { createForm } from "@cloudedots/svelte-forms";
3+
import * as yup from "yup";
4+
5+
// Create Form Instance
6+
const { form, formControl, isValid } = createForm({
7+
// Initial Form Data
8+
initialValues: {
9+
email: '',
10+
password: '',
11+
},
12+
// Form Validation using Yup
13+
validationSchema: yup.object().shape({
14+
email: yup.string().email().required(),
15+
password: yup.string().min(6).required()
16+
})
17+
});
18+
19+
const onSubmit = () => {
20+
// "$form" contains current Form Data
21+
console.log($form);
22+
}
23+
</script>
24+
25+
<form on:submit|preventDefault={onSubmit}>
26+
<input type="text" name="email" bind:value={$form.email} use:formControl />
27+
<input
28+
type="password"
29+
name="password"
30+
bind:value={$form.password}
31+
use:formControl
32+
/>
33+
34+
<button type="submit" disabled={!$isValid}>Submit</button>
35+
</form>

demo/Full.svelte

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
<script lang="ts">
2+
import { createForm } from "@cloudedots/svelte-forms";
3+
import * as yup from "yup";
4+
import UserAddressForm from "./UserAddressForm.svelte"; // Components
5+
6+
// (Optional) Form's Data type will be automatically inferred from "initialValues" in "createForm" if type of Data is not specified
7+
type FormData = {
8+
title: string,
9+
description: string,
10+
users: {
11+
name: string,
12+
email: string,
13+
address: {
14+
state: string,
15+
city: string,
16+
},
17+
}[],
18+
};
19+
20+
// Create Form Instance
21+
const {
22+
form, // Svelte Store<FormData> containing Form Data
23+
state, // Svelte Store<FormState> containing Form State - { [every_property]: { _touched: boolean, _errors: string[] }}
24+
isValid, // Svelte Store<boolean> containing entire Form's validation status
25+
isTouched, // Svelte Store<boolean> containing entire Form's touched status
26+
validateForm, // Function(highlight: 'none' | 'errors' | 'all' = 'none') for manually validting entire form
27+
handleChange, // Function(event: Event) to manually updating individual form control's state - can be used in place of "formControl" Action
28+
setTouched, // Function() for manually setting Form state as "touched"
29+
updateForm, // Function() for updating Form's Structure after Form Controls are Added or Removed in cases like Form Arrays
30+
formControl, // Svelte Action to be used with <input>, <select>, <textarea> or similar HTML input elements
31+
} = createForm<FormData>({
32+
// Initial Values of Form
33+
initialValues: {
34+
title: "", // Simple String
35+
description: "", // Simple String
36+
users: [], // Complex Form Array
37+
},
38+
// Yup Validation Schema
39+
validationSchema: yup.object().shape({
40+
title: yup.string().min(8).required(),
41+
description: yup.string(),
42+
users: yup.array().of(
43+
yup.object().shape({
44+
name: yup.string().required(),
45+
email: yup.string().email().required(),
46+
address: yup.object().shape({
47+
state: yup.string().required(),
48+
city: yup.string(),
49+
}),
50+
})
51+
),
52+
}),
53+
validationClasses: {
54+
valid: "is-valid", // CSS class added to valid form controls
55+
invalid: "is-invalid", // CSS class added to invalid form controls
56+
showValid: true, // Add CSS classes to valid form controls
57+
showInvalid: true, // Add CSS classes to invalid form controls
58+
},
59+
});
60+
61+
// Add new user to Users Form Array
62+
const addUser = () => {
63+
// Update Form Data
64+
$form.users = [
65+
...$form.users,
66+
{
67+
name: "",
68+
email: "",
69+
address: {
70+
state: "",
71+
city: "",
72+
},
73+
},
74+
];
75+
updateForm(); // Manually trigger Form Update - Required
76+
};
77+
78+
// Remove user from Users Form Array
79+
const removeUser = (index) => () => {
80+
$form.users = $form.users.filter((_, i) => i !== index); // Update Form Data
81+
$state.users = $state.users.filter((_, i) => i !== index); // Updating State is required after removing Form Controls
82+
updateForm(); // Manually trigger Form Update - Required
83+
};
84+
85+
// Submit Form
86+
const onSubmit = () => {
87+
console.log($form); // Get Form Data
88+
};
89+
90+
$: console.log($form, $state); // Log Form Data and Form State on every Change
91+
</script>
92+
93+
<form on:submit|preventDefault={onSubmit}>
94+
<input
95+
placeholder="Title"
96+
name="title"
97+
bind:value={$form.title}
98+
use:formControl
99+
/>
100+
{#if $state.title._errors?.length}
101+
{#each $state.title._errors as error}
102+
<span class="error">{error}</span>
103+
{/each}
104+
{/if}
105+
106+
<input
107+
placeholder="Description"
108+
name="description"
109+
bind:value={$form.description}
110+
use:formControl
111+
/>
112+
{#if $state.description._errors?.length}
113+
{#each $state.description._errors as error}
114+
<span class="error">{error}</span>
115+
{/each}
116+
{/if}
117+
118+
{#each $form.users as user, index}
119+
<h2>
120+
User {user.name}
121+
<button type="button" on:click={removeUser(i)}> Remove User </button>
122+
</h2>
123+
124+
<input
125+
placeholder="name"
126+
name="users[{index}].name"
127+
bind:value={user.name}
128+
use:formControl
129+
/>
130+
{#if $state.users[index].name._errors?.length}
131+
{#each $state.users[index].name._errors as error}
132+
<span class="error">{error}</span>
133+
{/each}
134+
{/if}
135+
136+
<input
137+
placeholder="email"
138+
name="users[{index}].email"
139+
bind:value={user.email}
140+
use:formControl
141+
/>
142+
{#if $state.users[index].email._errors?.length}
143+
{#each $state.users[index].email._errors as error}
144+
<span class="error">{error}</span>
145+
{/each}
146+
{/if}
147+
148+
<!-- Using with Components -->
149+
<UserAddressForm {form} {state} {formControl} {index} />
150+
{/each}
151+
152+
<button type="button" on:click={addUser}> Add User </button>
153+
154+
<button type="button" on:click={() => validateForm("errors")}>
155+
Validate Form
156+
</button>
157+
158+
<button type="submit" disabled={!$isValid}> Submit </button>
159+
</form>
160+
161+
<style>
162+
.valid {
163+
border: 1px solid green;
164+
}
165+
166+
.invalid {
167+
border: 1px solid red;
168+
}
169+
170+
.error {
171+
color: red;
172+
}
173+
</style>

demo/UserAddressForm.svelte

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<script lang="ts">
2+
export let form: any;
3+
export let state: any;
4+
export let formControl;
5+
export let index: number;
6+
</script>
7+
8+
<input
9+
type="text"
10+
placeholder="State"
11+
bind:value="{$form.users[index].address.state}"
12+
name="users[{index}].address.state"
13+
use:formControl
14+
/>
15+
{#if $state.users[index].address.state._errors?.length}
16+
{#each $state.users[index].address.state._errors as error}
17+
<span class="error">{error}</span>
18+
{/each}
19+
{/if}
20+
21+
<input
22+
type="text"
23+
placeholder="City"
24+
bind:value="{$form.users[index].address.city}"
25+
name="users[{index}].address.city"
26+
use:formControl
27+
/>
28+
{#if $state.users[index].address.city._errors?.length}
29+
{#each $state.users[index].address.city._errors as error}
30+
<span class="error">{error}</span>
31+
{/each}
32+
{/if}

0 commit comments

Comments
 (0)