0

Still new to all things reactjs and JavaScript, so this maybe something simple, but I have yet to find an example when searching online.

I would like to build a table with each row having an input box and a onClick/submit that will then send the input amount entered for that row in the function or just some way to access the input data for that row. The rows are built from an array saved in state.

Here is a stripped down code of where I am currently at. This is only the table that gets called by a higher level container that passes down biweeklyPays and saveChanges.

function PayoutsTable(props) {
    var payoutRows = []
    var biweeklyPays = props.biweeklyPays
    for (let b of biweeklyPays) {
        payoutRows.push(
            <tr>
                <td>{b.user.first_name + ' ' + b.user.last_name}</td>
                <td>{b.biweeklyPay.payoutAmount}</td>
                <td><input className="form-control" type="number" id="payoutAmount" step=".01" min="0" /></td>
                <td><button className="btn btn-primary" onClick={() => props.saveChanges(b)}>Submit</button></td>
            </tr>
        )
    }
    return (
        <div>
            <table className="table table-responsive table-striped">
                <thead>
                    <tr>
                        <th>Name</th>
                        <th>Payout Amount</th>
                        <th></th>
                        <th></th>
                    </tr>
                 </thead>
                 <tbody>
                     {payoutRows}
                 </tbody>
             </table>
        </div>
    )
}

1 Answer 1

1

What you've created is pure, stateless component which by definition cannot be used for stateful "solutions" like editing input or other forms.

You should convert your components into class with state and update state when input value is changed.

Steps:

  1. convert to class (https://facebook.github.io/react/docs/state-and-lifecycle.html#converting-a-function-to-a-class)
  2. render actual value in input -> <input ... value={this.state.values[i]} .../>
  3. register for changes in input -> this.updateInput(i, e) }`
  4. button shall send local state to parent -> <button ... onClick={() => this.props.saveChanges(b, this.state.values[i])

(i is index of your iteration, you can change your for into for example _.forEach(biweeklyPays, (b, i) => { .... })

I assumed that you keep array of input values in state, to accomplish this you should initialize your component like this:

getInitialState: function() {
    return { values: [] };
}

The onUpdateRowValue(i, e) mentioned shall just update i-th element of state:

onUpdateRowValue: function(i, e) {
    var values = this.values.slice(0);
    values[i] = e.target.value
    this.setState({values: values});
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.