Skip to content

Commit bdcc646

Browse files
committed
v6 cometh!
1 parent e0b89ef commit bdcc646

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+3004
-0
lines changed

asyncValidation/.babelrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"presets": ["react", "es2015"]
3+
}

asyncValidation/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Simple Form Example
2+
3+
## To run locally
4+
5+
```
6+
npm install
7+
npm run dev
8+
```
9+
10+
Then open [`http://localhost:3030/`](http://localhost:3030/).

asyncValidation/devServer.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
var path = require('path');
2+
var express = require('express');
3+
var webpack = require('webpack');
4+
var config = require('./webpack.config.dev');
5+
6+
var app = express();
7+
var compiler = webpack(config);
8+
9+
app.use(require('webpack-dev-middleware')(compiler, {
10+
noInfo: true,
11+
publicPath: config.output.publicPath
12+
}));
13+
14+
app.use(require('webpack-hot-middleware')(compiler));
15+
16+
app.get('*', function(req, res) {
17+
res.sendFile(path.join(__dirname, 'index.html'));
18+
});
19+
20+
app.listen(3030, 'localhost', function(err) {
21+
if (err) {
22+
console.log(err);
23+
return;
24+
}
25+
26+
console.log('Listening at http://localhost:3030');
27+
});

asyncValidation/index.html

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
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, maximum-scale=1.0, user-scalable=no"/>
6+
<title>Redux Form</title>
7+
<link href="http://dev.redux-form.com/6.0.0-alpha.4/bundle.css"
8+
media="screen, projection"
9+
rel="stylesheet" type="text/css"/>
10+
<link href="https://fonts.googleapis.com/css?family=Lato:400,300,700" rel="stylesheet" type="text/css">
11+
<link href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css"
12+
media="screen, projection" rel="stylesheet" type="text/css"/>
13+
<meta itemprop="name" content="Redux Form"/>
14+
<meta property="og:type" content="website"/>
15+
<meta property="og:title" content="Redux Form"/>
16+
<meta property="og:site_name" content="Redux Form"/>
17+
<meta property="og:description"
18+
content="The best way to manage your form state in Redux."/>
19+
<meta property="og:image" content="logo.png"/>
20+
<meta property="twitter:site" content="@erikras"/>
21+
<meta property="twitter:creator" content="@erikras"/>
22+
</head>
23+
<body>
24+
<div id="content">
25+
<style type="text/css" scoped>
26+
.loader {
27+
margin: 10% auto;
28+
font-size: 10px;
29+
position: relative;
30+
text-indent: -9999em;
31+
border-top: 1.1em solid rgba(100, 100, 100, 0.2);
32+
border-right: 1.1em solid rgba(100, 100, 100, 0.2);
33+
border-bottom: 1.1em solid rgba(100, 100, 100, 0.2);
34+
border-left: 1.1em solid grey;
35+
-webkit-transform: translateZ(0);
36+
-ms-transform: translateZ(0);
37+
transform: translateZ(0);
38+
-webkit-animation: load8 1.1s infinite linear;
39+
animation: load8 1.1s infinite linear;
40+
}
41+
42+
.loader,
43+
.loader:after {
44+
border-radius: 50%;
45+
width: 10em;
46+
height: 10em;
47+
}
48+
49+
@-webkit-keyframes load8 {
50+
0% {
51+
-webkit-transform: rotate(0deg);
52+
transform: rotate(0deg);
53+
}
54+
100% {
55+
-webkit-transform: rotate(360deg);
56+
transform: rotate(360deg);
57+
}
58+
}
59+
60+
@keyframes load8 {
61+
0% {
62+
-webkit-transform: rotate(0deg);
63+
transform: rotate(0deg);
64+
}
65+
100% {
66+
-webkit-transform: rotate(360deg);
67+
transform: rotate(360deg);
68+
}
69+
}
70+
</style>
71+
72+
<div class="loader">Loading...</div>
73+
</div>
74+
<script type="text/javascript" src="dist/bundle.js"></script>
75+
<script>
76+
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
77+
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
78+
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
79+
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
80+
ga('create', 'UA-69298417-1', 'auto');
81+
ga('send', 'pageview');
82+
</script>
83+
</body>
84+
</html>

asyncValidation/package.json

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
{
2+
"name": "redux-form-async-validation-example",
3+
"version": "5.0.0",
4+
"description": "An async validation example for redux-form",
5+
"repository": {
6+
"type": "git",
7+
"url": "https://github.com/erikras/redux-form"
8+
},
9+
"scripts": {
10+
"clean": "rimraf dist",
11+
"build:webpack": "cross-env NODE_ENV=production webpack --config webpack.config.prod.js",
12+
"build": "npm run clean && npm run build:webpack",
13+
"lint": "eslint src",
14+
"start": "node devServer.js",
15+
"prepublish": "npm run lint && npm run build"
16+
},
17+
"keywords": [
18+
"react",
19+
"reactjs",
20+
"flux",
21+
"redux",
22+
"react-redux",
23+
"redux-form",
24+
"form",
25+
"decorator",
26+
"example",
27+
"demo"
28+
],
29+
"betterScripts": {
30+
"dev": {
31+
"command": "node webpack/webpack-dev-server.js",
32+
"env": {
33+
"UV_THREADPOOL_SIZE": 100,
34+
"NODE_ENV": "development",
35+
"NODE_PATH": "./src"
36+
}
37+
}
38+
},
39+
"author": "Erik Rasmussen <[email protected]> (http://github.com/erikras)",
40+
"license": "MIT",
41+
"bugs": {
42+
"url": "https://github.com/erikras/redux-form/issues"
43+
},
44+
"homepage": "https://github.com/erikras/redux-form",
45+
"dependencies": {
46+
"babel-polyfill": "^6.6.1",
47+
"html-loader": "^0.4.3",
48+
"json-loader": "^0.5.4",
49+
"markdown-loader": "^0.1.7",
50+
"raw-loader": "^0.5.1",
51+
"react": "^15.0.0-rc.2",
52+
"react-dom": "^15.0.0-rc.2",
53+
"react-redux": "^4.4.1",
54+
"redux": "^3.3.1",
55+
"redux-form": "6.0.0-alpha.4",
56+
"redux-form-website-template": "0.0.13"
57+
},
58+
"devDependencies": {
59+
"babel-core": "^6.3.15",
60+
"babel-eslint": "^5.0.0-beta4",
61+
"babel-loader": "^6.2.0",
62+
"babel-preset-es2015": "^6.3.13",
63+
"babel-preset-react": "^6.3.13",
64+
"cross-env": "^1.0.7",
65+
"eslint": "^1.6.0",
66+
"eslint-config-rackt": "^1.1.1",
67+
"eslint-loader": "^1.3.0",
68+
"eslint-plugin-babel": "^3.0.0",
69+
"eslint-plugin-react": "^3.11.3",
70+
"eventsource-polyfill": "^0.9.6",
71+
"express": "^4.13.3",
72+
"extract-text-webpack-plugin": "^1.0.1",
73+
"redbox-react": "^1.2.2",
74+
"rimraf": "^2.4.3",
75+
"webpack": "^1.12.9",
76+
"webpack-dev-middleware": "^1.4.0",
77+
"webpack-hot-middleware": "^2.6.0"
78+
}
79+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Async Blur Validation Example
2+
3+
The recommended way to provide server-side validation is to use
4+
[Submit Validation](submit-validation), but there may be instances when you want to run
5+
server-side validation _while the form is being filled out_. The classic example of this
6+
letting someone choose a value, like a username, that must be unique within your system.
7+
8+
To provide asynchronous validation, provide `redux-form` with an asynchronous validation
9+
function (`asyncValidate`) that takes an object of form values, and the Redux `dispatch`
10+
function, and returns a promise that either rejects with an object of errors or resolves.
11+
12+
You will also need to specify which fields should fire the asynchronous validation when
13+
they are blurred with the `asyncBlurFields` config property.
14+
15+
### Important
16+
17+
1. Asynchronous validation _will_ be called before the `onSubmit` is fired, but if all
18+
you care about is validation `onSubmit`, you should use
19+
[Submit Validation](submit-validation).
20+
2. Asynchronous validation will _not_ be called if synchronous validation is failing
21+
_for the field just blurred_.
22+
23+
The errors are displayed in the exact same way as validation errors created by
24+
[Synchronous Validation](synchronous-validation).
25+
26+
### How to use the form below:
27+
28+
* Usernames that will _fail_ validation: `john`, `paul`, `george` or `ringo`.
29+
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import React from 'react'
2+
import { Field, reduxForm } from 'redux-form'
3+
const { DOM: { input } } = React
4+
import validate from './validate'
5+
import asyncValidate from './asyncValidate'
6+
7+
const AsyncValidationForm = (props) => {
8+
const { asyncValidating, handleSubmit, pristine, reset, submitting } = props
9+
return (
10+
<form onSubmit={handleSubmit}>
11+
<div>
12+
<label>Username</label>
13+
<Field name="username" component={username =>
14+
<div className={asyncValidating === 'username' ? 'async-validating' : ''}>
15+
<input type="text" {...username} placeholder="Username"/>
16+
{username.touched && username.error && <span>{username.error}</span>}
17+
</div>
18+
}/>
19+
</div>
20+
<div>
21+
<label>Password</label>
22+
<Field name="password" component={password =>
23+
<div>
24+
<input type="password" {...password} placeholder="Password"/>
25+
{password.touched && password.error && <span>{password.error}</span>}
26+
</div>
27+
}/>
28+
</div>
29+
<div>
30+
<button type="submit" disabled={submitting}>Sign Up</button>
31+
<button type="button" disabled={pristine || submitting} onClick={reset}>Clear Values</button>
32+
</div>
33+
</form>
34+
)
35+
}
36+
37+
export default reduxForm({
38+
form: 'asyncValidation', // a unique identifier for this form
39+
validate,
40+
asyncValidate,
41+
asyncBlurFields: [ 'username' ]
42+
})(AsyncValidationForm)

asyncValidation/src/asyncValidate.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
2+
3+
const asyncValidate = (values/*, dispatch */) => {
4+
return sleep(1000) // simulate server latency
5+
.then(() => {
6+
if ([ 'john', 'paul', 'george', 'ringo' ].includes(values.username)) {
7+
throw { username: 'That username is taken' }
8+
}
9+
})
10+
}
11+
12+
export default asyncValidate
13+

asyncValidation/src/index.js

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import React from 'react'
2+
import ReactDOM from 'react-dom'
3+
import { Provider } from 'react-redux'
4+
import { createStore } from 'redux'
5+
import { App, Code, Markdown, Values } from 'redux-form-website-template'
6+
import reducer from './reducer'
7+
8+
const dest = document.getElementById('content')
9+
const store =
10+
(window.devToolsExtension ? window.devToolsExtension()(createStore) : createStore)(reducer)
11+
12+
const showResults = values =>
13+
new Promise(resolve => {
14+
setTimeout(() => { // simulate server latency
15+
window.alert(`You submitted:\n\n${JSON.stringify(values, null, 2)}`)
16+
resolve()
17+
}, 500)
18+
})
19+
20+
let render = () => {
21+
const AsyncValidationForm = require('./AsyncValidationForm').default
22+
const readme = require('./AsyncValidation.md')
23+
const raw = require('!!raw!./AsyncValidationForm')
24+
const rawValidate = require('!!raw!./validate')
25+
const rawAsyncValidate = require('!!raw!./asyncValidate')
26+
ReactDOM.render(
27+
<Provider store={store}>
28+
<App
29+
/**
30+
* This <App/> component only provides the site wrapper.
31+
* Remove it on your dev server if you wish. It will not affect the functionality.
32+
*/
33+
absolute
34+
version={REDUX_FORM_VERSION}
35+
path="/examples/async-validation"
36+
breadcrumbs={[ { path: 'http://redux-form.com/examples', title: 'Examples' },
37+
{ path: 'http://redux-form.com/examples/async-validation', title: 'Async Validation Example' } ]}>
38+
39+
<Markdown content={readme}/>
40+
41+
<h2>Form</h2>
42+
43+
<AsyncValidationForm onSubmit={showResults}/>
44+
45+
<Values form="asyncValidation"/>
46+
47+
<h2>Code</h2>
48+
49+
<h4>validate.js</h4>
50+
51+
<Code source={rawValidate}/>
52+
53+
<h4>asyncValidate.js</h4>
54+
55+
<Code source={rawAsyncValidate}/>
56+
57+
<h4>AsyncValidationForm.js</h4>
58+
59+
<Code source={raw}/>
60+
61+
</App>
62+
</Provider>,
63+
dest
64+
)
65+
}
66+
67+
if (module.hot) {
68+
// Support hot reloading of components
69+
// and display an overlay for runtime errors
70+
const renderApp = render
71+
const renderError = (error) => {
72+
const RedBox = require('redbox-react')
73+
ReactDOM.render(
74+
<RedBox error={error} className="redbox"/>,
75+
dest
76+
)
77+
}
78+
render = () => {
79+
try {
80+
renderApp()
81+
} catch (error) {
82+
renderError(error)
83+
}
84+
}
85+
const rerender = () => {
86+
setTimeout(render)
87+
}
88+
module.hot.accept('./AsyncValidationForm', rerender)
89+
module.hot.accept('./AsyncValidation.md', rerender)
90+
module.hot.accept('!!raw!./AsyncValidationForm', rerender)
91+
module.hot.accept('!!raw!./asyncValidate', rerender)
92+
module.hot.accept('!!raw!./validate', rerender)
93+
}
94+
95+
render()

0 commit comments

Comments
 (0)