Skip to content
This repository was archived by the owner on Apr 9, 2025. It is now read-only.

Commit d8aa96e

Browse files
authored
Merge pull request #14 from dbssman/feature/13-docs-api-reference
🧪 Api reference docs and first beta release
2 parents 2e192ef + ca925a2 commit d8aa96e

33 files changed

+1488
-158
lines changed

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11

22
<div align="center">
3+
<object data="https://vue-form-handler.com/favicon.png"></object>
34
<h1>vue-form-handler</h1>
4-
5+
56
The easy way of handling your vue forms
6-
</div>
77

88
[![Build Status](https://github.com/mattphillips/deep-object-diff/actions/workflows/ci.yaml/badge.svg)](https://github.com/dbssman/vue-form-handler/actions/workflows/node.js.yml)
99
[![version](https://img.shields.io/npm/v/deep-object-diff.svg?style=flat-square)](https://www.npmjs.com/package/vue-form-handler)
1010
[![downloads](https://img.shields.io/npm/dm/deep-object-diff.svg?style=flat-square)](http://npm-stat.com/charts.html?package=vue-form-handler&from=2023-01-20)
1111
[![MIT License](https://img.shields.io/npm/l/deep-object-diff.svg?style=flat-square)](https://github.com/dbssman/vue-form-handler/blob/master/License.md)
1212
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
1313

14+
<a href="https://www.buymeacoffee.com/dbssman" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174"></a>
15+
</div>
16+
17+
1418
## 📦 Installation
1519
---
1620
``` yarn add vue-form-handler ```
@@ -99,4 +103,4 @@ This project is heavily inspired by other awesome projects like:
99103

100104
## 📄 License
101105
---
102-
[MIT License](https://github.com/dbssman/vue-form-handler/blob/master/License.md) © 2022-PRESENT [Dennis Bosmans](https://github.com/dbssman)
106+
[MIT License](https://github.com/dbssman/vue-form-handler/blob/master/License.md) © 2022-PRESENT [Dennis Bosmans](https://github.com/dbssman)

docs/.vitepress/config.cts

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@ import { defineConfig } from "vitepress"
33
export default defineConfig({
44
title: 'VueFormHandler',
55
description: 'Discover the easy way of handling your vue forms',
6+
head: [
7+
['meta', { name: 'theme-color', content: '#ffffff' }],
8+
['link', { rel: 'icon', href: '/favicon-32x32.png', type: 'image/png' }],
9+
['link', { rel: 'icon', href: '/favicon.svg', type: 'image/svg+xml' }],
10+
['meta', { name: 'author', content: 'Dennis R. Bosmans' }],
11+
['meta', { property: 'og:title', content: 'VueFormHandler' }],
12+
['meta', { property: 'og:image', content: 'https://vue-form-handler.com/favicon.png' }],
13+
['meta', { property: 'og:description', content: 'The only handler you\'ll need to easily work with forms in vue' }],
14+
],
615
themeConfig: {
716
logo: '/favicon.svg',
817
editLink: {
@@ -11,38 +20,39 @@ export default defineConfig({
1120
},
1221
nav: [
1322
{ text: 'Home', link: '/' },
14-
{ text: 'Get started', link: '/get-started' },
23+
{ text: 'Get started', link: '/get-started/introduction' },
1524
],
1625
sidebar: [
1726
{
18-
text: 'Documentation', items: [
19-
{ text: 'Get started', link: '/get-started' },
20-
{ text: 'Tutorial', link: '/tutorial' },
21-
{
22-
text: 'Guides', items: [
23-
{ text: 'Validation', link: '/guides/validation' },
24-
{ text: 'Typescript', link: '/guides/typescript' },
25-
{ text: 'Form submission', link: '/guides/form-submission' },
26-
{ text: 'Custom components', link: '/guides/custom-components' },
27-
{ text: 'Native support', link: '/guides/native-support' },
28-
]
29-
},
30-
{
31-
text: 'Examples', items: [
32-
{ text: 'Basic', link: '/examples/basic' },
33-
{ text: 'Async validations', link: '/examples/async-validations' },
34-
{ text: 'Typescript', link: '/examples/typescript' },
35-
{ text: 'Interceptor', link: '/examples/interceptor' },
36-
{ text: 'Dependent fields', link: '/examples/dependent-fields' },
37-
{ text: 'More examples', link: '/examples/more-examples' }
38-
]
39-
},
27+
text: 'Get started', items: [
28+
{ text: 'Introduction', link: '/get-started/introduction' },
29+
{ text: 'Quick Start', link: '/get-started/quick-start' },
30+
]
31+
},
32+
{
33+
text: 'Guides', collapsible: true, items: [
34+
{ text: 'Validation', link: '/guides/validation' },
35+
{ text: 'Typescript', link: '/guides/typescript' },
36+
{ text: 'Form submission', link: '/guides/form-submission' },
37+
{ text: 'Custom components', link: '/guides/custom-components' },
38+
{ text: 'Native support', link: '/guides/native-support' },
39+
]
40+
},
41+
{
42+
text: 'Examples', collapsible: true, items: [
43+
{ text: 'Basic', link: '/examples/basic' },
44+
{ text: 'Async validations', link: '/examples/async-validations' },
45+
{ text: 'Typescript', link: '/examples/typescript' },
46+
{ text: 'Interceptor', link: '/examples/interceptor' },
47+
{ text: 'Dependent fields', link: '/examples/dependent-fields' },
48+
{ text: 'More examples', link: '/examples/more-examples' }
4049
]
4150
},
4251
{
43-
text: 'API Reference', items: [
52+
text: 'API Reference', collapsible: true, items: [
4453
{
45-
text: 'useFormHandler', link: '/api/use-form-handler/index', items: [
54+
text: 'useFormHandler', link: '/api/use-form-handler/',
55+
items: [
4656
{ text: 'clearError', link: '/api/use-form-handler/clear-error' },
4757
{ text: 'clearField', link: '/api/use-form-handler/clear-field' },
4858
{ text: 'formState', link: '/api/use-form-handler/form-state' },

docs/api/form-handler.md

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,34 @@
1-
# \<FormHandler/>
1+
# \<FormHandler/>
2+
3+
The `FormHandler` component is an utility for people that are still using the options API or, that for some reason want to do the handling on the template side.
4+
5+
::: tip
6+
It is highly recommend that you use the `useFormHandler` composable if possible, since it is the intended way of making use of this package and gives you more control over the form.
7+
:::
8+
## How it works
9+
10+
You pass the same props as you'd be passing to the composable but to a component on the template, and the component will enable you a [scoped slot](https://vuejs.org/guide/components/slots.html#scoped-slots) with the return of `useFormHandler`.
11+
12+
As you can imagine, the `FormHandler` composable and `useFormHandler` share the same API but differ in the usage.
13+
14+
## Example:
15+
16+
```vue
17+
<template @submit.prevent="handleSubmit(successFn)">
18+
<FormHandler>
19+
<template v-slot="{register, handleSubmit}">
20+
<form @submit.prevent="handleSubmit(successFn)">
21+
<input v-bind="register('firstName')">
22+
<input v-bind="register('lastName')">
23+
</form>
24+
</template>
25+
</FormHandler>
26+
</template>
27+
<script setup lang="ts">
28+
import { FormHandler } from 'vue-form-handler'
29+
30+
const successFn = (form:Record<string,any>) => {
31+
console.log({form})
32+
}
33+
</script>
34+
```
Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,96 @@
1-
# clearError
1+
# clearError
2+
3+
Clears all the errors from the form or the error from a field programmatically.
4+
5+
## Demo
6+
7+
Coming soon...
8+
## Usage
9+
10+
### Validating/Invalidating the form without a field scoped validation
11+
12+
```vue
13+
<template>
14+
<form>
15+
<input type="text" v-bind="register('name')" />
16+
<input type="text" v-bind="register('email')" />
17+
<input type="text" v-bind="register('password')" />
18+
<input type="text" v-bind="register('password_confirmation')" />
19+
<button type="submit">Submit</button>
20+
</form>
21+
</template>
22+
<script setup lang="ts" >
23+
import { useFormHandler, Interceptor } from 'vue-form-handler'
24+
25+
const sleep = (milliseconds: number) => {
26+
return new Promise(resolve => setTimeout(resolve, milliseconds))
27+
}
28+
29+
//validate your fields here
30+
const validateFieldGroup = async () => {
31+
await sleep(1000)
32+
return Math.random() < 0.5;
33+
}
34+
35+
const interceptor: Interceptor = async ({ name, setError, clearError }) => {
36+
if (['name', 'email'].includes(name)) {
37+
await validateUser()
38+
? clearError(name)
39+
: setError('user', 'User already exists')
40+
}
41+
return true
42+
}
43+
44+
const { register } = useFormHandler({ interceptor })
45+
</script>
46+
```
47+
48+
Notice how we use the combination of [setError](/api/use-form-handler/set-error) and `clearError` in order to invalidate the form when we have some fields that need to be validated together and the error is not scoped to one single field but to the whole field group.
49+
50+
### Clearing the errors of a form after triggering validation/ submitting on demand
51+
52+
```vue
53+
<template>
54+
<form @submit.prevent="handleSubmit(successFn, errorFn)">
55+
<input type="text" v-bind="register('name', {
56+
required: true
57+
})" />
58+
<p v-if="formState.errors.name"> {{ formState.errors.name }} </p>
59+
<input type="text" v-bind="register('email', {
60+
required: true
61+
})" />
62+
<p v-if="formState.errors.email"> {{ formState.errors.email }} </p>
63+
<input type="text" v-bind="register('summary')">
64+
<button type="submit">Submit</button>
65+
</form>
66+
</template>
67+
<script setup lang="ts" >
68+
import { useFormHandler } from 'vue-form-handler'
69+
import { watch } from 'vue'
70+
71+
let hasErrorsAfterSubmit = false;
72+
const successFn = (form: any) => { console.log({ form }) }
73+
const errorFn = () => { hasErrorsAfterSubmit = true }
74+
75+
76+
const { register, handleSubmit, values, clearError, formState } = useFormHandler()
77+
78+
watch(
79+
() => values,
80+
() => {
81+
if (hasErrorsAfterSubmit) {
82+
clearError();
83+
hasErrorsAfterSubmit = false
84+
}
85+
},
86+
{ deep: true })
87+
</script>
88+
```
89+
90+
## Type Declarations
91+
92+
```ts
93+
export type ClearError = (
94+
name?: string
95+
) => void
96+
```
Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,68 @@
1-
# clearField
1+
# clearField
2+
3+
Clears a field, this means that the field is set to it's default value or to the fallback value.
4+
This will also trigger a validation for the field if existing.
5+
6+
## Demo
7+
8+
Coming soon...
9+
10+
## Usage
11+
12+
### Clear a field conditioned by another field
13+
14+
```vue
15+
<template>
16+
<select v-bind="register('continent')" placeholder="Choose your country">
17+
<option disabled value=null>Choose your continent</option>
18+
<option value="AM">America</option>
19+
<option value="AS">Asia</option>
20+
<option value="EU">Europe</option>
21+
</select>
22+
<select v-bind="register('country')" placeholder="Choose your country">
23+
<option disabled value=null>Choose your country</option>
24+
<option value="CAN">Canada</option>
25+
<option value="USA">United States</option>
26+
<option value="JAP">Japan</option>
27+
<option value="CHN">China</option>
28+
<option value="ESP">Spain</option>
29+
<option value="DEU">Germany</option>
30+
</select>
31+
</template>
32+
<script setup lang="ts">
33+
import { useFormHandler } from 'vue-form-handler'
34+
35+
const interceptor = ({ name, clearField }) => {
36+
if (name === 'continent') {
37+
clearField('country')
38+
}
39+
return true
40+
}
41+
42+
const { register } = useFormHandler({
43+
interceptor
44+
})
45+
</script>
46+
```
47+
48+
### Allowing the field to emit a 'clear' event or to have a button that clears a field
49+
50+
```vue
51+
<template>
52+
<input type="text" v-bind="register('clearableField')">
53+
<button @click="clearField('clearableField')">X</button>
54+
</template>
55+
<script setup lang="ts" >
56+
import { useFormHandler } from 'vue-form-handler'
57+
58+
const { register, clearField } = useFormHandler()
59+
</script>
60+
```
61+
62+
## Type Declarations
63+
64+
```ts
65+
export type ClearField = (
66+
name: string
67+
) => Promise<void>
68+
```
Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,55 @@
1-
# formState
1+
# formState
2+
3+
Provides you with the reactive state of the form, including validation, dirty and touched state, for the whole form or individual fields.
4+
5+
## Return
6+
7+
| attribute | type | description |
8+
|-----------|--------|--------------------------------------------|
9+
| dirty | `Record<string, boolean>` | Object containing all the inputs that have been modified |
10+
| errors | `Record<string, string>` | Object containing all the current field errors of the form |
11+
| touched | `Record<string, boolean>` | Object containing all the inputs the users has interacted with |
12+
| isDirty | `boolean` | True if there is any modified field on the form |
13+
| isTouched | `boolean` | True if there has been any interaction with a form field |
14+
| isValid | `boolean` | True if there are no form errors |
15+
16+
## Rules
17+
18+
`formState` is read-only, so no assignments are expected. It is entirely reactive, so you can react on changes of the whole element and/or it's main attributes.
19+
20+
## Usage
21+
22+
```vue
23+
<template>
24+
<form>
25+
<input type="text" v-bind="register('name', {
26+
required: true
27+
})" />
28+
<p v-if="formState.errors.name"> {{ formState.errors.name }} </p>
29+
<input type="text" v-bind="register('email', {
30+
required: true
31+
})" />
32+
<p v-if="formState.errors.email"> {{ formState.errors.email }} </p>
33+
<input type="text" v-bind="register('summary')">
34+
<button type="submit">Submit</button>
35+
</form>
36+
</template>
37+
<script setup lang="ts" >
38+
import { useFormHandler } from 'vue-form-handler'
39+
40+
const { register, formState } = useFormHandler()
41+
</script>
42+
```
43+
44+
## Type Declarations
45+
46+
```ts
47+
export interface FormState {
48+
isDirty: boolean
49+
isTouched: boolean
50+
isValid: boolean
51+
dirty: Record<string, boolean>
52+
touched: Record<string, boolean>
53+
errors: Record<string, string>
54+
}
55+
```

0 commit comments

Comments
 (0)