React Js : Handle Nested Element In State - javascript

I have below Code :-
import React,{useState} from 'react'
const iState ={
Name : '',
Email :'',
Salary :0,
Error:{
EName:'*',
EEmail:'*',
ESalary:'*'
}
}
function ReactForm() {
const [state, setstate] = useState(iState);
function validationHandler(e)
{
console.log(e.target.name);
switch (e.target.name) {
case 'txtName':
if(e.target.value=='')
{
setstate({...state.Error, EName:'Value Cannot be blank'})
}
setstate({...state, Name:e.target.value})
break;
case 'txtEmail':
setstate({...state, Email:e.target.value})
break;
case 'txtSalary':
setstate({...state, Salary:e.target.value})
break;
default:
break;
}
console.log(state);
}
return (
<div>
Name : <input name="txtName" type="text" onChange={(e)=>validationHandler(e)}></input>
<label> {this.state.Error.EName==undefined ? '*':this.state.Error.EName} </label>
<br></br>
Email : <input name="txtEmail" type="text" onChange={(e)=>validationHandler(e)}></input>
<br></br>
Salary : <input name="txtSalary" type="text" onChange={(e)=>validationHandler(e)}></input>
<br></br>
<button onClick={validationHandler}>Validate Us</button>
</div>
)
}
export default ReactForm
I have nested Error element for validation in state -
Error:{
EName:'*',
EEmail:'*',
ESalary:'*'
}
I am trying to bind it to react element as -
Name : <input name="txtName" type="text" onChange={(e)=>validationHandler(e)}></input>
<label> {this.state.Error.EName==undefined ? '*':this.state.Error.EName} </label>
But Getting An Error -

You don't need to use this to access state in functional components. Just do, state.Error.EName. this is only necessary in class components.

You are using functional component and your state is not binded to the class component so you don't need to access it through this.
return (
<div>
Name : <input name="txtName" type="text" onChange={(e)=>validationHandler(e)}></input>
<label> {state.Error.EName==undefined ? '*': state.Error.EName} </label>
<br></br>
Email : <input name="txtEmail" type="text" onChange={(e)=>validationHandler(e)}></input>
<br></br>
Salary : <input name="txtSalary" type="text" onChange={(e)=>validationHandler(e)}></input>
<br></br>
<button onClick={validationHandler}>Validate Us</button>
</div>
)

Related

How to store ratio values in React?

I want to display user inputs and render them as new inputs are in. But currently, I can't seem to find a way to store the ratio values of multiple selections. I have tried "bind.(this)" and etc. None worked :(
Here's my code
import React, { Component } from "react";
class Input extends Component {
state = {
nameItems: [],
ageItems: [],
statusItems: [],
nameInput: '',
ageInput: '',
statusInput: ''
}
nameChangeHandler = ({target:{value}}) => this.setState({
nameInput: value
})
ageChangeHandler = ({target:{value}}) => this.setState({
ageInput: value
})
submitHandler = e =>{
e.preventDefault()
this.setState({
nameItems: [...this.state.nameItems, this.state.nameInput],
ageItems: [...this.state.ageItems, this.state.ageInput],
statusItems: [...this.state.statusItems, this.state.statusInput],
nameInput: '',
ageInput: '',
statusInput: ''
})
}
render() {
return (
<div>
<h1>User signup form</h1>
<form onSubmit={this.submitHandler}>
<label for="name">Name:</label><br />
<input type="text" id="name" name="name" value={this.state.nameInput} onChange={this.nameChangeHandler} /><br />
<label for="age">Age:</label><br />
<input type="number" id="age" name="age" value={this.state.ageInput} onChange={this.ageChangeHandler}/><br />
<div class="schoolYear">
<p>Your status:</p>
<input type="radio" id="freshman" name="status" value="freshman" />
<label for="freshman">Freshman</label><br />
<input type="radio" id="css" name="status" value="sophomore" />
<label for="sophomore">Sophomore</label><br />
<input type="radio" id="junior" name="status" value="junior" />
<label for="junior">Junior</label><br />
<input type="radio" id="senior" name="status" value="senior" />
<label for="senior">Senior</label><br />
</div>
<input class="submit" type="submit" value="Submit" />
<ul>
{
this.state.nameItems.map((key) => <li>{key}</li>)
}
{
this.state.ageItems.map((key) => <li>{key}</li>)
}
{
this.state.statusItems.map((key) => <li>{key}</li>)
}
</ul>
</form>
</div>
)
}
}
export default Input;
I have tried using the onChange on each individual option and the whole div but still can seem to obtain the radio value. Also when I tried setting "checked" the whole program seems to end up in a loop.
Just Copied Your code .
First of All , if you want to multiple select radio , don't name it as the same.
<div class="schoolYear">
<p>Your status:</p>
<input type="radio" id="freshman" name="freshman" value="freshman" onChange={(event)=>{setStatus((prev)=>[...prev,event.currentTarget.value])}}/>
<label for="freshman">Freshman</label><br />
<input type="radio" id="css" name="css" value="sophomore" onChange={(event)=>{setStatus((prev)=>[...prev,event.currentTarget.value])}}/>
<label for="sophomore">Sophomore</label><br />
<input type="radio" id="junior" name="junior" value="junior" onChange={(event)=>{setStatus((prev)=>[...prev,event.currentTarget.value])}}/>
<label for="junior">Junior</label><br />
<input type="radio" id="senior" name="senior" value="senior" onChange={(event)=>{setStatus((prev)=>[...prev,event.currentTarget.value])}}/>
<label for="senior">Senior</label><br />
</div>

