how to edit a form in react using formik - reactjs

var fname,
gender,
city = "";
this.props.data.map((row, index) => {
// console.log(index);
if (this.props.selectedVal === index) {
gender = row[0];
fname = row[1];
city = row[2];
}
return [];
});
return (
<div>
<Dialog
open={this.props.open}
onClose={this.handleClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<h1>Edit User</h1>
<DialogContent>
<DialogContentText id="alert-dialog-description" />
<form onSubmit={handleSubmit}>
<TextField
type="text"
margin="dense"
id="firstname"
label="Name"
onChange={handleChange}
value={fname}
{...props}
/>
<br />
<TextField
type="text"
margin="dense"
id="gender"
label="gender"
onChange={handleChange}
value={gender}
{...props}
/>
<br />
<TextField
type="text"
margin="dense"
id="city"
label="city"
onChange={handleChange}
value={city}
{...props}
/>
</form>
</DialogContent>
<DialogActions>
<Button onClick={this.handleClose} color="primary">
RESET
</Button>
<Button onClick={this.handleClose} color="primary" autoFocus>
SUBMIT
</Button>
</DialogActions>
</Dialog>
</div>
);
};
render() {
return (
<div align="center">
<Formik
initialValues={{
name: this.props.fname,
gender: this.props.gender,
city: this.props.city
}}
onSubmit={initialValues => console.log("values" + initialValues.name)}
render={this.form}
/>
</div>
);
}
}
Here i am getting the values from table while click on a specific row. I'm getting these values in a dialog using formik. Now i want to edit this formik form. I faced a problem. These values are not edited. How to edit these readonly values.
I added my codesandbox link codesandbox

The way you are doing things is not correct. Some of the functions which you are using never exist.
Here is the working demo of your code Codesandbox demo
Please take a look at the code and understand how it is transformed between two components and feel free to ask me if you have any queries/get stuck understanding the code.

Related

On submits doesn't trigger a function in ReactJs

const CreateMessage = () => {
const disatch = useDispatch()
const chatR = useSelector(state => state.chat);
const { chat } = chatR;
const [text, setText] = useState("")
useEffect(()=>{
setText("")
},[chat])
function handleSubmit(event) {
event.preventDefault()
console.log(3333)
}
return (
<StyledCreateMessage id="myform" onSubmit={handleSubmit}>
<div className="searchForm">
{/* <input className='input' type="text" placeholder='Write a message...' /> */}
<textarea value={text} onChange={(e)=>setText(e.target.value)} spellCheck="false" className='input' placeholder='write a message...'></textarea>
</div>
<div className="send">
<Stack direction="row" spacing={1}>
<IconButton color="primary" sx={{color:"white"}} aria-label="upload picture" component="label">
<input hidden type="file" />
<AttachFileIcon />
</IconButton>
<IconButton color="primary" sx={{color:"white"}} aria-label="upload picture" component="label">
<input hidden type="file" accept='image/*' />
<PhotoCamera />
</IconButton>
<IconButton type="submit" form="myform" color="primary" sx={{color:"white"}} aria-label="upload picture" component="label">
<SendIcon />
</IconButton>
</Stack>
</div>
</StyledCreateMessage>
)
}
why when I clock
<IconButton type="submit" form="myform" color="primary" sx={{color:"white"}} aria-label="upload picture" component="label">
<SendIcon />
</IconButton>
It doesn't trigger handleSubmit
You need to add onClick={handleSubmit} to your IconButton.
Here is an example right from react docs: https://reactjs.org/docs/forms.html
Your form won't have the context of the button based on the way you have it set up.
There are a few things you can do
The button would have to be in the form itself, which seems like what you'd want.
Do the onClick solution mentioned above
Pass some state between the form component and the button, which seems difficult for something simple.

Why can't I get values of Date and Text Area in Formik?

