Handling multiple number type inputs - reactjs

I have several number type inputs in one page view. If I enter a number in one input, the value of all inputs changes. I only have one value in state, to which I assign the variable from input. How to control only the input that the target is on?
Parent:
class App extends Component {
state = {
starships: [],
value: 0,
quantity: 0,
};
handleInputChange = (e) => {
this.setState({
value: e.target.value,
});
};
render() {
const { starships, value, quantity } = this.state;
return (
<>
<Header quantity={quantity} />
<StarshipsList
starships={starships}
value={value}
quantity={quantity}
onChange={this.handleInputChange}
onClick={this.handleAddBtn}
/>
</>
);
}
}
Child's child:
function Starship(props) {
return (
<tbody>
{props.starships.map(({ url, name, manufacturer, cost_in_credits }) => (
<tr key={url}>
<td>{name}</td>
<td>{manufacturer}</td>
<td>{cost_in_credits}</td>
<td>
<input
onChange={props.onChange}
value={props.value}
className="input"
type="number"
min="0"
/>
<button onClick={props.onClick} className="add-btn">
Add
</button>
</td>
</tr>
))}
</tbody>
);
}

You need to create a component (TrComponent) to render the tr tag and child.
In TrComponent, you create a state call value and handle change to update this state
To handle onClick in TrComponent, you can update like: onClick={() => props.onClick(values_you_want)}

First of all change value state to object
state = {
starships: [],
value: {},
quantity: 0,
};
Now change handleInputChange function to accept value and key
handleInputChange = (key, value) => {
this.setState({
value[key]: value,
});
};
Now in Starship component we will call onChange method with url as key and e.target.value as value:
<input
onChange={(e) => props.onChange(url, e.target.value)}
value={props.value[url]}
className="input"
type="number"
min="0"
/>

Related

remove the value enterd in input fild after submistion :react js [duplicate]