React Comment Section Character Counter

Hey fellow developers,
so, I'm having this issue with React, and although I think I'm getting to show the 2000 as a number and a value overall, when I write inside the comment section, the number changes to NaN. I tried using the parseInt() in order to turn the span into a number, but nothing happens... Any suggestions?
Here's the code :)
import React from "react";
import Header from "../Header";
import "./contact-form.css";
function characterCounter() {
let text = document.getElementById("message").value;
let textLength = text.length;
let counter = document.getElementById("characterCounter");
let counterNumber = parseInt(counter);
counter.textContent = counterNumber - textLength;
}
class ContactPage extends React.Component {
render() {
return (
<div>
<Header />
<h1>Contact.</h1>
<form action="" className="contact-form" id="contactForm">
<label>Your Name</label>
<input type="text" placeholder="First Name..." />
<label>Your Last Name</label>
<input type="text" placeholder="Last Name..." />
<label>Your Email</label>
<input type="text" placeholder="Email..." />
<label>Your comment</label>
<textarea
name=""
id="message"
cols="10"
rows="10"
placeholder="Hey..."
onKeyDown={characterCounter}
></textarea>
<span>
Max words <span id="characterCounter">2000</span>
</span>
<button id="buttonSubmitContact" type="submit">
Submit
</button>
</form>
</div>
);
}
}
export default ContactPage;
So... you are using React, don't you? Well I will rewrite the component to solve the issue in the React's way
const MAX_CHARS = 2000
function ContactPage() {
const [charsLeft, setCharsLeft] = useState(0);
const updateCharsCount = ({target:{value}}) => {
setCharsLeft(MAX_CHARS - value)
}
return (
<div>
<Header/>
<h1>Contact</h1>
<form action="" className="contact-form" id="contactForm">
<label>Your Name</label>
<input type="text" placeholder="First Name..."/>
<label>Your Last Name</label>
<input type="text" placeholder="Last Name..."/>
<label>Your Email</label>
<input type="text" placeholder="Email..."/>
<label>Your comment</label>
<textarea
name=""
id="message"
cols="10"
rows="10"
placeholder="Hey..."
onChange={updateCharsCount}
></textarea>
<span>Max words {charsLeft}/{MAX_CHARS}</span>
<button id="buttonSubmitContact" type="submit">
Submit
</button>
</form>
</div>
);
}
export default ContactPage;
By the way, I've used functional component instead of class component, it's the current approach

React Typescript - set two values into state

