Skip to content

Instantly share code, notes, and snippets.

@danielrob
Created July 27, 2017 22:24
Show Gist options
  • Save danielrob/a5d75dcfcc6c8a2e733b823bce886e81 to your computer and use it in GitHub Desktop.
Save danielrob/a5d75dcfcc6c8a2e733b823bce886e81 to your computer and use it in GitHub Desktop.
FieldArray with radio buttons dependent extras
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { Values } from 'redux-form-website-template';
import store from './store';
import showResults from './showResults';
import SimpleForm from './SimpleForm';
const rootEl = document.getElementById('root');
ReactDOM.render(
<Provider store={store}>
<div style={{ padding: 15 }}>
<h2>Less Simple Form</h2>
<SimpleForm onSubmit={showResults} />
<Values form="lessSimple" />
</div>
</Provider>,
rootEl,
);
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
export default (async function showResults(values) {
await sleep(500); // simulate server latency
window.alert(`You submitted:\n\n${JSON.stringify(values, null, 2)}`);
});
import React from 'react';
import { connect } from 'react-redux'
import { Field, reduxForm, FieldArray, formValueSelector } from 'redux-form';
const Animal = ({ name, isSelected }) => (
<span>
<Field
name={`${name}.name`}
type="text"
component="input"
/>
<span style={{width: '20px', display: 'inline-block'}}/>
{isSelected && (
<Field
name={`${name}.options`}
type="text"
component="input"
placeholder="more details"
/>
)}
</span>
)
const renderAnimals = ({ fields, meta: { error }, selectedIndex }) => (
<ul>
<li>
</li>
{fields.map((animal, index) => (
<li key={index}>
<Field
name="selectedIndex"
type="radio"
component="input"
normalize={value => parseInt(value)}
value={index}
/>
<span style={{width: '20px', display: 'inline-block'}}/>
{/* This is seperated so that only the two items whose props will change need to re-render when there is a change */}
<Animal name={animal} isSelected={selectedIndex === index}/>
</li>
))}
{error && <li className="error">{error}</li>}
</ul>
);
const RenderAnimals = connect(
state => ({
selectedIndex: formValueSelector('lessSimple')(state, 'selectedIndex')
})
)(renderAnimals)
const SimpleForm = props => {
const { handleSubmit, pristine, reset, submitting } = props;
return (
<form onSubmit={handleSubmit}>
<FieldArray
name="animals"
component={RenderAnimals}
/>
<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: 'lessSimple', // a unique identifier for this form
initialValues: {
selectedIndex: 1,
animals: [
{ name: "dog", options: "" },
{ name: "cat", options: "" },
{ name: "mouse", options: "" },
]
}
})(SimpleForm);
import { createStore, combineReducers } from 'redux';
import { reducer as reduxFormReducer } from 'redux-form';
const reducer = combineReducers({
form: reduxFormReducer, // mounted under "form"
});
const store = (window.devToolsExtension
? window.devToolsExtension()(createStore)
: createStore)(reducer);
export default store;
@danielrob
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment