Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReactJS: How do I add a new row to table from Form input values?

I'm learning ReactJS.

I'd like to add text into a input field and then click a submit button. this new value is add to a table.

I've started with a simple form component that has input values first name and last name. A table component that extends the form. the form added to the default App class.

Form.js

import React, { Component } from 'react';
import './form.css';

export default class Form extends Component {


  render(){
      return(
        <div id="Form">

          <form onSubmit={this.handleSubmit}>
              Username<br/>
              <input type="text" name="username" placeholder="Username" /><br/>
              Password<br/>
              <input type="password" name="password" placeholder="Password"/><br/>
              <br/>
              <input type="submit" value="Submit" />
          </form>
        </div>
      );
    }

}

Table.js

import React, { Component } from 'react';
import './table.css';
import Form from './Form.js';

export default class Table extends Form {
  render(){
      return(
        <div id="Table">
          <table>
            <tr>
              <th>Username</th>
              <th>Password</th>
            </tr>
            <tr>
              <td>a</td>
              <td></td>
            </tr>

          </table>
        </div>
      );
    }

}

App.js

import React, { Component } from 'react';
import logo from './logo.svg';
import Table from './Table.js';
import Form from './Form.js';
import './App.css';

class App extends Component {
  render() {
    return (
      <div className="App">
        <Form />
      </div>
    );
  }
}

export default App;
like image 398
Abdirizak Obsiye Avatar asked Jan 20 '18 00:01

Abdirizak Obsiye


2 Answers

I made a CodePen with a working example.

Explanation

You have to write the methods on your parent component and pass them as props to your child components. The state of your application will be on the parent component as well.

The methods you should create are the handleInputChange and handleFormSubmit. You have to pass both methods as props to your Form component.

And the state will have a 'username' and a 'password' for the new item, and an array of existing items and where the new items will be added. You will pass the array of items to your Table component as a prop.

In the Table component just map the items prop and print a <tr> with the data for each item in the array.

./App.js

import React, { Component } from 'react';
import './App.css';
import Table from './Table';
import Form from './Form';

class App extends Component {
  constructor() {
    super();

    this.state = {
      username: '',
      password: '',
      items: []
    }
  };

  handleFormSubmit = (e) => {
    e.preventDefault();

    let items = [...this.state.items];

    items.push({
      username: this.state.username,
      password: this.state.password
    });

    this.setState({
      items,
      username: '',
      password: ''
    });
  };

  handleInputChange = (e) => {
    let input = e.target;
    let name = e.target.name;
    let value = input.value;

    this.setState({
      [name]: value
    })
  };

  render() {
    return (
      <div className="App">
        <Table items={ this.state.items }/>
        <Form handleFormSubmit={ this.handleFormSubmit } 
          handleInputChange={ this.handleInputChange }
          newUsername={ this.state.username }
          newPassword={ this.state.password } />
      </div>
    );
  }
}

export default App;

./Form.js

import React, { Component } from 'react';

class Form extends React.Component {
  render() {
    return (
      <div id="Form">
        <h3>Add a new item to the table:</h3>  
        <form onSubmit={this.props.handleFormSubmit}>
          <label htmlFor="username">
          Username:
          <input id="username" value={this.props.newUsername} 
            type="text" name="username"
            onChange={this.props.handleInputChange} />
          </label>
          <label for="password">
          Password:
          <input id="password" value={this.props.newPassword} 
            type="password" name="password"
            onChange={this.props.handleInputChange} />
          </label>
          <button type="submit" value="Submit">Add Item</button>
        </form>
      </div>
    );
  }
}

export default Form;

./Table.js

import React, { Component } from 'react';

class Table extends React.Component {
  render() {
    const items = this.props.items;
    return (
      <div id="Table">
        <table>
          <tbody>
            <tr>
              <th>Username</th>
              <th>Password</th>
            </tr>
            {items.map(item => {
              return (
                <tr>
                  <td>{item.username}</td>
                  <td>{item.password}</td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    );
  }
}

export default Table;

I recommend you to read the Controlled Components section of the React documentation.

For more complex form cases you could use Redux and redux-form.

I hope this will help.

like image 125
Giu Magnani Avatar answered Nov 15 '22 03:11

Giu Magnani


You can do like below. store your input field values to an array state and pass it to your Table component as props. In your Table component take an array variable and iterate your formData props then push username and password to rows array and print that.

Full functionality you can check below

Form.js

import React, { Component } from 'react';
import './form.css';
import Table './Table.js';

export default class Form extends Component {
    constructor(props){
    super(props);
    this.state = {
    uName: '',
    uPassword: '',
    formValid: false,
    formData: []
}
    this.changeUsername = this.changeUsername.bind(this);
    this.changePassword = this.changePassword.bind(this);
}

changeUsername(event){
   this.setState({
      uName: event.target.value
   })
}

changePassword(event){
    this.setState({
      uPassword: event.target.value
    })
}

handleSubmit(e){
     e.preventDefault();
     if(this.state.uName != "" && this.state.uPassword != "" && this.state.uName != null && this.state.uPassword != null){
         let object = {}
         object.username = this.state.uName;
         object.password = this.state.uPassword;

         this.setState({
            formValid: true,
            formData: obj
          })

     }
}

renderTable(){
     <Table formData = {this.state.formData} />
}

  render(){
      return(
        <div id="Form">

          <form onSubmit={this.handleSubmit}>
              Username<br/>
              <input type="text" value = {this.state.uName} name="username" placeholder="Username" onChange={this.changeUsername}/><br/>
              Password<br/>
              <input type="password" value = {this.state.uPassword} name="password" placeholder="Password" onChange={this.changePassword}/><br/>
              <br/>
              <input type="submit" value="Submit" />
          </form>
{this.state.formValid ? this.renderTable() : ''}
        </div>
      );
    }

}

Table.js

import React, { Component } from 'react';
import './table.css';

export default class Table extends Form {
constructor(props){
    super(props);

}
  render(){
     const {formData} = this.props;
     let rows = []
     if(formData){
       for(var i=0; i<formData.length;i++){
        rows.push(<tr><td>{formData[i].username}</td><td>{formData[i].password}</td></tr>)
        }  
      }
      return(
        <div id="Table">
          <table>
            <tr>
              <th>Username</th>
              <th>Password</th>
            </tr>
            {rows}

          </table>
        </div>
      );
    }
   }
like image 32
Hemadri Dasari Avatar answered Nov 15 '22 04:11

Hemadri Dasari