I have a form with 3 number fields. The user can enter a quantity and unit price. Which will then show the total price in the last field as a disabled field.
My current code sets the value correctly in the Total Price input field, however it fails to set the state.
So for example if the user inputs Quantity equal to 4 and UnitPrice to 25. this.state.TotalPrice should be 100
handleChangeQuantity(event) {
const { value } = event.target;
this.setState({ Quantity: value });
}
handleChangeUnitPrice(event) {
const { value } = event.target;
this.setState({ UnitPrice: value });
}
handleChangeTotalPrice(event) {
const { TotalPrice } = event.target.value;
this.setState({
TotalPrice: this.state.Quantity * this.state.UnitPrice
});
}
<div>
<label>
Quantity
</label>
<input
value={this.state.Quantity}
onChange={this.handleChangeQuantity}
type="number"
className="phone validate"
name="Quantity #1"
maxLength={9}
pattern='[0-9]{0,5}'
/>
</div>
<div>
<label>
Unit Price
</label>
<input
value={this.state.UnitPrice}
onChange={this.handleChangeUnitPrice}
type="number"
className="phone validate"
name="Unit Price #1"
maxLength={15}
pattern='[0-9]{0,5}'
/>
</div>
<div>
<label>
Total Price
</label>
<input
value={this.state.Quantity * this.state.UnitPrice}
onChange={this.handleChangeExtendedPrice}
type="number"
className="phone validate"
name="Estimated Extended Price #1"
disabled
/>
</div>
In the last input field totalPrice , you could set the value as,
value={this.state.TotalPrice}
So you can set the state value in,
handleChangeTotalPrice = () => {
this.setState({
TotalPrice: this.state.Quantity * this.state.UnitPrice,
})
console.log(this.state.TotalPrice)
}
So you can call the handleChangeTotalPrice function whenever there is a change in quantity and price..
The state value of TotalPrice would gets updated accordingly.
You could change your code like the following,
import React from 'react'
export class App extends React.Component {
state = {
Quantity: 0,
UnitPrice: 0,
TotalPrice: 0,
}
handleChangeQuantity = async (event: any) => {
const { value } = event.target
await this.setState({ Quantity: value })
this.handleChangeTotalPrice()
}
handleChangeUnitPrice = async (event: any) => {
const { value } = event.target
await this.setState({ UnitPrice: value })
this.handleChangeTotalPrice()
}
handleChangeTotalPrice = () => {
this.setState({
TotalPrice: this.state.Quantity * this.state.UnitPrice,
})
console.log(this.state.TotalPrice)
}
render() {
return (
<div>
<div>
<label>Quantity</label>
<input
value={this.state.Quantity}
onChange={this.handleChangeQuantity}
type="number"
className="phone validate"
name="Quantity #1"
maxLength={9}
pattern="[0-9]{0,5}"
/>
</div>
<div>
<label>Unit Price</label>
<input
value={this.state.UnitPrice}
onChange={this.handleChangeUnitPrice}
type="number"
className="phone validate"
name="Unit Price #1"
maxLength={15}
pattern="[0-9]{0,5}"
/>
</div>
<div>
<label>Total Price</label>
<input
value={this.state.TotalPrice}
type="number"
className="phone validate"
name="Estimated Extended Price #1"
disabled
/>
</div>
</div>
)
}
}
Working Sandbox
For starters I would put the jsx into a render method:
render() {
const { Quantity, UnitPrice } = this.state;
return (
<>
<div>
<label>
Quantity
</label>
<input
value={Quantity}
onChange={this.handleChangeQuantity}
type="number"
className="phone validate"
name="Quantity #1"
maxLength={9}
pattern='[0-9]{0,5}'
/>
</div>
<div>
<label>
Unit Price
</label>
<input
value={UnitPrice}
onChange={this.handleChangeUnitPrice}
type="number"
className="phone validate"
name="Unit Price #1"
maxLength={15}
pattern='[0-9]{0,5}'
/>
</div>
<div>
<label>
Total Price
</label>
<input
value={Quantity * UnitPrice}
onChange={this.handleChangeExtendedPrice}
type="number"
className="phone validate"
name="Estimated Extended Price #1"
disabled
/>
</div>
</>
);
}
This should help with solving your problem:
React setState not updating state
Here is a code pen link to a working version of your code. I took out the classNames and other things. Feel free to play around with it. https://codepen.io/maksimmamrikov/pen/jObVKbZ?editors=1010

How to pass form values from child component to parent in react

