The original example: Redux Form - Field Arrays Example
Last active
October 28, 2017 14:30
-
-
Save shinaisan/8220c38644302f73bffe006cca29cb78 to your computer and use it in GitHub Desktop.
Redux Form - Field Arrays Example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import FieldArraysForm from './FieldArraysForm'; | |
import { createStore } from 'redux'; | |
import { Provider } from 'react-redux'; | |
import reducer from './reducer'; | |
import "bootstrap/dist/css/bootstrap.css"; | |
const store = createStore(reducer); | |
class App extends React.Component { | |
constructor(props) { | |
super(props); | |
this.state = {debug: ''}; | |
} | |
handleSubmit(values) { | |
const self = this; | |
self.setState({debug: JSON.stringify(values)}); | |
} | |
render() { | |
const onSubmit = this.handleSubmit.bind(this); | |
return ( | |
<Provider store={store}> | |
<div> | |
<FieldArraysForm onSubmit={onSubmit} /> | |
<div> | |
<pre>{this.state.debug}</pre> | |
</div> | |
</div> | |
</Provider> | |
); | |
} | |
} | |
export default App; | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
NAME=redux-form-selecting-form-values | |
echo -n "This script runs create-react-app $NAME. Proceed? (Y/N) " | |
read YN | |
if [ x$YN != xY ] | |
then | |
echo "Bye." | |
exit | |
fi | |
# Delete this line only if you are sure what is done from this line on. | |
exit | |
create-react-app $NAME | |
cd $NAME | |
cp -v ../package.json . | |
cd src | |
rm -f App.* logo.svg | |
cp -v ../../*.js . | |
cd .. | |
yarn install | |
echo 'To launch the dev server, run `yarn run start`.' | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react' | |
import { Field, FieldArray, reduxForm } from 'redux-form' | |
import validate from './validate' | |
import { | |
Form, | |
ListGroup, ListGroupItem, | |
Row, Col, | |
Button | |
} from 'react-bootstrap' | |
import 'font-awesome/css/font-awesome.css' | |
import FontAwesome from 'react-fontawesome' | |
const renderField = ({ input, label, type, meta: { touched, error } }) => ( | |
<div> | |
<Col sm={2}> | |
<label>{label}</label> | |
</Col> | |
<Col sm={4}> | |
<input {...input} type={type} placeholder={label} size="40"/> | |
{touched && error && <span>{error}</span>} | |
</Col> | |
</div> | |
) | |
const renderHobbies = ({ fields, meta: { error } }) => ( | |
<ListGroup> | |
<ListGroupItem listItem> | |
<Button type="button" bsStyle="primary" | |
onClick={() => fields.push()}> | |
<FontAwesome name="plus"/>{' '}Add Hobby | |
</Button> | |
</ListGroupItem> | |
{fields.map((hobby, index) => ( | |
<ListGroupItem listItem key={index}> | |
<Button | |
type="button" | |
bsStyle="danger" | |
title="Remove Hobby" | |
onClick={() => fields.remove(index)} | |
> | |
<FontAwesome name="trash"/>{' '}Remove Hobby | |
</Button> | |
<Row> | |
<Field | |
name={hobby} | |
type="text" | |
component={renderField} | |
label={`Hobby #${index + 1}`} | |
/> | |
</Row> | |
</ListGroupItem> | |
))} | |
{error && <ListGroupItem listItem className="error">{error}</ListGroupItem>} | |
</ListGroup> | |
) | |
const renderMembers = ({ fields, meta: { error, submitFailed } }) => ( | |
<ListGroup> | |
<ListGroupItem listItem> | |
<Button type="button" bsStyle="primary" | |
onClick={() => fields.push({})}> | |
<FontAwesome name="plus"/>{' '}Add Member | |
</Button> | |
{submitFailed && error && <span>{error}</span>} | |
</ListGroupItem> | |
{fields.map((member, index) => ( | |
<ListGroupItem listItem key={index}> | |
<Button | |
type="button" | |
bsStyle="danger" | |
title="Remove Member" | |
onClick={() => fields.remove(index)} | |
> | |
<FontAwesome name="trash"/>{' '}Remove Member | |
</Button> | |
<h4>Member #{index + 1}</h4> | |
<Row> | |
<Field | |
name={`${member}.firstName`} | |
type="text" | |
component={renderField} | |
label="First Name" | |
/> | |
<Field | |
name={`${member}.lastName`} | |
type="text" | |
component={renderField} | |
label="Last Name" | |
/> | |
</Row> | |
<FieldArray name={`${member}.hobbies`} component={renderHobbies} /> | |
</ListGroupItem> | |
))} | |
</ListGroup> | |
) | |
const FieldArraysForm = props => { | |
const { handleSubmit, pristine, reset, submitting } = props | |
return ( | |
<Form onSubmit={handleSubmit}> | |
<Row> | |
<Field | |
name="clubName" | |
type="text" | |
component={renderField} | |
label="Club Name" | |
/> | |
</Row> | |
<FieldArray name="members" component={renderMembers} /> | |
<div> | |
<Button type="submit" bsStyle="primary" disabled={submitting}> | |
Submit | |
</Button> | |
<Button type="button" bsStyle="default" disabled={pristine || submitting} onClick={reset}> | |
Clear Values | |
</Button> | |
</div> | |
</Form> | |
) | |
} | |
export default reduxForm({ | |
form: 'fieldArrays', // a unique identifier for this form | |
validate | |
})(FieldArraysForm) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "redux-form-initialize-from-state", | |
"version": "0.1.0", | |
"private": true, | |
"dependencies": { | |
"bootstrap": "^3.3.7", | |
"font-awesome": "^4.7.0", | |
"react": "^16.0.0", | |
"react-bootstrap": "^0.31.5", | |
"react-dom": "^16.0.0", | |
"react-fontawesome": "^1.6.1", | |
"react-redux": "^5.0.6", | |
"redux": "^3.7.2", | |
"redux-form": "^7.1.2" | |
}, | |
"devDependencies": { | |
"react-scripts": "1.0.14" | |
}, | |
"scripts": { | |
"start": "react-scripts start", | |
"build": "react-scripts build", | |
"test": "react-scripts test --env=jsdom", | |
"eject": "react-scripts eject" | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { combineReducers } from 'redux'; | |
import { reducer as formReducer } from 'redux-form'; | |
const rootReducer = combineReducers({ | |
form: formReducer | |
}); | |
export default rootReducer; | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const validate = values => { | |
const errors = {} | |
if (!values.clubName) { | |
errors.clubName = 'Required' | |
} | |
if (!values.members || !values.members.length) { | |
errors.members = { _error: 'At least one member must be entered' } | |
} else { | |
const membersArrayErrors = [] | |
values.members.forEach((member, memberIndex) => { | |
const memberErrors = {} | |
if (!member || !member.firstName) { | |
memberErrors.firstName = 'Required' | |
membersArrayErrors[memberIndex] = memberErrors | |
} | |
if (!member || !member.lastName) { | |
memberErrors.lastName = 'Required' | |
membersArrayErrors[memberIndex] = memberErrors | |
} | |
if (member && member.hobbies && member.hobbies.length) { | |
const hobbyArrayErrors = [] | |
member.hobbies.forEach((hobby, hobbyIndex) => { | |
if (!hobby || !hobby.length) { | |
hobbyArrayErrors[hobbyIndex] = 'Required' | |
} | |
}) | |
if (hobbyArrayErrors.length) { | |
memberErrors.hobbies = hobbyArrayErrors | |
membersArrayErrors[memberIndex] = memberErrors | |
} | |
if (member.hobbies.length > 5) { | |
if (!memberErrors.hobbies) { | |
memberErrors.hobbies = [] | |
} | |
memberErrors.hobbies._error = 'No more than five hobbies allowed' | |
membersArrayErrors[memberIndex] = memberErrors | |
} | |
} | |
}) | |
if (membersArrayErrors.length) { | |
errors.members = membersArrayErrors | |
} | |
} | |
return errors | |
} | |
export default validate |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment