Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"skipFiles": ["<node_internals>/**"]
"skipFiles": ["<node_internals>/**"],
"sourceMaps": true
}
]
}
8 changes: 8 additions & 0 deletions CHANGELOG.MD
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# 2.0.0

- don't throw if context not provided in validator

- remove debounce option

- dont support async validations

# 1.2.0

- add onValidated - fired once after validation occurs.
Expand Down
96 changes: 9 additions & 87 deletions examples/index.js → examples/example.js
Original file line number Diff line number Diff line change
@@ -1,87 +1,15 @@
import { render } from 'react-dom'
import React, { useState, useCallback } from 'react'
import React from 'react'
import { Form, Validator } from '@tswaters/react-form-validation'

const AsyncValidation = () => {
const [shouldResolve, setShouldResolve] = useState(false)
const [loading, setLoading] = useState(false)
const getUserService = useCallback(
() =>
new Promise((resolve, reject) =>
setTimeout(
() => (shouldResolve ? resolve() : reject(new Error('user exists'))),
500
)
),
[shouldResolve]
)

const validation = useCallback(async () => {
setLoading(true)
try {
await getUserService()
} finally {
setLoading(false)
}
}, [getUserService])

return (
<>
<Validator validation={validation} change debounce={1500}>
{({ error, validated }) => (
<div
className={`form-group
${validated ? 'was-validated' : ''}
${loading ? 'loading' : ''}`}
>
<label className="control-label" htmlFor="name">
Name
</label>
<input
id="user-name"
name="user-name"
className="form-control"
type="text"
required
/>
{error && <div className="invalid-feedback">{error.message}</div>}
</div>
)}
</Validator>
<div className="form-group">
<div className="custom-control custom-radio custom-control-inline">
<input
type="radio"
id="resovle"
name="resovle"
className="custom-control-input"
onChange={() => setShouldResolve(true)}
checked={shouldResolve}
/>
<label className="custom-control-label" htmlFor="resovle">
Resolve
</label>
</div>
<div className="custom-control custom-radio custom-control-inline">
<input
type="radio"
id="reject"
name="reject"
className="custom-control-input"
onChange={() => setShouldResolve(false)}
checked={!shouldResolve}
/>
<label className="custom-control-label" htmlFor="reject">
Reject
</label>
</div>
</div>
</>
)
}

render(
<Form onSubmit={() => console.log('SUBMITTING!!!!!')} noValidate>
<Form
onSubmit={(e) => {
e.preventDefault()
console.log('SUBMITTING!!!!!')
}}
noValidate
>
<div className="container">
<div className="card-group">
<div className="card">
Expand Down Expand Up @@ -121,7 +49,7 @@ render(
validation={(input, fields) => {
const other = fields.find((x) => x.id === 'name')
if (!other || other.value !== input.value)
throw new Error('must match')
return new Error('must match')
}}
>
{({ error, validated }) => {
Expand All @@ -148,12 +76,6 @@ render(
</Validator>
</div>
</div>
<div className="card">
<div className="card-header">Async Validation</div>
<div className="card-body">
<AsyncValidation />
</div>
</div>
</div>
<div className="card-group">
<div className="card">
Expand Down
6 changes: 5 additions & 1 deletion examples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,8 @@
}
</style>
<div id="root"></div>
<script type="text/babel" src="index.js" data-presets="babel-sucks"></script>
<script
type="text/babel"
src="./example.js"
data-presets="babel-sucks"
></script>
15 changes: 5 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,10 @@
"sinon": "^9.0.2"
},
"babel": {
"sourceMaps": "both",
"retainLines": true,
"presets": [
[
"@babel/preset-env",
{
"exclude": [
"@babel/plugin-transform-regenerator",
"@babel/plugin-transform-async-to-generator"
]
}
],
"@babel/preset-env",
"@babel/preset-react"
],
"plugins": [
Expand Down Expand Up @@ -153,7 +147,8 @@
"spec": [
"test/setup.js",
"test/**/*.test.js"
]
],
"timeout": false
},
"bugs": {
"url": "https://github.com/tswaters/react-form-validation/issues"
Expand Down
68 changes: 18 additions & 50 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,6 @@ const example = () => {

- **NOTE:** onSubmit will only be called if the form passes validation!

- **NOTE:** this library calls `preventDefault` to do async validations.

### Form element components

Input/Select/TextArea take all the same props.
Expand Down Expand Up @@ -176,74 +174,44 @@ const LoginForm = () => {

You can provide validations to the `<Input/Select/TextArea>` element and they will be called as part of validating the element.

These validation routines can be async and await their response. Form submission will be blocked while validations are awaiting their response.

The validation routine will consider something as failed with the following returns:
Validation routines must be synchronous. Validation will be considered failed with the following returns:

- a string - the error returned will be `new Error(returnValue)`

- an error - the error returned will be `returnValue`

- throw an error - the error returned will be `thrownValue`

Otherwise, the validation is considered to have succeeded.

```js
import { Validator, Input } from '@tswaters/react-form-validation'
import { Form, Validator } from '@tswaters/react-form-validation'

const MyForm = () => {
const [error, setError] = useState(null)
const [response, setResponse] = useState(null)
const [loading, setLoading] = useState(true)

const validation = useMemo(
() => [
async (input) => {
setLoading(true)
try {
await UserService.checkIfAlreadyExists(input.value)
} finally {
setLoading(false)
}
},
],
[]
)

const handleSubmit = useCallback(async (e) => {
const validation = useCallback((inputRef) => {
if (restrictedWords.includes(inputRef.value))
return new Error('cant use restricted words')
}, [])

const handleSubmit = useCallback((e) => {
e.preventDefault()
try {
const res = await fetch('/api', {
method: 'POST',
body: new FormData(e.target),
headers: {
Accept: 'application/json',
},
})
const data = await res.json()
if (res.ok) return setResponse(data)
throw data
} catch (err) {
setError(err)
}
console.log('completely valid, no restricted words here!')
}, [])

return (
<Form onSubmit={handleSubmit} noValidate>
<Validator>
{({ error }) => (
<input
name="user-name"
change={true}
debounce={500}
validation={validation}
className={loading ? 'loading' : ''}
/>
)}
<Validator change validation={validation}>
{({ error }) => {
return (
<>
<input name="user-name" required />
{error && <div>{error.message}</div>}
</>
)
}}
</Validator>
<button type="submit">Submit</button>
{response && <div>{response}</div>}
{error && <div>{error.message}</div>}
</Form>
)
}
Expand Down
2 changes: 1 addition & 1 deletion rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const config = (format, file, minify, server = false) => ({
port: 8001,
host: '0.0.0.0',
path: 'examples/index.html',
contentBase: ['examples', 'dist', 'node_modules'],
contentBase: ['examples', 'dist'],
open: false,
wait: 500,
}),
Expand Down
2 changes: 0 additions & 2 deletions src/context.js

This file was deleted.

Loading