I have a FieldArray input in my redux-form and want to print the values of that form on the table. I am new to React but have some JavaScript experience. PLEASE HELP. It has been 47 hours and I still dont have a clue on how to print the values passed on redux-form to may table rows. PLEASE HELP.
YOU CAN SEE App.js and Index.js here-
APP.JS -
import React, { Component } from ‘react’;
import { reduxForm,FieldArray, Field,formValueSelector } from ‘redux-form’;
import MuiThemeProvider from ‘material-ui/styles/MuiThemeProvider’;
import injectTapEventPlugin from ‘react-tap-event-plugin’;
import TextField from ‘material-ui/TextField’;
import RaisedButton from ‘material-ui/RaisedButton’;
import FloatingActionButton from ‘material-ui/FloatingActionButton’;
import ContentAdd from ‘material-ui/svg-icons/content/add’;
import {fullWhite} from ‘material-ui/styles/colors’;
import ActionAndroid from ‘material-ui/svg-icons/action/android’;
import FontIcon from ‘material-ui/FontIcon’;
import DatePicker from ‘material-ui/DatePicker’;
import moment from ‘moment’;
import logo from ‘./logo.svg’;
import {Table,TableBody,TableHeader,TableHeaderColumn,TableRow,TableRowColumn,} from ‘material-ui/Table’;
import IconButton from ‘material-ui/IconButton’;
import DeleteIcon from ‘material-ui/IconButton’;
import ActionHome from ‘material-ui/svg-icons/action/home’;
import {connect} from ‘react-redux’
import ‘./App.css’;
injectTapEventPlugin();
const renderField = ({ input, label, meta: { touched, error }, ...custom }) => (
<div>
<TextField
hintText={label}
floatingLabelText={label}
errorText={touched && error && <span>{error}</span>}
{...input}
{...custom}/>{/*things will not work if you don't write {...custom} instead of type={type} since it s material-Ui text field */}
</div>
)
const renderHobbies = ({ fields, meta: { error } }) => (
<ul>
<li>
<RaisedButton label="Add hobby" primary={true} onClick={() => fields.push()} /> {/*see hobbies only have () brackets while members has ({}) brackets*/}
{/*<button type="button" onClick={() => fields.push()}>
Add Hobby
</button>*/}
</li>
{fields.map((hobby, index) => (
<li key={index}>
<RaisedButton label="Remove Hobby" onClick={() => fields.remove(index)}/>
{/* <button
type="button"
title="Remove Hobby"
onClick={() => fields.remove(index)}
/> */}
<Field
name={hobby}
type="text"
component={renderField}
label={`Hobby #${index + 1}`}
/>
</li>
))}
{error && <li className="error">{error}</li>}
</ul>
)
const renderMembers = ({ fields, meta: { error, submitFailed } }) => (
<ul>
<li>
<DatePicker
hintText="Controlled Date Input"
onChange={this.handleChange}
/>
<FloatingActionButton onClick={() => fields.push({})}> {/* see the main array has ({}) brackets while the hobbies array only has () brackets*/}
<ContentAdd />
</FloatingActionButton>
{/*} <button type="button" onClick={() => fields.push({})}>
Add Member
</button> */}
{submitFailed && error && <span>{error}</span>}
</li>
{fields.map((member, index) => ( //below each 'member' will be asked to make hobbies
<li key={index}>
<FloatingActionButton onClick={() => fields.push({})}>
<ContentAdd />
</FloatingActionButton>
<FloatingActionButton secondary = {true} onClick={() => fields.remove(index)}>
<ContentAdd />
</FloatingActionButton>
{/*} <button
type="button"
title="Remove Member"
onClick={() => fields.remove(index)}
/> */}
<h4>Member #{index + 1}</h4>
<Field
name={`${member}.firstName`}
type="text"
component={renderField}
label="First Name"
/>
<Field
name={`${member}.lastName`}
type="text"
component={renderField}
label="Last Name"
/>
<FieldArray name={`${member}.hobbies`} component={renderHobbies} />
</li>
))}
</ul>
)
let SignInForm = props => {
const {
handleChange,
handleSubmit,
pristine,
values,
reset,
submitting
} = props
return (
<MuiThemeProvider>
<form onSubmit={handleSubmit}>
<label>Wlecome to presentation scheduler</label>
<FieldArray name="members" component={renderMembers}/>
<div>
<RaisedButton disabled={submitting}
type="submit"
label="Submit"
labelPosition="after"
primary={true}
icon={<ActionAndroid />}
/>
{/*} <button type="submit" disabled={submitting}>
Submit
</button> */}
<RaisedButton disabled={pristine || submitting} onClick={reset}
label="Clear Values"
labelPosition="after"
secondary={true}
icon={<ActionAndroid />}
/>
{/*} <button type="button" disabled={pristine || submitting} onClick={reset}>
Clear Values
</button> */}
</div>
</form>
<div>
<Table>
<TableHeader>
<TableRow>
<TableHeaderColumn>ID</TableHeaderColumn>
<TableHeaderColumn>First Name</TableHeaderColumn>
<TableHeaderColumn>Last Name</TableHeaderColumn>
<TableHeaderColumn>List of Hobbies (1 - 5)</TableHeaderColumn>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableRowColumn>Name is</TableRowColumn>
<TableRowColumn>uhkhk</TableRowColumn>
<TableRowColumn>{this.submit}</TableRowColumn>
<TableRowColumn>Readng</TableRowColumn>
</TableRow>
</TableBody>
{/* <TableRow>
<TableRowColumn style={styles.add}>
<IconButton
onClick={() => fields.insert(fields.length, fromJS({}))}
> <AddIcon />
</IconButton>
{(touched || submitFailed) && error && <span>{error}</span>}
</TableRowColumn>
</TableRow> */}
</Table>
</div>
</MuiThemeProvider>
);
};
class App extends Component {
constructor(props) {
super(props);
this.state = {
controlledDate: moment(),
};
}
submit = (values) => {
console.log(values);
return (
<div>{values.email}</div>
)
}
handleChange = (event, date) => {
this.setState({
controlledDate: date,
});
};
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Redux Form </h2>
<h1 className="App-title">Hellow React</h1>
</header>
<p className="App-intro">
Welcome to shiny app
</p>
<SignInForm onSubmit={this.submit}
/>
</div>
);
}
}
const validate = values => {
const errors = {};
if (!values.email) {
console.log('email is required');
errors.email = 'Required';
} else if (!/^.+@.+$/i.test(values.email)) {
console.log('email is invalid');
errors.email = 'Invalid email';
}
if (!values.password) {
console.log('password is required');
errors.password = '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) { //agar hobby ka area bhi theek type kar diya toh bhar diya toh
memberErrors.hobbies = hobbyArrayErrors //provide no hobby errors and only memberErrors
membersArrayErrors[memberIndex] = memberErrors //provide only memberError sas there are no hobby errors
}
if (member.hobbies.length > 5) {
if (!memberErrors.hobbies) { // If no memberErrors.hobbies then create a memberErrors.hobbies for more stuff to come
memberErrors.hobbies = [] //Allow more stuff to come if there are no memberError.hobbies
}
memberErrors.hobbies._error = 'No more than five hobbies allowed' //In any case dont allow more than 5 to come
membersArrayErrors[memberIndex] = memberErrors //provide this error irrespective of anything
}
}
})
if (membersArrayErrors.length) {
errors.members = membersArrayErrors
}
}
return errors;
};
SignInForm=reduxForm({
form: 'signIn',
validate
})(SignInForm);
export default App;
INDEX.JS -
import React from ‘react’;
import ReactDOM from ‘react-dom’;
import ‘./index.css’;
import App from ‘./App’;
import registerServiceWorker from ‘./registerServiceWorker’;
import { Provider } from ‘react-redux’;
import { createStore, combineReducers } from ‘redux’;
import { reducer as formReducer } from ‘redux-form’;
const rootReducer = combineReducers({
form: formReducer,
});
const store = createStore(rootReducer);
ReactDOM.render(
<Provider store={ store }>
<App />
</Provider>,
document.getElementById('root'));