I have a form containing various input fields and two buttons; one for submitting and one for cancelling.
<form id="create-course-form">
<input type="text" name="course_Name" ref="fieldName">
<input type="text" name="course_org" ref="fieldOrg">
<input type="text" name="course_Number" ref="fieldNum">
<input type="submit" name="saveCourse" value="Create">
<input type="button" name="cancelCourse" value="cancel" onClick={this.cancelCourse}>
</form>
What I want is to empty all inputs when the cancel button is clicked. So far I've managed to do this by using each input's ref prop.
cancelCourse(){
this.refs.fieldName.value="";
this.refs.fieldorg.value="";
this.refs.fieldNum.value="";
}
However, I want to empty the input fields without having to empty each one seperately. I want something similar to this (jQuery): $('#create-course-form input[type=text]').val('');
The answer here depends on whether or not your inputs are controlled or uncontrolled. If you are unsure or need more info on this, check out what the official docs say about controlled components and uncontrolled components. Thanks #Dan-Esparza for providing the links.
Also, please note that using string literals in ref is deprecated. Use the standard callback method instead.
Clearing a form with uncontrolled fields
You can clear the entire form rather than each form field individually.
cancelCourse = () => {
document.getElementById("create-course-form").reset();
}
render() {
return (
<form id="create-course-form">
<input />
<input />
...
<input />
</form>
);
}
If your form didn't have an id attribute you could use a ref as well:
cancelCourse = () => {
this.myFormRef.reset();
}
render() {
return (
<form ref={(el) => this.myFormRef = el;}>
<input />
<input />
...
<input />
</form>
);
}
Clearing a form with controlled fields
If you are using controlled form fields, you may have to explicitly reset each component inside your form, depending on how your values are stored in the state.
If they are declared individually, you need to reset each one explicitly:
cancelCourse = () => {
this.setState({
inputVal_1: "",
inputVal_2: "",
...
inputVal_n: "",
});
}
render() {
return (
<input value={this.state.inputVal_1} onChange={this.handleInput1Change}>
<input value={this.state.inputVal_2} onChange={this.handleInput2Change}>
...
<input value={this.state.inputVal_n} onChange={this.handleInputnChange}>
);
}
Demo below:
class MyApp extends React.Component {
constructor() {
super();
this.state = {
inputVal_1: "",
inputVal_2: "",
inputVal_3: "",
inputVal_4: "",
inputVal_5: "",
inputVal_6: "",
inputVal_7: "",
inputVal_8: "",
inputVal_9: "",
inputVal_10: ""
};
}
handleInput1Change = (e) => {
this.setState({inputVal_1: e.target.value});
}
handleInput2Change = (e) => {
this.setState({inputVal_2: e.target.value});
}
handleInput3Change = (e) => {
this.setState({inputVal_3: e.target.value});
}
handleInput4Change = (e) => {
this.setState({inputVal_4: e.target.value});
}
handleInput5Change = (e) => {
this.setState({inputVal_5: e.target.value});
}
handleInput6Change = (e) => {
this.setState({inputVal_6: e.target.value});
}
handleInput7Change = (e) => {
this.setState({inputVal_7: e.target.value});
}
handleInput8Change = (e) => {
this.setState({inputVal_8: e.target.value});
}
handleInput9Change = (e) => {
this.setState({inputVal_9: e.target.value});
}
handleInput10Change = (e) => {
this.setState({inputVal_10: e.target.value});
}
cancelCourse = () => {
this.setState({
inputVal_1: "",
inputVal_2: "",
inputVal_3: "",
inputVal_4: "",
inputVal_5: "",
inputVal_6: "",
inputVal_7: "",
inputVal_8: "",
inputVal_9: "",
inputVal_10: ""
});
}
render() {
return (
<form>
<input value={this.state.inputVal_1} onChange={this.handleInput1Change} />
<input value={this.state.inputVal_2} onChange={this.handleInput2Change} />
<input value={this.state.inputVal_3} onChange={this.handleInput3Change} />
<input value={this.state.inputVal_4} onChange={this.handleInput4Change} />
<input value={this.state.inputVal_5} onChange={this.handleInput5Change} />
<input value={this.state.inputVal_6} onChange={this.handleInput6Change} />
<input value={this.state.inputVal_7} onChange={this.handleInput7Change} />
<input value={this.state.inputVal_8} onChange={this.handleInput8Change} />
<input value={this.state.inputVal_9} onChange={this.handleInput9Change} />
<input value={this.state.inputVal_10} onChange={this.handleInput10Change} />
<input type="submit" name="saveCourse" value="Create" />
<input type="button" name="cancelCourse" value="cancel" onClick={this.cancelCourse} />
</form>
);
}
}
ReactDOM.render(<MyApp />, 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"></div>
There is a cleaner way to do this though. Rather than having n state properties and n event handlers, one for each input, with some clever coding we can reduce the code dramatically.
In the constructor we just declare an empty object, which will be used to hold input values. We use only one input handler and pass it the index of the input element we want to change the value of. This means that the value of an individual input is generated the moment we start typing into it.
To reset the form, we only need to set our input object back to being empty again.
The input value is this.state.inputVal[i]. If i doesn't exist (we haven't typed anything yet into that input) we want the value to be an empty string (instead of null).
cancelCourse = () => {
this.setState({inputVal: {}});
}
render() {
return (
<form>
{[...Array(n)].map(
(item, i) => <input value={this.state.inputVal[i] || ""} onChange={this.handleInputChange.bind(this, i)} />
)}
</form>
);
}
Demo below:
class MyApp extends React.Component {
constructor() {
super();
this.state = {
inputVal: {}
};
}
handleInputChange = (idx, {target}) => {
this.setState(({inputVal}) => {
inputVal[idx] = target.value;
return inputVal;
});
}
cancelCourse = () => {
this.setState({inputVal: {}});
}
render() {
return(
<form>
{[...Array(10)].map( //create an array with a length of 10
(item, i) => <input value={this.state.inputVal[i] || ""} onChange={this.handleInputChange.bind(this, i)} /> //bind the index to the input handler
)}
<input type="submit" name="saveCourse" value="Create" />
<input type="button" name="cancelCourse" value="cancel" onClick={this.cancelCourse} />
</form>
);
}
}
ReactDOM.render(<MyApp />, 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"></div>
Very easy:
handleSubmit(e){
e.preventDefault();
e.target.reset();
}
// If using class component
<form onSubmit={this.handleSubmit.bind(this)}>
...
</form>
// If using function component
<form onSubmit={handleSubmit}>
...
</form>
Using event.target.reset() only works for uncontrolled components, which is not recommended. For controlled components you would do something like this:
import React, { Component } from 'react'
class MyForm extends Component {
initialState = { name: '' }
state = this.initialState
handleFormReset = () => {
this.setState(() => this.initialState)
}
render() {
return (
<form onReset={this.handleFormReset}>
<div>
<label htmlFor="name">Name</label>
<input
type="text"
placeholder="Enter name"
name="name"
value={name}
onChange={this.handleInputOnChange}
/>
</div>
<div>
<input
type="submit"
value="Submit"
/>
<input
type="reset"
value="Reset"
/>
</div>
</form>
)
}
}
ContactAdd.propTypes = {}
export default MyForm
You can also do it by targeting the current input, with anything.target.reset() . This is the most easiest way!
handleSubmit(e){
e.preventDefault();
e.target.reset();
}
<form onSubmit={this.handleSubmit}>
...
</form>
Here's an update to Chris's answer above, using modern React hooks.
Same high level idea; your form can be either a Controlled or Uncontrolled component.
Uncontrolled components:
Uncontrolled components leave state management up to the browser. That means you have to ask the browser to reset the form inputs. To do that, capture the form element as a ref, and then call the submit() method on that element.
export default function Form() {
const ref = React.useRef();
function reset(ev) {
ev.preventDefault();
ref.current.reset();
}
return (
<form ref={ref}>
<label htmlFor="email">Email Address</label>
<input id="email" type="email" name="email" />
<label htmlFor="message">Message</label>
<textarea id="message" name="message" />
<button type="submit">Submit</button>
<button onClick={reset}>Reset</button>
</form>
);
}
Controlled components:
With a controlled component, you manage the state in React. That means you have to create the initial state, and update it every time an input changes. In this world, resetting the form is just a matter of setting the form state back to its initial state.
export default function Form() {
const [state, setState] = React.useState({ email: "", message: "" });
function reset(ev) {
ev.preventDefault();
setState({ email: "", message: "" });
}
return (
<form className="Form">
<label htmlFor="email">Email Address</label>
<input
id="email"
type="email"
name="email"
value={state.email}
onChange={(ev) => {
setState({ ...state, email: ev.target.value });
}}
/>
<label htmlFor="message">Message</label>
<textarea
id="message"
name="message"
value={state.message}
onChange={(ev) => {
setState({ ...state, message: ev.target.value });
}}
/>
<button type="submit">Submit</button>
<button onClick={reset}>Reset</button>
</form>
);
}
Full example at https://codesandbox.io/s/reactformreset-10cjn3
Following code should reset the form in one click.
import React, { Component } from 'react';
class App extends Component {
constructor(props){
super(props);
this.handleSubmit=this.handleSubmit.bind(this);
}
handleSubmit(e){
this.refs.form.reset();
}
render(){
return(
<div>
<form onSubmit={this.handleSubmit} ref="form">
<input type="text" placeholder="First Name!" ref='firstName'/><br/<br/>
<input type="text" placeholder="Last Name!" ref='lastName'/><br/><br/>
<button type="submit" >submit</button>
</form>
</div>
}
}
To clear your form, admitted that your form's elements values are saved in your state, you can map through your state like that :
// clear all your form
Object.keys(this.state).map((key, index) => {
this.setState({[key] : ""});
});
If your form is among other fields, you can simply insert them in a particular field of the state like that:
state={
form: {
name:"",
email:""}
}
// handle set in nested objects
handleChange = (e) =>{
e.preventDefault();
const newState = Object.assign({}, this.state);
newState.form[e.target.name] = e.target.value;
this.setState(newState);
}
// submit and clear state in nested object
onSubmit = (e) =>{
e.preventDefault();
var form = Object.assign({}, this.state.form);
Object.keys(form).map((key, index) => {
form[key] = "" ;
});
this.setState({form})
}
This one works best to reset the form.
import React, { Component } from 'react'
class MyComponent extends Component {
constructor(props){
super(props)
this.state = {
inputVal: props.inputValue
}
// preserve the initial state in a new object
this.baseState = this.state ///>>>>>>>>> note this one.
}
resetForm = () => {
this.setState(this.baseState) ///>>>>>>>>> note this one.
}
submitForm = () => {
// submit the form logic
}
updateInput = val => this.setState({ inputVal: val })
render() {
return (
<form>
<input
onChange={this.updateInput}
type="text
value={this.state.inputVal} />
<button
onClick={this.resetForm}
type="button">Cancel</button>
<button
onClick={this.submitForm}
type="submit">Submit</button>
</form>
)
}
}
When the form is submitted, the 'event' will be passed as an argument to the handleSubmit method, and if that you can access the <form> element by typing event.target. then you just need to reset the form using .reset() form method.
https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/reset
handleSubmit = (event)=>{
event.preventDefault()
....
event.target.reset()
}
render() {
return (
<>
<form onSubmit={this.handleSubmit}>
<label htmlFor='movieTitle'>Title</label>
<input name='movieTitle' id='movieTitle' type='text' />
<input type='submit' value='Find Movie Info' />
</form>
</>
)
}
I don't know if this is still relevant. But when I had similar issue this is how I resolved it.
Where you need to clear an uncontrolled form you simply do this after submission.
this.<ref-name-goes-here>.setState({value: ''});
Hope this helps.
import React, { Component } from 'react'
export default class Form extends Component {
constructor(props) {
super(props)
this.formRef = React.createRef()
this.state = {
email: '',
loading: false,
eror: null
}
}
reset = () => {
this.formRef.current.reset()
}
render() {
return (
<div>
<form>
<input type="email" name="" id=""/>
<button type="submit">Submit</button>
<button onClick={()=>this.reset()}>Reset</button>
</form>
</div>
)
}
}
/*
See newState and use of it in eventSubmit() for resetting all the state.
I have tested it is working for me. Please let me know for mistakes
*/
import React from 'react';
const newState = {
fullname: '',
email: ''
}
class Form extends React.Component {
constructor(props) {
super(props);
this.state = {
fullname: ' ',
email: ' '
}
this.eventChange = this
.eventChange
.bind(this);
this.eventSubmit = this
.eventSubmit
.bind(this);
}
eventChange(event) {
const target = event.target;
const value = target.type === 'checkbox'
? target.type
: target.value;
const name = target.name;
this.setState({[name]: value})
}
eventSubmit(event) {
alert(JSON.stringify(this.state))
event.preventDefault();
this.setState({...newState});
}
render() {
return (
<div className="container">
<form className="row mt-5" onSubmit={this.eventSubmit}>
<label className="col-md-12">
Full Name
<input
type="text"
name="fullname"
id="fullname"
value={this.state.fullname}
onChange={this.eventChange}/>
</label>
<label className="col-md-12">
email
<input
type="text"
name="email"
id="email"
value={this.state.value}
onChange={this.eventChange}/>
</label>
<input type="submit" value="Submit"/>
</form>
</div>
)
}
}
export default Form;
the easiest way is doing it regularly with just HTML and using the button type "reset" there is no need to mess with anything in react at all, no state, no nothing.
import React, {useState} from 'react'
function HowReactWorks() {
return (
<div>
<form>
<div>
<label for="name">Name</label>
<input type="text" id="name" placeholder="name" />
</div>
<div>
<label for="password">Password</label>
<input type="password" id="password" placeholder="password" />
</div>
<button type="reset">Reset</button>
<button>Submit</button>
</form>
</div>
)
}
export default HowReactWorks
edited for the people that don't know how to include HTML in react
You can use this method as well
const resetData = (e) => {
e.preventDefault();
settitle("");
setdate("");
};
<input type="text" onChange={(e) => settitle(e.target.value)} value={title} />
<input type="date" onChange={(e) => setdate(e.target.value)} value={date} />
<button onClick={resetData}>Reset Data</button>
This is the solution that worked for me, in the case of parent component triggering reset of child controlled input components:
const ParentComponent = () => {
const [reset, setReset] = useState()
const submitHandler = (e) => {
e.preventDefault()
//do your stuff
setReset(Date.now()) // pass some value to trigger update
}
return (
<form onSubmit={submitHandler}>
<ChildInputComponent reset={reset} />
<ChildInputComponent reset={reset} />
</form>
)
}
const ChildInputComponent = ({reset}) => {
const [value, setValue] = useState()
useEffect(() => {
setValue('')
}, [reset])
return <input value={value} onChange={(e) => setValue(e.target.value)} />
}
Assuming you declared
const [inputs, setInputs] = useState([]);
As multiple parameters. You can actually reset the items using this syntax:
setInputs([]);
Just in case, this how you define handleChange.
You can use this form or any ways you want.
const handleChange = (event) => {
const name = event.target.name;
const email = event.target.email;
const message = event.target.message;
const value = event.target.value;
setInputs(values => ({...values, [name]: value, [email]: value, [message]: value}))
}
You can use this form as an example.
<form onSubmit={handleSubmit}>
<div className="fields">
<div className="field half">
<label for="name">Name</label>
<input value={inputs.name || ''} type="text" name="name" id="nameId" onChange={handleChange} maxLength="30" />
</div>
<div className="field half">
<label for="email">Email</label>
<input value={inputs.email || ''} type="text" name="email" id="emailId" onChange={handleChange} maxLength="40"/>
</div>
<div className="field">
<label for="message">Message</label>
<textarea value={inputs.message || ''} name="message" id="messageId" rows="6" onChange={handleChange} maxLength="400" />
</div>
</div>
<ul className="actions">
<li><input type="submit" value="Send Message" className="primary" /></li>
<li><input onClick={resetDetails} type="reset" value="Clear" /></li>
</ul>
</form>
This is just one of many ways to declare forms. Good luck!
const onReset = () => {
form.resetFields();
};
state={
name:"",
email:""
}
handalSubmit = () => {
after api call
let resetFrom = {}
fetch('url')
.then(function(response) {
if(response.success){
resetFrom{
name:"",
email:""
}
}
})
this.setState({...resetFrom})
}
Why not use HTML-controlled items such as <input type="reset">

How to get value from input?

I make simple task for getting job. Working with react and redux. When i get value from input and send them to reducer they are lost in the way. Wait, not so easy. 1st item getting by reducer gets prop name, age, type, index and return new state. Nice. But other items lost prop name and age in the way. What? How did them it? Reducer return empty obj for render. Dont look on obj in dispatch i will rework it.
REDUCER
case 'EDIT_ITEM':
console.log(action.name, action.age, action.id);
return state.map((item, index) =>
action.id === index
? {
name: action.name,
age: action.age
}
: item
);
App.js
function EditUsers() {
const listItems = users.map(function (value, index) {
return (
<form>
<div className="input-group">
<div className="input-group-prepend">
<span className="input-group-text">{value.name}, {value.age}</span>
</div>
<input type="text" placeholder="New name" id="newName" className="form-control"/>
<input type="text" placeholder="New age" id="newAge" className="form-control" aria-describedby="button-addon2"/>
<div className="input-group-append">
<button onClick={() => dispatch({
type: 'EDIT_ITEM',
id: index,
name: document.getElementById('newName').value,
age: document.getElementById("newAge").value
})}
className="btn btn-outline-primary"
type="button"
id="button-addon2">
Изменить
</button>
</div>
</div>
</form>
)
});
return (
<div>{listItems}</div>
)
}
You won't be able to access the input values from the button's onClick event, but if you decide to leave the inputs uncontrolled and move the logic to the associated form's onSubmit callback, then you can access the form's field values from the onSubmit event.
Define a submitHandler function to consume both the index and submit event, e:
const submitHandler = index => e => {
e.preventDefault(); // <-- prevent the default form action, important!
const { newName, newAge } = e.target; // <-- destructure the inputs from the event target
dispatch({
type: "EDIT_ITEM",
id: index,
name: newName.value, // <-- extract the input value
age: newAge.value // <-- extract the input value
});
};
Here the path to the input value is e.target.<fieldId>.value. Notice I've also defined submitHandler to curry the index, which allows for more optimal usage when mapping elements.
Next, attach the submitHandler callback to the onSubmit prop of the form.
const listItems = users.map(function(value, index) {
return (
<form key={index} onSubmit={submitHandler(index)}>
...
Here the curried function submitHandler(index) takes the index and encloses it in an instance of the callback, returning a function that takes the onSubmit event object, e => {....
Finally, update the button to have type="submit" and no onClick handler.
<button
className="btn btn-outline-primary"
type="submit"
id="button-addon2"
>
Изменить
</button>
Full code
const submitHandler = index => e => {
e.preventDefault();
const { newName, newAge } = e.target;
dispatch({
type: "EDIT_ITEM",
id: index,
name: newName.value,
age: newAge.value
});
};
function EditUsers() {
const listItems = users.map(function(value, index) {
return (
<form key={index} onSubmit={submitHandler(index)}>
<div className="input-group">
<div className="input-group-prepend">
<span className="input-group-text">
{value.name}, {value.age}
</span>
</div>
<input
type="text"
placeholder="New name"
id="newName"
className="form-control"
/>
<input
type="text"
placeholder="New age"
id="newAge"
className="form-control"
aria-describedby="button-addon2"
/>
<div className="input-group-append">
<button
className="btn btn-outline-primary"
type="submit"
id="button-addon2"
>
Изменить
</button>
</div>
</div>
</form>
);
});
return <div>{listItems}</div>;
}

How do I pass down function from parent component to child component in React

Currently I am trying to split up the app in separate components to make it more readable and testable. But now I faced an issue, which is the general function in the parent component. How do I call the general onChange function from separate components. Because there are multiple input fields that do the same, so therefore I want to make a reusable function in parent component, that can be called from the child component.
// child component
export default class Name extends React.Component {
constructor(props) {
super(props);
}
state = {
name: '',
nameErrorMessage: ''
}
checkName = (name: string) => {
const re = /[^a-zA-Z]/;
const checkValidation = re.test(name);
const nameRequirements = !checkValidation && name.length > 1;
if(!nameRequirements) {
this.setState({ nameErrorMessage: 'name contains numbers, symbols or is too short (min length of 2 letters)', nameBoolean: false });
} else {
this.setState({ nameErrorMessage: '', nameBoolean: true });
}
}
handleNameChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const getName = event.target.value;
const getNameValid = this.checkName(getName);
return getNameValid;
}
onChange = () => {
this.props.parentMethod();
}
render() {
return (
<div className="two-columns two-columns-child column-block">
<label className="label-customized">First name</label><br/>
<input
name="name"
className="input-customized"
type="text"
value={this.state.name}
onBlur={this.handleNameChange}
onChange={this.onChange}
placeholder="Enter first name"
/>
<br/>
<span className="error-message">{this.state.nameErrorMessage}</span>
</div>
)
}
}
// parent component
onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
let onChangeName:any = event.target.getAttribute('name');
this.setState({[onChangeName]: event.target.value })
}
return (
<div className="App">
<form onSubmit={this.checkForm}>
<Name/>
</form>
</div>
)
PARENT COMPONENT
pass onChange as property to the child component
...
return (
<div className="App">
<form onSubmit={this.checkForm}>
<Name onChange={this.onChange}/>
</form>
</div>
)
CHILD COMPONENT
call the passed prop when onChange is called for the input
return <div className="two-columns two-columns-child column-block">
<label className="label-customized">First name</label><br/>
<input
name="name"
className="input-customized"
type="text"
value={this.state.name}
onBlur={this.handleNameChange}
onChange={e => this.props.onChange(e)}
placeholder="Enter first name"
/>
<br/>
<span className="error-message">{this.state.nameErrorMessage}</span>
</div>

Clicking on radiobutton returns undefined values

I want to create an app where you can choose quantity fo water that you have drinked. I want to use radiobuttons in form for 3 default values -250ml, 500ml and 1000ml.
I created radiobuttons, but when I click on them, I get undefined value after e.target method.
I tried to bind my functions on checked and onChange but it didn't help.
Main component WaterApp.js:
import WaterButtons from './WaterButtons';
const quantitiesData = [
{
id: 'water_250_ml',
value: 250,
name: 'water_250_ml'
},
{
id: 'water_500_ml',
value: 500,
name: 'water_500_ml'
},
{
id: 'water_1000_ml',
value: 1000,
name: 'water_1000_ml'
}
];
export default class WaterApp extends React.Component {
state = {
waterQuantity: 'water_250_ml'
};
handleCheckedWaterQuantity = (e) => {
this.state.checkedQuantity === e.target.value;
}
handleWaterQuantityChange = (e) => {
const waterQuantity = e.target.value;
this.setState({ waterQuantity });
console.log(waterQuantity);
}
render() {
return (
<div>
<form>
<WaterButtons
quantities={quantitiesData}
handleCheckedWaterQuantity={(e) => this.handleCheckedWaterQuantity(e)}
handleWaterQuantityChange={(e) => this.handleWaterQuantityChange(e)}
/>
</form>
</div>
)
}
}
WaterButtons.js
import WaterButton from './WaterButton';
const WaterButtons = (props) => (
<div>
{
props.quantities.map((quantity) => (
<WaterButton
key={quantity.id}
id={quantity.id}
value={quantity.value}
label={quantity.name}
checked={props.handleCheckedWaterQuantity}
handleWaterQuantityChange={props.handleWaterQuantityChange}
/>
))
}
</div>
);
export default WaterButtons;
WaterButton.js
const WaterButton = (props) => (
<div>
<input
type="radio"
id={props.id}
value={props.value}
name="waterQuantity"
checked={props.checked}
onChange={(e) => {props.handleWaterQuantityChange(props.value)}}
/>
<label htmlFor={props.id}>
{props.label}
</label>
</div>
);
export default WaterButton;
I want to get the value for clicked radiobutton.
[EDIT] Also, I have a problem with checked value for every radiobutton. Function that is now is not working. I thought maybe I should change my code so that in WaterButton.js i define state for buttons. Then it would have to be class not stateless component.
You are calling handleWaterQuantityChange with incorrect argument please see the below code
Your onChange should be onChange={(e) => {props.handleWaterQuantityChange(e)}}
const WaterButton = (props) => (
<div>
<input
type="radio"
id={props.id}
value={props.value}
name="waterQuantity"
checked={props.checked}
onChange={(e) => {props.handleWaterQuantityChange(e)}}
/>
<label htmlFor={props.id}>
{props.label}
</label>
</div>
);
In props.handleWaterQuantityChange you are passing props.value instead of event
<input
type="radio"
id={props.id}
value={props.value}
name="waterQuantity"
checked={props.checked}
onChange={(e) => {props.handleWaterQuantityChange(e)}}
or
<input
type="radio"
id={props.id}
value={props.value}
name="waterQuantity"
checked={props.checked}
onChange={props.handleWaterQuantityChange}

How to access table cell data in react

I have created a cart using reactjs and now I pass an object into the cart and I can add quantity and then I will be calculated automatically subtotal of a product. But now I have to calculate Total using this subtotal value. So Can I know how to access table column 'subtotal' and calculate the total price of products purchased?
I have attached the table below.
render(){
const subtot =this.DrugsDetailsRequest.totalPrice*this.state.textInputValue1
console.log(subtot);// this will get you the total
const sum=sum+subtot;
console.log(sum);
return (
<tr>
<td data-th="Product">
<p>{this.DrugsDetailsRequest.item_name}</p>
</td>
<td> Rs: {this.DrugsDetailsRequest.totalPrice}</td>
<td>
<input name="textInputValue1" type="number" className="form-control text-center" onChange={ this.handleChange } />
</td>
<td className="text-center">
<input name="textInputValue2" type="text" className="form-control text-center" value={subtot}
onChange={ this.handleChange } />
</td>
<td className="actions">
<button className="btn btn-danger btn-sm" onClick={(e) => this.delete(this.DrugsDetailsRequest._id)}>Delete</button>
</td>
</tr>
);
}
}
enter image description here
This is one solution for you: Using Refs
For more information, you could read it here: Refs and the DOM
This is the example which looks closely to what you are in need.
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
// create a ref to store the textInput DOM element
this.textInput = React.createRef();
this.focusTextInput = this.focusTextInput.bind(this);
}
focusTextInput() {
// Explicitly focus the text input using the raw DOM API
// Note: we're accessing "current" to get the DOM node
this.textInput.current.focus();
}
render() {
// tell React that we want to associate the <input> ref
// with the `textInput` that we created in the constructor
return (
<div>
<input
type="text"
ref={this.textInput} />
<input
type="button"
value="Focus the text input"
onClick={this.focusTextInput}
/>
</div>
);
}
}
in react, you should try to make your UI rendering controled by the react's state.
in your case, if you want to access the subtotal, then you might design your component state like this:
class Cart extends React.Component {
constructor(props) {
super(props);
// initial cart state
this.state = {
total: 0,
inCartItems: {
ddd: {
price: 12,
quantity: 0,
subtotal: 0,
},
www: {
price: 45,
quantity: 0,
subtotal: 0,
},
e3400: {
price: 45,
quantity: 0,
subtotal: 0,
},
},
};
}
handleChange = (itemName, quantity) => {
// set new inCartItems state
// then use the updated state to calculate total by just sum up the subtotal in each items
}
render() {
return (
// your table content
<div>
{/*handle item number change like this*/}
<input onChange={(e) => this.handleChange('ddd', e.target.value)} />
<input onChange={(e) => this.handleChange('www', e.target.value)} />
<input onChange={(e) => this.handleChange('e3400', e.target.value)} />
<div className={'total'}>
{this.state.total}
</div>
</div>
// ....
);
}
}

Resources