mirror of
https://github.com/zhigang1992/redux-form.git
synced 2026-04-30 05:15:41 +08:00
Added simple form example with material-ui.
This commit is contained in:
committed by
Erik Rasmussen
parent
26a483ddf6
commit
71b32925c3
@@ -7,6 +7,7 @@ Each example is its own standalone web app with hot reloading. To run them local
|
||||
`redux-form` repository, `cd` into an example folder, and run `npm install` and `npm start`. Then
|
||||
open [`localhost:3030`](http://localhost:3030) in your browser.
|
||||
|
||||
|
||||
---
|
||||
|
||||
### [Simple Form](simple)
|
||||
@@ -50,4 +51,8 @@ open [`localhost:3030`](http://localhost:3030) in your browser.
|
||||
> How to create a multi-page "wizard" form.
|
||||
|
||||
---
|
||||
|
||||
### [Material-ui Examples](material-ui)
|
||||
|
||||
> Contains multiple material-ui examples
|
||||
|
||||
---
|
||||
|
||||
3
examples/material-ui/.babelrc
Normal file
3
examples/material-ui/.babelrc
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"presets": ["react", "es2015"]
|
||||
}
|
||||
10
examples/material-ui/README.md
Normal file
10
examples/material-ui/README.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Simple Material UI Form Example
|
||||
|
||||
## To run locally
|
||||
|
||||
```
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
|
||||
Then open [`http://localhost:3030/`](http://localhost:3030/).
|
||||
27
examples/material-ui/devServer.js
Normal file
27
examples/material-ui/devServer.js
Normal file
@@ -0,0 +1,27 @@
|
||||
var path = require('path');
|
||||
var express = require('express');
|
||||
var webpack = require('webpack');
|
||||
var config = require('./webpack.config.dev');
|
||||
|
||||
var app = express();
|
||||
var compiler = webpack(config);
|
||||
|
||||
app.use(require('webpack-dev-middleware')(compiler, {
|
||||
noInfo: true,
|
||||
publicPath: config.output.publicPath
|
||||
}));
|
||||
|
||||
app.use(require('webpack-hot-middleware')(compiler));
|
||||
|
||||
app.get('*', function(req, res) {
|
||||
res.sendFile(path.join(__dirname, 'index.html'));
|
||||
});
|
||||
|
||||
app.listen(3030, 'localhost', function(err) {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Listening at http://localhost:3030');
|
||||
});
|
||||
90
examples/material-ui/index.html
Normal file
90
examples/material-ui/index.html
Normal file
@@ -0,0 +1,90 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charSet="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
|
||||
<title>Redux Form</title>
|
||||
<link href="http://redux-form.com/6.0.0-alpha.6/bundle.css"
|
||||
media="screen, projection"
|
||||
rel="stylesheet" type="text/css"/>
|
||||
<link href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css"
|
||||
media="screen, projection" rel="stylesheet" type="text/css"/>
|
||||
<style type="text/css">
|
||||
/*This CSS has been tweked from root site
|
||||
to match with material-ui*/
|
||||
form > div > div > div {
|
||||
padding: 0px;
|
||||
border: none;
|
||||
}
|
||||
</style>
|
||||
<meta itemprop="name" content="Redux Form"/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:title" content="Redux Form"/>
|
||||
<meta property="og:site_name" content="Redux Form"/>
|
||||
<meta property="og:description"
|
||||
content="The best way to manage your form state in Redux."/>
|
||||
<meta property="og:image" content="logo.png"/>
|
||||
<meta property="twitter:site" content="@erikras"/>
|
||||
<meta property="twitter:creator" content="@erikras"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="content">
|
||||
<style type="text/css" scoped>
|
||||
.loader {
|
||||
margin: 10% auto;
|
||||
font-size: 10px;
|
||||
position: relative;
|
||||
text-indent: -9999em;
|
||||
border-top: 1.1em solid rgba(100, 100, 100, 0.2);
|
||||
border-right: 1.1em solid rgba(100, 100, 100, 0.2);
|
||||
border-bottom: 1.1em solid rgba(100, 100, 100, 0.2);
|
||||
border-left: 1.1em solid grey;
|
||||
-webkit-transform: translateZ(0);
|
||||
-ms-transform: translateZ(0);
|
||||
transform: translateZ(0);
|
||||
-webkit-animation: load8 1.1s infinite linear;
|
||||
animation: load8 1.1s infinite linear;
|
||||
}
|
||||
|
||||
.loader,
|
||||
.loader:after {
|
||||
border-radius: 50%;
|
||||
width: 10em;
|
||||
height: 10em;
|
||||
}
|
||||
|
||||
@-webkit-keyframes load8 {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes load8 {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<div class="loader">Loading...</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="dist/bundle.js"></script>
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
ga('create', 'UA-69298417-1', 'auto');
|
||||
ga('send', 'pageview');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
81
examples/material-ui/package.json
Normal file
81
examples/material-ui/package.json
Normal file
@@ -0,0 +1,81 @@
|
||||
{
|
||||
"name": "redux-form-simple-material-ui-example",
|
||||
"version": "6.0.0-alpha.6",
|
||||
"description": "A simple example for redux-form with material-ui",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/erikras/redux-form"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "rimraf dist",
|
||||
"build:webpack": "cross-env NODE_ENV=production webpack --config webpack.config.prod.js",
|
||||
"build": "npm run clean && npm run build:webpack",
|
||||
"lint": "eslint src",
|
||||
"start": "node devServer.js",
|
||||
"prepublish": "npm run lint && npm run build"
|
||||
},
|
||||
"keywords": [
|
||||
"react",
|
||||
"reactjs",
|
||||
"flux",
|
||||
"redux",
|
||||
"react-redux",
|
||||
"redux-form",
|
||||
"form",
|
||||
"decorator",
|
||||
"example",
|
||||
"demo"
|
||||
],
|
||||
"betterScripts": {
|
||||
"dev": {
|
||||
"command": "node webpack/webpack-dev-server.js",
|
||||
"env": {
|
||||
"UV_THREADPOOL_SIZE": 100,
|
||||
"NODE_ENV": "development",
|
||||
"NODE_PATH": "./src"
|
||||
}
|
||||
}
|
||||
},
|
||||
"author": "Erik Rasmussen <rasmussenerik@gmail.com> (http://github.com/erikras)",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/erikras/redux-form/issues"
|
||||
},
|
||||
"homepage": "https://github.com/erikras/redux-form",
|
||||
"dependencies": {
|
||||
"babel-polyfill": "^6.6.1",
|
||||
"html-loader": "^0.4.3",
|
||||
"json-loader": "^0.5.4",
|
||||
"markdown-loader": "^0.1.7",
|
||||
"material-ui": "^0.14.4",
|
||||
"raw-loader": "^0.5.1",
|
||||
"react": "^15.0.0-rc.2",
|
||||
"react-dom": "^15.0.0-rc.2",
|
||||
"react-redux": "^4.4.1",
|
||||
"react-tap-event-plugin": "^1.0.0",
|
||||
"redux": "^3.3.1",
|
||||
"redux-form": "6.0.0-alpha.6",
|
||||
"redux-form-website-template": "0.0.24"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-core": "^6.3.15",
|
||||
"babel-eslint": "^5.0.0-beta4",
|
||||
"babel-loader": "^6.2.0",
|
||||
"babel-preset-es2015": "^6.3.13",
|
||||
"babel-preset-react": "^6.3.13",
|
||||
"cross-env": "^1.0.7",
|
||||
"eslint": "^1.6.0",
|
||||
"eslint-config-rackt": "^1.1.1",
|
||||
"eslint-loader": "^1.3.0",
|
||||
"eslint-plugin-babel": "^3.0.0",
|
||||
"eslint-plugin-react": "^3.11.3",
|
||||
"eventsource-polyfill": "^0.9.6",
|
||||
"express": "^4.13.3",
|
||||
"extract-text-webpack-plugin": "^1.0.1",
|
||||
"redbox-react": "^1.2.2",
|
||||
"rimraf": "^2.4.3",
|
||||
"webpack": "^1.12.9",
|
||||
"webpack-dev-middleware": "^1.4.0",
|
||||
"webpack-hot-middleware": "^2.6.0"
|
||||
}
|
||||
}
|
||||
11
examples/material-ui/src/MaterialUi.md
Normal file
11
examples/material-ui/src/MaterialUi.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Simple Form Example
|
||||
|
||||
This is a simple demonstration of how to connect all the standard [material-ui](https://github.com/callemall/material-ui) form elements to `redux-form`.
|
||||
|
||||
For the most part, it is a matter of wrapping each form control in a `<Field>` component as custom component.
|
||||
|
||||
The `Field` component will provide your input with `onChange`, `onBlur`, `onFocus`, `onDrag`, and `onDrop` props to listen to the events, as well as a `value prop to make each input a [controlled component](http://facebook.github.io/react/docs/forms.html#controlled-components).
|
||||
|
||||
For controlls like `SelectField` we need to simulate the `onChange` manually. As props have been exposed in `redux-form` you can fire `onChange` manually. Read more [here](../../../docs/api/Field.md#usage)
|
||||
|
||||
The delay between when you click "Submit" and when the alert dialog pops up is intentional, to simulate server latency.
|
||||
104
examples/material-ui/src/MaterialUiForm.js
Normal file
104
examples/material-ui/src/MaterialUiForm.js
Normal file
@@ -0,0 +1,104 @@
|
||||
import React from 'react'
|
||||
import { Field, reduxForm } from 'redux-form'
|
||||
import TextField from 'material-ui/lib/text-field'
|
||||
import RadioButton from 'material-ui/lib/radio-button'
|
||||
import RadioButtonGroup from 'material-ui/lib/radio-button-group'
|
||||
import Checkbox from 'material-ui/lib/checkbox'
|
||||
import SelectField from 'material-ui/lib/select-field'
|
||||
import MenuItem from 'material-ui/lib/menus/menu-item'
|
||||
|
||||
class MaterialUiForm extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
}
|
||||
render() {
|
||||
const { handleSubmit, pristine, reset, submitting } = this.props
|
||||
return (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div>
|
||||
<Field name="firstName" component={firstName =>
|
||||
<TextField hintText = "First Name"
|
||||
floatingLabelText="First Name"
|
||||
{...firstName}
|
||||
/>
|
||||
}/>
|
||||
</div>
|
||||
<div>
|
||||
<Field name="lastName" component={lastName =>
|
||||
<TextField
|
||||
hintText = "Last Name"
|
||||
floatingLabelText="Last Name"
|
||||
{...lastName} />
|
||||
}/>
|
||||
</div>
|
||||
<div>
|
||||
<Field name="email" component={email =>
|
||||
<TextField
|
||||
hintText="Email"
|
||||
floatingLabelText="Email"
|
||||
{...email}
|
||||
/>
|
||||
}/>
|
||||
</div>
|
||||
<div>
|
||||
<Field name="sex" component={sex =>
|
||||
<RadioButtonGroup {...sex}>
|
||||
<RadioButton
|
||||
value="male"
|
||||
label="male"
|
||||
/>
|
||||
<RadioButton
|
||||
value="female"
|
||||
label="female"
|
||||
/>
|
||||
</RadioButtonGroup>
|
||||
}/>
|
||||
</div>
|
||||
<div>
|
||||
<Field name="favoriteColor" component={props =>
|
||||
<div>
|
||||
<SelectField
|
||||
{...props}
|
||||
value={props.value}
|
||||
floatingLabelText = "Favourite Color"
|
||||
onChange = {(event, index, value) => props.onChange(value)}
|
||||
>
|
||||
<MenuItem value={'ff0000'} primaryText="Red"/>
|
||||
<MenuItem value={'00ff00'} primaryText="Green"/>
|
||||
<MenuItem value={'0000ff'} primaryText="Blue"/>
|
||||
</SelectField>
|
||||
</div>
|
||||
}/>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<Field name="employed" id="employed" component={ props =>
|
||||
<Checkbox label ="Employed"
|
||||
checked = {props.value ? true : false}
|
||||
onCheck = {(e) => props.onChange(e)}
|
||||
/>
|
||||
}/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<Field name="notes" component={notes =>
|
||||
<TextField hintText="Notes"
|
||||
multiLine = {true}
|
||||
rows={2} {...notes}
|
||||
/>
|
||||
}/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button type="submit" disabled={pristine || submitting}>Submit</button>
|
||||
<button type="button" disabled={pristine || submitting} onClick={reset}>Clear Values</button>
|
||||
</div>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default reduxForm({
|
||||
form: 'MaterialUiForm' // a unique identifier for this form
|
||||
})(MaterialUiForm)
|
||||
85
examples/material-ui/src/index.js
Normal file
85
examples/material-ui/src/index.js
Normal file
@@ -0,0 +1,85 @@
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import injectTapEventPlugin from 'react-tap-event-plugin'
|
||||
import { Provider } from 'react-redux'
|
||||
import { createStore, combineReducers } from 'redux'
|
||||
import { reducer as reduxFormReducer } from 'redux-form'
|
||||
import { App, Code, Markdown, Values, generateExampleBreadcrumbs } from 'redux-form-website-template'
|
||||
injectTapEventPlugin()
|
||||
const dest = document.getElementById('content')
|
||||
const reducer = combineReducers({
|
||||
form: reduxFormReducer // mounted under "form"
|
||||
})
|
||||
const store =
|
||||
(window.devToolsExtension ? window.devToolsExtension()(createStore) : createStore)(reducer)
|
||||
|
||||
const showResults = values =>
|
||||
new Promise(resolve => {
|
||||
setTimeout(() => { // simulate server latency
|
||||
window.alert(`You submitted:\n\n${JSON.stringify(values, null, 2)}`)
|
||||
resolve()
|
||||
}, 500)
|
||||
})
|
||||
|
||||
let render = () => {
|
||||
const MaterialUiForm = require('./MaterialUiForm').default
|
||||
const readme = require('./MaterialUi.md')
|
||||
const raw = require('!!raw!./MaterialUiForm')
|
||||
ReactDOM.render(
|
||||
<Provider store={store}>
|
||||
<App
|
||||
/**
|
||||
* This <App/> component only provides the site wrapper.
|
||||
* Remove it on your dev server if you wish. It will not affect the functionality.
|
||||
*/
|
||||
version={REDUX_FORM_VERSION}
|
||||
path="/examples/material-ui/"
|
||||
breadcrumbs={generateExampleBreadcrumbs('material-ui', 'Material Ui Form Example', REDUX_FORM_VERSION)}>
|
||||
|
||||
<Markdown content={readme}/>
|
||||
|
||||
<h2>Form</h2>
|
||||
|
||||
<MaterialUiForm onSubmit={showResults}/>
|
||||
|
||||
<Values form="MaterialUiForm"/>
|
||||
|
||||
<h2>Code</h2>
|
||||
|
||||
<h4>SimpleForm.js</h4>
|
||||
|
||||
<Code source={raw}/>
|
||||
|
||||
</App>
|
||||
</Provider>,
|
||||
dest
|
||||
)
|
||||
}
|
||||
|
||||
if (module.hot) {
|
||||
// Support hot reloading of components
|
||||
// and display an overlay for runtime errors
|
||||
const renderApp = render
|
||||
const renderError = (error) => {
|
||||
const RedBox = require('redbox-react')
|
||||
ReactDOM.render(
|
||||
<RedBox error={error} className="redbox"/>,
|
||||
dest
|
||||
)
|
||||
}
|
||||
render = () => {
|
||||
try {
|
||||
renderApp()
|
||||
} catch (error) {
|
||||
renderError(error)
|
||||
}
|
||||
}
|
||||
const rerender = () => {
|
||||
setTimeout(render)
|
||||
}
|
||||
module.hot.accept('./MaterialUiForm', rerender)
|
||||
module.hot.accept('./MaterialUi.md', rerender)
|
||||
module.hot.accept('!!raw!./MaterialUiForm', rerender)
|
||||
}
|
||||
|
||||
render()
|
||||
46
examples/material-ui/webpack.config.dev.js
Normal file
46
examples/material-ui/webpack.config.dev.js
Normal file
@@ -0,0 +1,46 @@
|
||||
var path = require('path');
|
||||
var webpack = require('webpack');
|
||||
|
||||
module.exports = {
|
||||
devtool: 'eval',
|
||||
entry: [
|
||||
'babel-polyfill',
|
||||
'eventsource-polyfill', // necessary for hot reloading with IE
|
||||
'webpack-hot-middleware/client',
|
||||
'./src/index'
|
||||
],
|
||||
output: {
|
||||
path: path.join(__dirname, 'dist'),
|
||||
filename: 'bundle.js',
|
||||
publicPath: '/dist/'
|
||||
},
|
||||
plugins: [
|
||||
new webpack.optimize.OccurenceOrderPlugin(),
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
new webpack.DefinePlugin({ REDUX_FORM_VERSION: JSON.stringify('6.0.0-alpha.6') })
|
||||
],
|
||||
resolve: {
|
||||
modulesDirectories: [
|
||||
'src',
|
||||
'node_modules'
|
||||
],
|
||||
extensions: [ '', '.json', '.js' ]
|
||||
},
|
||||
module: {
|
||||
loaders: [
|
||||
{
|
||||
test: /\.jsx?/,
|
||||
loaders: [ 'babel', 'eslint' ],
|
||||
include: path.join(__dirname, 'src')
|
||||
},
|
||||
{
|
||||
test: /\.json$/,
|
||||
loader: 'json-loader'
|
||||
},
|
||||
{
|
||||
test: /\.md/,
|
||||
loaders: [ "html-loader", "markdown-loader" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
53
examples/material-ui/webpack.config.prod.js
Normal file
53
examples/material-ui/webpack.config.prod.js
Normal file
@@ -0,0 +1,53 @@
|
||||
var path = require('path');
|
||||
var webpack = require('webpack');
|
||||
|
||||
module.exports = {
|
||||
devtool: 'source-map',
|
||||
entry: [
|
||||
'babel-polyfill',
|
||||
'./src/index'
|
||||
],
|
||||
output: {
|
||||
path: path.join(__dirname, 'dist'),
|
||||
filename: 'bundle.js',
|
||||
publicPath: '/dist/'
|
||||
},
|
||||
plugins: [
|
||||
new webpack.optimize.OccurenceOrderPlugin(),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: JSON.stringify('production')
|
||||
},
|
||||
REDUX_FORM_VERSION: JSON.stringify('6.0.0-alpha.6')
|
||||
}),
|
||||
new webpack.optimize.UglifyJsPlugin({
|
||||
compressor: {
|
||||
warnings: false
|
||||
}
|
||||
})
|
||||
],
|
||||
resolve: {
|
||||
modulesDirectories: [
|
||||
'src',
|
||||
'node_modules'
|
||||
],
|
||||
extensions: [ '', '.json', '.js' ]
|
||||
},
|
||||
module: {
|
||||
loaders: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
loaders: [ 'babel' ],
|
||||
include: path.join(__dirname, 'src')
|
||||
},
|
||||
{
|
||||
test: /\.json$/,
|
||||
loader: 'json-loader'
|
||||
},
|
||||
{
|
||||
test: /\.md/,
|
||||
loaders: [ "html-loader", "markdown-loader" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user