I am using Formik and Yup for a form control in React application. I use also Semantic UI. In the application, when I click the submit button, whereas I can read the values from FormField elements and see them on Console, I can not get the value of Date and Text Area elements and they appear blank on Console. How can I solve this out?
Here I define the intial values.
const initialValues = {
jobTitle: { id: "" },
deadline: "",
description: "",
};
Then here I try to get the values from form element
return (
<div>
<Card fluid>
<Card.Content>
<Card.Header>Create A New Job Ad</Card.Header>
<Divider inverted />
<Formik
initialValues={initialValues}
validationSchema={jobAdCreateSchema}
onSubmit={(values) => {
handleSubmit(values);
}}
>
{({ values, setFieldValue }) => (
<div>
<pre>{JSON.stringify(values, undefined, 2)}</pre>
<Form className="ui form">
<FormField>
<label>Job Title</label>
<Dropdown
selection
placeholder="Select a Job Title"
name="jobTitle"
fluid
options={jobTitleOption}
value={values.jobTitle.id}
onChange={(_, { value }) =>
setFieldValue("jobTitle.id", value)
}
/>
</FormField>
<FormField>
<label>Application Deadline</label>
<input
name="deadline"
style={{ width: "100%" }}
type="date"
placeholder="Application Deadline"
value={values.deadline}
onChange={formik.handleChange}
/>
</FormField>
<FormField>
<label>Job Description</label>
<TextArea
name="description"
placeholder="Job Description"
style={{ minHeight: 100 }}
value={values.description}
onChange={formik.handleChange}
/>
</FormField>
<FormField>
<Button color="green" type="submit">
Submit
</Button>
</FormField>
</Form>
</div>
)}
</Formik>
</Card.Content>
</Card>
</div>
);
formik isn't defined, so your assigning an onChange function that doesn't exist.
Destructure handleChange from the argument, then assign it to the inputs like so:
{({ values, setFieldValue, handleChange }) => (
//...
<input
name="deadline"
style={{ width: "100%" }}
type="date"
placeholder="Application Deadline"
value={values.deadline}
onChange={handleChange}
/>
)}
Live demo

Change of input value with state in React JS

