I have this ponent in React JS. I have 3 input fields. One for pounds, one for PPP (Price Per Pound) and the other one is the total. A user inputs the pounds they want in the input field, I already pass the PPP as a value by default, and then I want to calculate the total by multiplying price * ppp as the user is typing.
This is the whole ponent:
class NewTransaction extends React.Component {
constructor(props) {
super(props);
this.state = {
pounds: '',
ppp: 2.10,
total: 0
};
this.handleFormSubmit = this.handleFormSubmit.bind(this);
this.handlePoundsChange = this.handlePoundsChange.bind(this);
this.handlePPPChange = this.handlePPPChange.bind(this);
this.handleTotalChange = this.handleTotalChange.bind(this);
}
ponentWillMount(){}
handlePoundsChange(event) {
this.setState({value: event.target.value});
}
handlePPPChange(event) {
this.setState({value: event.target.value});
}
handleTotalChange(event) {
this.setState({value: event.target.value});
}
handleFormSubmit(event) {
event.preventDefault();
let pounds = $("#pounds").val();
let ppp = $("#ppp").val();
let total = ppp * pounds;
console.log(total);
axios.post('/api/add/transaction', {
pounds: pounds,
ppp: ppp,
total: total
})
.then(function (response) {
console.log(response);
$("#pounds").val('');
$("#ppp").val('');
$("#total").val('');
})
.catch(function (error) {
console.log(error.response.data);
});
}
render() {
return (
<div className="container">
<form className="container" onSubmit={this.handleFormSubmit}>
<table className="table table-bordered">
<tbody>
<tr>
<td>Pounds</td>
<td>
<input type="text" name="pounds" id="pounds" className="form-control" placeholder="Enter Pounds..." onChange={this.handlePoundsChange} required />
</td>
</tr>
<tr>
<td>Price</td>
<td>
<input type="text" name="ppp" id="ppp" className="form-control" value="2.10" onChange={this.handlePPPChange} required />
</td>
</tr>
<tr>
<td>Total</td>
<td>
<input type="text" name="total" id="total" className="form-control" onChange={this.handleTotalChange} />
</td>
</tr>
</tbody>
</table>
<div className="col-xs-12">
<input
type="submit"
className="btn btn-block btn-primary"
value="Customer Checkout"/>
</div>
</form>
</div>
)
}
}
So if a user enters 2 in the pounds input field, React will go in and multiply 2 * the PPP (in this case 2.10), and I want that to show up in the "Total" input field right away.
I have this ponent in React JS. I have 3 input fields. One for pounds, one for PPP (Price Per Pound) and the other one is the total. A user inputs the pounds they want in the input field, I already pass the PPP as a value by default, and then I want to calculate the total by multiplying price * ppp as the user is typing.
This is the whole ponent:
class NewTransaction extends React.Component {
constructor(props) {
super(props);
this.state = {
pounds: '',
ppp: 2.10,
total: 0
};
this.handleFormSubmit = this.handleFormSubmit.bind(this);
this.handlePoundsChange = this.handlePoundsChange.bind(this);
this.handlePPPChange = this.handlePPPChange.bind(this);
this.handleTotalChange = this.handleTotalChange.bind(this);
}
ponentWillMount(){}
handlePoundsChange(event) {
this.setState({value: event.target.value});
}
handlePPPChange(event) {
this.setState({value: event.target.value});
}
handleTotalChange(event) {
this.setState({value: event.target.value});
}
handleFormSubmit(event) {
event.preventDefault();
let pounds = $("#pounds").val();
let ppp = $("#ppp").val();
let total = ppp * pounds;
console.log(total);
axios.post('/api/add/transaction', {
pounds: pounds,
ppp: ppp,
total: total
})
.then(function (response) {
console.log(response);
$("#pounds").val('');
$("#ppp").val('');
$("#total").val('');
})
.catch(function (error) {
console.log(error.response.data);
});
}
render() {
return (
<div className="container">
<form className="container" onSubmit={this.handleFormSubmit}>
<table className="table table-bordered">
<tbody>
<tr>
<td>Pounds</td>
<td>
<input type="text" name="pounds" id="pounds" className="form-control" placeholder="Enter Pounds..." onChange={this.handlePoundsChange} required />
</td>
</tr>
<tr>
<td>Price</td>
<td>
<input type="text" name="ppp" id="ppp" className="form-control" value="2.10" onChange={this.handlePPPChange} required />
</td>
</tr>
<tr>
<td>Total</td>
<td>
<input type="text" name="total" id="total" className="form-control" onChange={this.handleTotalChange} />
</td>
</tr>
</tbody>
</table>
<div className="col-xs-12">
<input
type="submit"
className="btn btn-block btn-primary"
value="Customer Checkout"/>
</div>
</form>
</div>
)
}
}
So if a user enters 2 in the pounds input field, React will go in and multiply 2 * the PPP (in this case 2.10), and I want that to show up in the "Total" input field right away.
Share Improve this question asked Apr 27, 2017 at 13:53 DavidDavid 2,0075 gold badges38 silver badges67 bronze badges 2-
why are you calling setState and changing
value
instead of the real property? for examplehandleTotalChange(event) { this.setState({total: event.target.value}); }
– Sagiv b.g Commented Apr 27, 2017 at 13:58 - Alright I changed that, good catch – David Commented Apr 27, 2017 at 14:02
3 Answers
Reset to default 2This is your fixed code. Should work like a charm.
class NewTransaction extends React.Component {
constructor(props) {
super(props);
this.state = {
pounds: 0,
ppp: 2.10,
total: 0
};
this.handleFormSubmit = this.handleFormSubmit.bind(this);
this.handlePoundsChange = this.handlePoundsChange.bind(this);
this.handlePPPChange = this.handlePPPChange.bind(this);
//this.handleTotalChange = this.handleTotalChange.bind(this);
}
ponentWillMount(){}
handlePoundsChange(event) {
this.setState(...this.state, {pounds: event.target.value});
}
handlePPPChange(event) {
this.setState(...this.state, {ppp: event.target.value});
}
handleTotalChange(event) {
//this.setState({value: event.target.value});
}
handleFormSubmit(event) {
event.preventDefault();
let pounds = this.state.pounds;
let ppp = this.state.ppp;
let total = ppp * pounds;
console.log(total);
const self = this;
axios.post('/api/add/transaction', {
pounds: pounds,
ppp: ppp,
total: total
})
.then(function (response) {
console.log(response);
self.setState({pounds: '', ppp: '', total: ''});
// $("#pounds").val('');
// $("#ppp").val('');
// $("#total").val('');
})
.catch(function (error) {
console.log(error.response.data);
});
}
render() {
const total = this.state.pounds * this.state.ppp;
return (
<div className="container">
<form className="container" onSubmit={this.handleFormSubmit}>
<table className="table table-bordered">
<tbody>
<tr>
<td>Pounds</td>
<td>
<input type="text" name="pounds" id="pounds" className="form-control" placeholder="Enter Pounds..." value={this.state.pounds} onChange={this.handlePoundsChange} required />
</td>
</tr>
<tr>
<td>Price</td>
<td>
<input type="text" name="ppp" id="ppp" className="form-control" value={this.state.ppp} onChange={this.handlePPPChange} required />
</td>
</tr>
<tr>
<td>Total</td>
<td>
<input type="text" name="total" id="total" className="form-control" value={total} />
</td>
</tr>
</tbody>
</table>
<div className="col-xs-12">
<input
type="submit"
className="btn btn-block btn-primary"
value="Customer Checkout"/>
</div>
</form>
</div>
)
}
}
Couple of strange things in your code.
1. Why are you calling setState
and changing the value
property instead of the relevant one?
for example shouldnt this:
handlePoundsChange(event) {
this.setState({value: event.target.value});
}
bee this:
handlePoundsChange(event) {
this.setState({pounds: event.target.value});
}
2. You are not binding the values from the state in the inputs.
this:
<input type="text" name="pounds" id="pounds" className="form-control" placeholder="Enter Pounds..." onChange={this.handlePoundsChange} required />
should be like this more or less:
<input value={this.state.pounds} type="text" name="pounds" id="pounds" className="form-control" placeholder="Enter Pounds..." onChange={this.handlePoundsChange} required />
3. Why is your total
element is an <input />
? you want the client to be abale to change that no matter what the other inputs value is?
EDIT
I forgot to mention, you don't need jQuery
here to reset the inputs. when you done with your ajax call you can just reset the state properties and the binding of the inputs will do that job for you.
You need to link the total input box value to the state.
<input value={this.state.total} type="text" name="total" id="total" className="form-control" onChange={this.handleTotalChange} />
Then if you want the value of the total to change when the user inputs Pounds and PPP you need to update your total state in the handlePoundsChange and handlePPPChange functions.
handlePoundsChange(event) {
this.setState({
total: event.target.value * this.state.ppp
});
}
handlePPPChange(event) {
this.setState({
total: event.target.value * this.state.pounds
});
}