Added simple form example with material-ui.

This commit is contained in:
Mihir Soni
2016-04-27 22:15:57 +05:30
committed by Erik Rasmussen
parent 26a483ddf6
commit 71b32925c3
11 changed files with 516 additions and 1 deletions

View File

@@ -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
---

View File

@@ -0,0 +1,3 @@
{
"presets": ["react", "es2015"]
}

View 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/).

View 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');
});

View 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>

View 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"
}
}

View 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.

View 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)

View 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()

View 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" ]
}
]
}
};

View 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" ]
}
]
}
};