I am having 3 text boxes in which users enter values alongwith that I have 3 sliders for which the value is set based on calculation of percentage from the entered values. My problem is I also want to change the text box values based on calculation formulas. So the text box I want them to reflect values with calculation as the slider values change plus user can also type in values.For eg for first textbox I want to calculate value inside with (total-b-c). So with changes in slider values of percentages the values in textboxes should also change. I am unable to do that now-
Here is some supporting code for the same-
const [userValues, setUserValues] = useState({
a: '0',
b: '0',
c: '0',
});
const handleInputChange = (event) =>{
setUserValues({ ...userValues, [event.target.name]: event.target.value });
}
Textboxes-
<div className="container1">
<div className="headingsleft">Enter number of <br></br> invoices</div>
<div>
<h4 style={{fontWeight:500, marginLeft:30,fontSize:19}}>a Invoices</h4>
<br></br>
<br></br>
<TextField label="p.a." type="number" name="a" size="small" className={classes.root} inputProps={{ min: "0" }} variant="outlined" value={userValues.nonedinumber} onChange={handleInputChange} required error={userValues.a=== ""} helperText={userValues.a=== "" ? 'Required' : ' '} ></TextField>
</div>
<div>
<h4 className="headings">b Invoices</h4>
<br></br>
<br></br>
<TextField label="p.a." type="number" name="b" size="small" className={classes.root} inputProps={{ min: "0" }} variant="outlined" value={userValues.b} onChange={handleInputChange} required error={userValues.b=== ""} helperText={userValues.b=== "" ? 'Required' : ' '}/>
</div>
<div>
<h4 style={{fontWeight:500, marginLeft:30,fontSize:19}}>cInvoices</h4>
<br></br>
<br></br>
<TextField label="p.a." type="number" name="c" size="small" className={classes.root} inputProps={{ min: "0" }} variant="outlined" value={userValues.c} onChange={handleInputChange} required error={userValues.c=== ""} helperText={userValues.c=== "" ? 'Required' : ' '}/>
</div>
<div>
<h4 style={{fontWeight:500, marginLeft:30,fontSize:19}}>Total Invoices</h4>
<br></br>
<br></br>
<TextField label="p.a." type="number" size="small" id="total" value={total} disabled variant="outlined" />
</div>
</div>
code for the slider-
const Inputaftercalculate = (props) => {
const classes = useStyles();
return (
<div>
<div className="container2">
<div className="headingsleft">Percentage Distribution
</div>
<div >
<br></br>
<br></br>
<Typography className={classes.slider} id="discrete-slider-always" gutterBottom>
</Typography>
<Slider
defaultValue={20}
getAriaValueText={valuetext}
aria-labelledby="discrete-slider-always"
step={10}
marks={marks}
valueLabelDisplay="on"
value={props.a}
disabled
/>
</div>
<div>
<br></br>
<br></br>
<Typography className={classes.slider} id="discrete-slider-always" gutterBottom>
</Typography>
<Slider
defaultValue={20}
getAriaValueText={valuetext}
aria-labelledby="discrete-slider-always"
step={10}
marks={marks}
valueLabelDisplay="auto"
value={props.b}
/>
</div>
<div>
<br></br>
<br></br>
<Typography className={classes.slider} id="discrete-slider-always" gutterBottom>
</Typography>
<Slider
defaultValue={1}
getAriaValueText={valuetext}
aria-labelledby="discrete-slider-always"
step={10}
marks={marks}
valueLabelDisplay="auto"
value={props.c}
/>
</div>
</div>
</div>
How can I make the input textboxes adjust inside values based on changes in slider values and also let users input in the textbox whenever they need to change values?
First you got get the value and it respective key from the event, then expand it and finally assign the value to the respective key name as shown bellow.
const handleInputChange = e => { const {name, value} = e.target; handleInputChange({ ...userValues, [name]: value, }) }

Why button's onClick event is triggered when i typing in TextField ReactJS

I have a sample code for Signing page as follows, When I am typing the username and passwords inside the text fields with every character the onClick event of the button is triggered and I can see the output of console.log(). Why it is triggered?
class Signin extends React.Component {
state = {
username: null,
password: null,
}
render () {
const { t, classes } = this.props;
return (
<div >
<div >
<div >
<Card>
<CardContent>
<form>
<TextField
inputProps={{ style:{fontSize:20, textAlign:'center', direction:'ltr'} }}
value={this.state.username}
onChange={e => this.setState({username: e.target.value})}
id="username"
label={t("Username")}
className={classes.textField}
fullWidth
margin="normal"
/>
<TextField
inputProps={{ style:{fontSize:20, textAlign:'center', direction:'ltr'} }}
value={this.state.password}
onChange={e => this.setState({password: e.target.value})}
id="password"
label={t("Password")}
className={classes.textField}
type="password"
fullWidth
margin="normal"
/>
<Button variant="raised" color="primary" fullWidth type="submit" onClick={console.log(this.state.username,this.state.password)} >{t("Login")}</Button>
</form>
</CardContent>
</Card>
</div>
</div>
</div>
);
}
}
Change your console.log from:
onClick={console.log(this.state.username,this.state.password)}
to like this below:
onClick={() => console.log(this.state.username,this.state.password)}
try this
it is happening because It depends on where exactly are you using the Arrow function. If the Arrow function is used in the render method, then they create a new instance every time render is called just like how bind would work.
<Button
variant="raised"
color="primary"
fullWidth type="submit"
onClick={()=>{console.log(this.state.username,this.state.password)} >{t("Login")}}</Button>

how to edit a textfield values in reactjs

Here i add my sample code.i have a static values getting from state now i want to change this values
render() {
console.log(this.props.selectedVal);
var name,
gender,
city = "";
this.props.data.map((row, index) => {
// console.log(index);
if (this.props.selectedVal === index) {
gender = row[0];
name = row[1];
city = row[2];
}
return [];
});
return (
<Dialog
open={this.props.open}
onClose={this.handleClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<h1>Edit User</h1>
<DialogContent>
<DialogContentText id="alert-dialog-description" />
<Formik
initialValues={{ name: "", gender: "", city: "" }}
onSubmit={values => console.log(values)}
>
{props => (
<form>
<TextField margin="dense" id="name" label="Name" value={name} />
<br />
<TextField
margin="dense"
id="gender"
label="Gender"
value={gender}
/>
<br />
<TextField margin="dense" label="City" value={city} />
</form>
)}
</Formik>
</DialogContent>
<DialogActions>
<Button onClick={this.handleClose} color="primary">
RESET
</Button>
<Button onClick={this.handleClose} color="primary" autoFocus>
SUBMIT
</Button>
</DialogActions>
</Dialog>
);
}
I am getting the values from the table row.Now i want to change these values using formik. How can I edit these values
Add a onChange listener in your textfield and map the value to a state variable:
textChange(e) {
const value = e.target.value
this.setState({ value })
}
render() {
return (
<TextField value={this.state.value} onChange={this.textChange} .. />
)
}
If you want to handle more values from different textfields using one method try something like this:
textChange(e) {
const id = e.target.id
const value = e.target.value
this.setState({ [id]: value })
}
render() {
return (
<TextField id="gender" value={this.state.gender} onChange={this.textChange} .. />
<TextField id="dense" value={this.state.dense} onChange={this.textChange} .. />
)
}
It seems like you get data with props from parent component. And, if I get it wright, question is how to change state of parent component? You need to add to props function binded to parent`s context and use setState there.

Resources