CAN SOMEONE PLEASE HELP - HOW TO PRINT VALUES OF Material-Ui REDUX FORM to Material-Ui Table after pressing Submit button ?


#1

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