jh5614
jh5614

Reputation: 11

ReactJS: Getting inputs from form

I am currently trying to get the complete input from a user in a form using React. I need to get these inputs and then store them so that I can pass these values to another function. Currently, I have been trying to use uncontrolled inputs without success, but have also tried controlled inputs without any success either. Any ideas? I have to pass these values to the function peopleContract.addPerson(this._firstName, this._lastName, this._email, {from: accounts[1], gas: 3000000})

Here is the code (commented is the controlled input approach):

import React from 'react';
import Web3 from 'web3';

//Declaring the ethereum client (initializing) with the url in which the testrpc is running
var ETHEREUM_CLIENT = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"))

//These could be dynamically added through input fields, but hard coding for now
var peopleContractABI = [{"constant":true,"inputs":[],"name":"getPeople","outputs":[{"name":"","type":"bytes32[]"},{"name":"","type":"bytes32[]"},{"name":"","type":"bytes32[]"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"people","outputs":[{"name":"firstName","type":"bytes32"},{"name":"lastName","type":"bytes32"},{"name":"email","type":"bytes32"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_firstName","type":"bytes32"},{"name":"_lastName","type":"bytes32"},{"name":"_email","type":"bytes32"}],"name":"addPerson","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"}]

var peopleContractAddress = '0xb1a711f4e1250761b85be7bb4478c07d256b8225'

var peopleContract = ETHEREUM_CLIENT.eth.contract(peopleContractABI).at(peopleContractAddress)

//Need to create a variable named accounts in order to know which account
//to make the transactions from
var accounts = ETHEREUM_CLIENT.eth.accounts

//Creating the dynamic input fields for the user to input his/her data
export class Form extends React.Component{
  handleSubmitClick = () => {
    const firstName = this._firstName.value;
    const lastName = this._lastName.value;
    const email = this._email.value;
    //do something with these variables
  }

/*
  handleChange(event) {
    this.setState({[key]: event.target.value});
  }
*/

/*
  handleChange(event) {
    this.setState({[event.target.name]: event.target.value});
  }

  handleSubmit(event) {
    alert('A user was submitted: ' + this.state.firstName + this.state.lastName + this.state.email);
    event.preventdefault();
*/

/*
    if((this.state.firstName==!"") && (this.state.lastName==!"")&& (this.state.email==!"")){
        peopleContract.addPerson(this.state.firstName, this.state.lastName, this.state.email, {from: accounts[1], gas: 3000000})

        // after you subimt values clear state
        this.setState({
            firstName: this.state.firstName,
            lastName: this.state.lastName,
            email: this.state.email
        })
    }else{
        // render error
        alert('Some fields are mandatory');
    }
}
*/

/*
  componentWillMount(){
    peopleContract.addPerson(this._firstName, this._lastName, this._email, {from: accounts[1], gas: 3000000})
  }
  */


  render() {
    peopleContract.addPerson(this._firstName, this._lastName, this._email, {from: accounts[1], gas: 3000000})
    return(
      <form>
      <div>
        <h4>Name</h4>
          <input
            type="text"
            ref={input => this._firstName = input} />
      </div>
      <div>
        <h4>Last Name</h4>
          <input
            type="text"
            ref = {input2 => this._lastName = input2} />
      </div>
      <div>
        <h4>Email</h4>
          <input
            type="text"
            ref = {input3 => this._email = input3}  />
        </div>
        <button onClick={this.handleSubmitClick}>Submit</button>
      </form>
    );
  }
}

Upvotes: 0

Views: 82

Answers (2)

Mayank Shukla
Mayank Shukla

Reputation: 104369

By using ref callback we store the reference of dom element, As per DOC:

When the ref attribute is used on an HTML element, the ref callback receives the underlying DOM element as its argument. For example, this code uses the ref callback to store a reference to a DOM node:

ref = { (input) => { this.textInput = input; }} />

To get the values of uncontrolled component using ref you need to write:

this._firstName.value,    //value

this._lastName.value,     //value

this._email.value         //value

Another change is remove this line from render method:

peopleContract.addPerson(this._firstName, this._lastName, this._email, {from: accounts[1], gas: 3000000})

Because during initial rendering ref will not be available, so it you try to access the value before rendering it will throw error.

The ref attribute takes a callback function, and the callback will be executed immediately after the component is mounted or unmounted.

Check the working solution:

class Form extends React.Component{

  handleSubmitClick() {
    const firstName = this._firstName.value;
    const lastName = this._lastName.value;
    const email = this._email.value;
    console.log(firstName, lastName,email);
    peopleContract.addPerson(firstName, lastName, email, {from: accounts[1], gas: 3000000})
  }

  render() {
    return(
      <form>
      <div>
        <h4>Name</h4>
          <input
            type="text"
            ref={input => this._firstName = input} />
      </div>
      <div>
        <h4>Last Name</h4>
          <input
            type="text"
            ref = {input2 => this._lastName = input2} />
      </div>
      <div>
        <h4>Email</h4>
          <input
            type="text"
            ref = {input3 => this._email = input3}  />
        </div>
        <button onClick={this.handleSubmitClick.bind(this)}>Submit</button>
      </form>
    );
  }
}

ReactDOM.render(<Form/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id='app'/>

Upvotes: 0

Luke Vella
Luke Vella

Reputation: 746

You are trying to use the refs before they are assigned in the render function.

It seems like you want to call peopleContract.addPerson() on submit so it should look like this

export class Form extends React.Component{
  handleSubmitClick = () => {
    const firstName = this._firstName.value;
    const lastName = this._lastName.value;
    const email = this._email.value;

    peopleContract.addPerson(firstName, lastName, email, {from: accounts[1], gas: 3000000})
  }
  render() {
    return(
      <form>
      <div>
        <h4>Name</h4>
          <input
            type="text"
            ref={input => this._firstName = input} />
      </div>
      <div>
        <h4>Last Name</h4>
          <input
            type="text"
            ref = {input2 => this._lastName = input2} />
      </div>
      <div>
        <h4>Email</h4>
          <input
            type="text"
            ref = {input3 => this._email = input3}  />
        </div>
        <button onClick={this.handleSubmitClick}>Submit</button>
      </form>
    );
  }
}

Upvotes: 1

Related Questions