I am new to react and I am trying to pass the values inside a form to the parent component and then display the values in other child component.
I tried using states and props but it seems like I am missing something. It tells me that you are trying to use props on undefined value. I am not able to figure out where. I tried googling and did some search. nothing works as of now.
Here is my code:
Parent :
constructor(props) {
super(props);
this.state = {
name: "",
age:"",
gender:""
};
}
changeValue(name,age,gender) {
this.setState({
name: name,
age:age,
gender:gender
});
}
render() {
return (
<div>
<FormView changeValue={this.changeValue.bind(this)}/>
<DisplayView name={this.state.name} age= {this.state.age} gender= {this.state.gender}/>
</div>
);
}
Child 1 :
constructor(props) {
super(props);
}
handleChange(e){
this.props.changeValue(e.target.name.value,e.target.age.value,e.target.gender.value);
}
render() {
return <form>
<label>
Name:
<input type="text" name="name" />
</label>
<label>
Age:
<input type="number" name="age" />
</label>
<label>
Gender:
<select name="gender" >
<option value="Male">Male</option>
<option value="Female">Female</option>
</select>
</label>
<input type="button" value="Submit" onClick = {this.handleChange.bind(this)} />
</form>
}
Child2 :
render(){
return (
<div>
<p>{this.props.name}</p>
<p>{this.props.age}</p>
<p>{this.props.gender}</p>
</div>
)
}
I am expecting to display the form values of child1 in child2.
I am getting an undefined value error.
You component works fine if we define an onSubmit listener and handler for the form. We also need to call event.preventDefault() to stop the page from refreshing, that way the values actually get passed up to parent component when you call this.props.changeValue()
See codesandbox: https://codesandbox.io/s/gallant-ellis-76bdv
import React from "react";
class FormView extends React.Component {
constructor(props) {
super(props);
}
handleChange(e){
e.preventDefault()
this.props.changeValue(
e.target.name.value,
e.target.age.value,
e.target.gender.value
);
};
render() {
return (
<form onSubmit={this.handleChange.bind(this)}>
<label>
Name:
<input type="text" name="name" />
</label>
<label>
Age:
<input type="number" name="age" />
</label>
<label>
Gender:
<select name="gender">
<option value="Male">Male</option>
<option value="Female">Female</option>
</select>
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
export default FormView;
To get an element in React you can use refs on each input or one on the form https://reactjs.org/docs/refs-and-the-dom.html
constructor(props) {
super(props);
}
handleChange(e){
console.log(this.name.value, this.age.value, this.gender.value);
this.props.changeValue(this.name.value, this.age.value, this.gender.value);
}
setName = (name) => {
this.name = name;
}
setAge = (age) => {
this.age = age;
}
setGender = (gender) => {
this.gender = gender;
}
render() {
return <form>
<label>
Name:
<input type="text" ref={this.setName} name="name" />
</label>
<label>
Age:
<input type="number" ref={this.setAge} name="age" />
</label>
<label>
Gender:
<select ref={this.setGender} name="gender" >
<option value="Male">Male</option>
<option value="Female">Female</option>
</select>
</label>
<input type="button" value="Submit" onClick = {this.handleChange.bind(this)} />

Creating radio button in React using ref

Need to create radio buttons for Title (Mr. & Ms.) using react and the ref attribute.
Code for Class(Omitting the useless part):-
getTitle () {
// how could I get the selected title value here
var title = this.refs. ??;
},
render () {
return (
<div className='input-wrap'>
<label className='label'>
Mr.
</label>
<input className='input'
type='radio'
ref= 'title'
name='user_title'
value='Mr.'
selected />
<label className='label'>
Ms.
</label>
<input className=input'
type='radio'
ref= 'title'
name='user_title'
value='Ms.' />
</div>
)
}
Question:- How could I get the selected Title value in getTitle() ?
You can do it without refs.
class Radio extends React.Component{
constructor(){
super();
this.state = {
inputValue : ''
}
}
change(e){
const val = e.target.value;
this.setState({
inputValue : val
})
}
render(){
return <div>
<label>MR<input type="radio" name="name" onChange={this.change.bind(this)} value="MR"/></label>
<label>MS<input type="radio" name="name" onChange={this.change.bind(this)} value="MS"/></label>
<br/>
<h2>Value : {this.state.inputValue}</h2>
</div>
}
}
React.render(<Radio/>, document.getElementById('container'))
Fiddle example is here
I hope it will help you !
Thanks!

Categories

Resources