Trying to update an object from child froms ? react js - javascript

I want to update a js object in a parent component from child component which contain a form
the function in my parent component.
getnewDataFirstGroup = (labelValue, typeValue, viewNameValue,todayMeasureValue, seasonLevelValue, numPosInSeasonValue, numSeasonsInYearValue) => {
this.setState({
newDatafirstG: {
label: labelValue,
type: typeValue,
viewName: viewNameValue,
todayMeasure: todayMeasureValue,
seasonLevel: seasonLevelValue,
numPosInSeason: numPosInSeasonValue,
numSeasonsInYear:numSeasonsInYearValue,
chartDefaultLevel:seasonLevelValue
}
})
}
getStepContent(steps) {
switch (steps) {
case 0:
return <FirstGroup folder={this.props.folder} onDataChange={this.getnewDataFirstGroup} />
case 1:
return <SecondGroup folder={this.props.folder} change={this.getnewDataSecondGroup} />;
case 2:
return <PreviewFile content={<ReactJson src={this.state.file} />} />;
default:
throw new Error('Unknown step');
};
}
as u see here i am trying to update newdatafirstG from the component First Group.
code of the first group component :
if (this.state.profileLabel && this.state.season && this.state.viewname && this.state.todayMeasure && this.state.seasonlevel && this.state.numPosSeason && this.state.numPosYear) {
this.props.onDataChange(this.state.profileLabel,this.state.season,this.state.viewname,this.state.todayMeasure,this.state.seasonlevel,this.state.numPosSeason,this.state.numPosYear )
}
}
the render of child component
render() {
const { classes } = this.props;
const vienwnameArray = this.listWorsheetsForm();
const seasonsLevel = this.ListSeasonLevel();
return (
<React.Fragment>
<div>
<Typography variant="h6" gutterBottom>
First Group
</Typography>
</div>
<Grid container spacing={3}>
<Grid item xs={10} sm={11}>
<TextField
required
id="label"
name="profileLabel"
label="Profile Label"
value={this.state.profileLabel}
onChange={this.handleChangeLabel}
fullWidth
autoComplete="given-name"
/>
</Grid>
<Grid item xs={12} sm={6} >
<FormControl required className={classes.formControl} >
<InputLabel id="profileType">Profile Type</InputLabel>
<Select
labelId="Type"
id="profileType"
onClose={this.handleCloseselect}
onOpen={this.handleOpenselect}
value={this.state.season}
onChange={this.handleChangeSeason}
>
<MenuItem value={'Pre-Season'}>Pre-Season</MenuItem>
<MenuItem value={'In-Season'} >In-Season</MenuItem>
</Select>
</FormControl>
</Grid>
<Grid item xs={12} sm={6}>
<FormControl required className={classes.formControl} >
<InputLabel id="viewname">View Name</InputLabel>
<Select
labelId="viewname"
id="vienwname"
onClose={this.handleCloseselect}
onOpen={this.handleOpenselect}
value={this.state.viewname}
onChange={this.handleChangeViewname}
>
{vienwnameArray.map((element, index) => (<MenuItem key={`${index}`} value={element}>{element}</MenuItem>))}
</Select>
</FormControl>
</Grid>
<Grid item xs={12} sm={6}>
<FormControl required className={classes.formControl} >
<InputLabel id="measure">Today Measure</InputLabel>
<Select
labelId="measure"
id="measure"
onClose={this.handleCloseselect}
onOpen={this.handleOpenselect}
value={this.state.measure}
onChange={this.handleChangeMeasure}
>
{this.state.measuresArray.map((element, index) => (<MenuItem key={`${index}`} value={element}>{element}</MenuItem>))}
</Select>
</FormControl>
</Grid>
<Grid item xs={12} sm={6}>
<FormControl required className={classes.formControl} >
<InputLabel id="season">Season Level</InputLabel>
<Select
labelId="season"
id="seasonlevel"
onClose={this.handleCloseselect}
onOpen={this.handleOpenselect}
value={this.state.seasonlevel}
onChange={this.handleChangeSeasonlevel}
>
{seasonsLevel.map((element, index) => (<MenuItem key={`${index}`} value={element}>{element}</MenuItem>))}
</Select>
</FormControl>
</Grid>
<Grid item xs={12} sm={6}>
<FormControl required className={classes.formControl} >
<InputLabel id="numPS">Num Position in Season</InputLabel>
<Select
labelId="numPS"
id="PosSeason"
onClose={this.handleCloseselect}
onOpen={this.handleOpenselect}
value={this.state.numPosSeason}
onChange={this.handleChangePosSeason}
>
{[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24].map((element, index) => (<MenuItem key={`${index}`} value={element}>{element}</MenuItem>))}
</Select>
</FormControl>
</Grid>
<Grid item xs={12} sm={6}>
<FormControl required className={classes.formControl} >
<InputLabel id="numPY">Num Position in Year</InputLabel>
<Select
labelId="numPY"
id="seasonlevel"
onClose={this.handleCloseselect}
onOpen={this.handleOpenselect}
value={this.state.numPosYear}
onChange={this.handleChangePosYear}
>
{[1, 2, 3, 4].map((element, index) => (<MenuItem key={`${index}`} value={element}>{element}</MenuItem>))}
</Select>
</FormControl>
</Grid>
</Grid>
{this.sendFirstGroupData()}
</React.Fragment>
);
};
How can i update my state in the parent component forom form which exist in the child component ?

From my experience, to update the parent component from the child component you would have to create a function in parent updateParent() lets say.
You would then pass this function into the child as a prop.
The child would call this function then: this.props.updateParent(..values)
I hope this helps. If you need more, I can update later with an example!

Related

Is there any way to change data on my consecutive select field by clicking on 1st select dropdown filed, and data can be added to db, in MUI of React

I am trying to change the second select dropdown field based on the first select dropdown field, is there any kind of possibility to do this along with the second auto select data store on my database when I post it.
How I do now
I manually select the Order Quantity and Style No. belongs to MON.
How I want to do
I only want that if I select MON, then Order Quantity and Style No. automatically selected.
MUI Select Drop Down code:
Here is the code which I written, please help me out to solve it.
{/* MON */}
<FormControl sx={{ m: 0.5 }} variant="standard">
<InputLabel
style={{ fontSize: "15px" }}
id="demo-customized-select-label"
>
MON
</InputLabel>
<Select
required
style={{
fontSize: "12px",
}}
labelId="demo-customized-select-label"
id="demo-customized-select"
value={plandata.MON}
onChange={(e) => {
setPlanData((prev) => ({
...prev,
MON: e.target.value,
}));
}}
input={<BootstrapInput />}
>
{rawData
?.filter(
(data) =>
data.c_n
.toString()
.includes(plandata.customer.toString()) &&
data.type.includes(plandata.division) &&
data.Item_description.toString().includes(
plandata.styleName.toString()
)
)
.map((value, i) => (
<MenuItem key={i} value={value.mon.toString()}>
{value.mon.toString()}
</MenuItem>
))}
</Select>
</FormControl>
{/* Order Quantity */}
<FormControl sx={{ m: 0.5 }} variant="standard">
<InputLabel
style={{ fontSize: "15px" }}
id="demo-customized-select-label"
>
Order Quantity
</InputLabel>
<Select
required
style={{
fontSize: "12px",
width: "85px",
}}
labelId="demo-customized-select-label"
id="demo-customized-select"
value={plandata.orderQuantity}
onChange={(e) => {
setPlanData((prev) => ({
...prev,
orderQuantity: e.target.value,
}));
}}
input={<BootstrapInput />}
>
{rawData
?.filter(
(data) =>
data.c_n
.toString()
.includes(plandata.customer.toString()) &&
data.type.includes(plandata.division) &&
data.Item_description.toString().includes(
plandata.styleName.toString()
) &&
data.mon.toString().includes(plandata.MON.toString())
)
.map((value, i) => (
<MenuItem key={i} value={value.oq.toString()}>
{value.oq.toString()}
</MenuItem>
))}
</Select>
</FormControl>
{/* Style No */}
<FormControl sx={{ m: 0.5 }} variant="standard">
<InputLabel
style={{ fontSize: "15px" }}
id="demo-customized-select-label"
>
Style No
</InputLabel>
<Select
required
style={{
fontSize: "12px",
width: "85px",
}}
labelId="demo-customized-select-label"
id="demo-customized-select"
value={plandata.finishcode}
onChange={(e) => {
setPlanData((prev) => ({
...prev,
finishcode: e.target.value,
}));
}}
input={<BootstrapInput />}
>
{rawData
?.filter(
(data) =>
data.c_n
.toString()
.includes(plandata.customer.toString()) &&
data.type.includes(plandata.division) &&
data.Item_description.toString().includes(
plandata.styleName.toString()
) &&
data.mon.toString().includes(plandata.MON.toString())
)
.map((value, i) => (
<MenuItem key={i} value={value.style_no.toString()}>
{value.style_no.toString()}
</MenuItem>
))}
</Select>
</FormControl>
Additionally
Moreover, if data is change by other select field then, when I add my data to my Database the changed data should be posted.

is it possible to make the antd FormItem flexiable

I am using FormItem as the app UI table filter condition, and using Row and Col to layout the component. Current I am facing a problem that when user scale the window, the FormItem could not auto fit the screen resize. So I want to make the FormItem flexiable, when user scale the broswer window, the FormItem could auto rearrangement to multiline to fit the screen change automatically. This is the code current I am using:
renderSimpleForm() {
const {
form,
dispatch,
loading,
activityM: { wordItems = [] },
activityM,
} = this.props;
const { getFieldDecorator } = form;
const {
formValues: { goodWord },
} = this.state;
return (
<Form onSubmit={this.handleSearch} layout="inline">
<Row gutter={16} justify="start">
<Col md={5} sm={24}>
<FormItem label="create date:">
{getFieldDecorator('activityCreateTime', {
})(<RangePicker className={styles.rangepicker} format={dateFormat} />)}
</FormItem>
</Col>
<Col md={5} sm={24}>
<FormItem label="activity date:">
{getFieldDecorator('activityTime', {
})(<RangePicker className={styles.rangepicker} format={dateFormat} />)}
</FormItem>
</Col>
<Col md={3} sm={24}>
<FormItem label="activity status:">
{getFieldDecorator('activityStatus', {
initialValue: '',
})(
<Select placeholder="please choose" style={{ width: 85 }} onSelect={this.onChoseHouse}>
<Option value="">all</Option>
{getSelectOptionByArr(questionType)}
</Select>
)}
</FormItem>
</Col>
<Col md={4} sm={24}>
<FormItem label="user:">
{getFieldDecorator('name', {
initialValue: this.state.formValues.name,
rules: [{ required: false }],
})(<Input type="text" placeholder="creator" />)}
</FormItem>
</Col>
<Col md={2} sm={20}>
<Button type="primary" shape="round" htmlType="submit" className="fun-button">
search
</Button>
</Col>
</Row>
</Form>
);
}
what should I do to make the FormItem items flexiable?
I define different size with different devcie right now like this with each col:
<Col xs={24} sm={12} md={12} lg={12} xl={8} xxl={5}>
<FormItem label="create date:">
{getFieldDecorator('activityCreateTime', {
})(<RangePicker className={styles.rangepicker} format={dateFormat} />)}
</FormItem>
</Col>

How to Add input fields in form when "Other" option is selected in dropdown in React.js

I have a multi select dropdown input and I am saving all the selected items in an (useState) array when user click add icon.
I want to render input field when "Other" option is selected in dropdown.
and also want that the value entered in other should be added in the array.
handle change :-
const handleCareerChoice = (event) => {
setValues({ ...values, careerChoice: event.target.value });
};
const handleChange = (input) => (event) => {
setValues({ ...values, error: false, [input]:event.target.value});
};
const [otherState, setOtherState] = useState(false);
dropdown
<Grid container className={classes.grid} style={{ marginBottom: "10px" }}>
<Grid item xs={11} sm={5} lg={11} sx={{ m: 1 }}>
<FormControl variant="outlined" fullWidth sx={{ mt: 1 }}>
<InputLabel id="demo-mutiple-checkbox-label">
Top Career Choice
</InputLabel>
<Select
label="Top Career Choice"
id="demo-mutiple-checkbox"
multiple
value={values.careerChoice}
onChange={handleChange("careerChoice")}
renderValue={(selected) => selected.join(", ")}
>
<TextField variant="outlined" style={{ width: "100%" }} />
{careerChoice.map((name) => (
<MenuItem key={name} value={name}>
<Checkbox checked={values.careerChoice.indexOf(name) > -1} />
<ListItemText primary={name} />
</MenuItem>
))}
<MenuItem >
<Checkbox onClick={setOtherCareerChoice(!otherCareerChoice)} />
<ListItemText primary={"Others"} />
</MenuItem>
</Select>
</FormControl>
</Grid>
{ otherCareerChoice && (
<Grid item xs={11} sm={5} lg={11} sx={{ m: 1 }}>
<FormControl variant="outlined" fullWidth sx={{ mt: 1 }}>
<InputLabel htmlFor="outlined-adornment-password">
Other Career Choice
</InputLabel>
<OutlinedInput
id="careerChoice"
name="careerChoice"
label="Additional Career Choice"
fullWidth
autoComplete="careerChoice"
// value={values.careerChoice}
onChange={handleCareerChoice}
endAdornment={
<InputAdornment position="end">
<IconButton
edge="end"
>
<Add/>
</IconButton>
</InputAdornment>
}
/>
</FormControl>
</Grid>
)}
currently, input is looking like
this but on clicking other text field, I see a blank screen with error
TypeError: selected.join is not a function
Please suggest me a good approach to do this
Here's a codesandbox for the full code
First you want to render the "Other Career Text" input box when it is selected from the dropdown. For that, add an onClick for Others in the dropdown
<MenuItem onClick={() => setOtherCareerChoice(!otherCareerChoice)}>
<Checkbox />
<ListItemText primary={"Others"} />
</MenuItem>
Now that the input field is rendered, at a value and onChange attribute to let the user type a text
<OutlinedInput
value={otherCareerText}
onChange={(event) => setOtherCareerText(event.target.value)}
Finally when the user clicks the "+" button, push this text to your state in an onClick
<IconButton
onClick={() => {
setValues({
...values,
careerChoice: [...values.careerChoice, otherCareerText]
});
setOtherCareerChoice(false);
setOtherCareerText("");
}}
>

Dynamically second field select value based on first select value

I am using React and Formik. I have initial values set.
initialValues={{
Department: "",
Category: "",
}}
Department and Category are material ui menus dependent on each other. If user selects a value from Department then Related categories will get updated.
New we get new initial values from api like this
initialValues={{
Department: "IT",
Category: "Forgot Password",
}}
Values are being set for both menus. but Category is not being filled as its data is being populated on change of Department. How to trigger change so that Categories will get values and i can set the data which i got from api.
Formik code
<Formik
enableReinitialize={true}
initialValues={{
Department: "IT",
Category: "Forgot Password",
}}
innerRef={formRef}
validateOnChange={true}
validateOnBlur={false}
validate={values => { }}
>
{({ values, touched, errors, handleChange, handleBlur, isValid, setFieldValue }) => (
<Form noValidate autoComplete="off" >
<Grid container spacing={3}>
<Grid item lg={4} xs={12}>
<FormControl className={classes.fullWidth} error={Boolean(errors.Department && touched.Department)}>
<InputLabel id="Department">Department</InputLabel>
<Select
name="Department"
labelId="Department"
id="Department"
onChange={(e, value) => {
setFieldValue('Department', value === null ? "" : value.props.value);
setFieldValue('Category', "");
departmentChange(value.props.value);
}}
fullWidth
value={values.Department}
>
{departmentList && departmentList.map((department, index) => {
return (
<MenuItem key={index} value={department.Department}>{department.Department}</MenuItem>
)
})}
</Select>
<FormHelperText className={classes.error}>{(errors.Department && touched.Department) && errors.Department}</FormHelperText>
</FormControl>
</Grid>
<Grid item lg={4} xs={12}>
<FormControl className={classes.fullWidth} error={Boolean(errors.Category && touched.Category)}>
<InputLabel id="Category">Category</InputLabel>
<Select
name="Category"
labelId="Category"
id="Category"
onChange={handleChange}
fullWidth
value={values.Category}
>
{categoryList && categoryList.map((category, index) => {
return (
<MenuItem key={index} value={category.Category}>{category.Category}</MenuItem>
)
})}
</Select>
<FormHelperText className={classes.error}>{(errors.Category && touched.Category) && errors.Category}</FormHelperText>
</FormControl>
</Grid>
<Grid item lg={12} xs={12} align="right">
<div className={classes.wrapper}>
<Button
className={classes.button}
type="submit"
color="primary"
variant="contained"
disabled={showButtonLoader}
>
submit
</Button>
{showButtonLoader && <CircularProgress size={24} className={classes.buttonProgress} />}
</div>
</Grid>
</Grid>
</Form>)}
</Formik>

React+JavaScript How to create an object in React with all the given fields

I have the following Sign-up page and I console log each time in the function called 'sign' once the Sign Up button is clicked. While each field is individually visible in the console, I need to make them appear as one object. Any help is appreciated, here is my code for the react function SignUp:
export default function SignUp() {
const [firstName, setFirstName] = React.useState("");
const [email, setEmail] = React.useState("");
const [password, setPassword] = React.useState("");
let sign = (event) => {
event.preventDefault();
console.log(firstName);
};
return (
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign up
</Typography>
<form className={classes.form} noValidate>
<Grid container spacing={2}>
<Grid item xs={12} sm={6}>
<TextField
autoComplete="fname"
name="firstName"
variant="outlined"
required
fullWidth
id="firstName"
label="First Name"
autoFocus
onChange={(event) => setFirstName(event.target.value)}
/>
</Grid>
<Grid item xs={12}>
<TextField
variant="outlined"
required
fullWidth
id="email"
label="Email Address"
name="email"
autoComplete="email"
onChange={(event) => setEmail(event.target.value)}
/>
</Grid>
<Grid item xs={12}>
<TextField
variant="outlined"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
autoComplete="current-password"
onChange={(event) => setPassword(event.target.value)}
/>
</Grid>
</Grid>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
onClick={sign}
>
Sign Up
</Button>
You can use useReducer to create a state object of your component like this:
import React, { useReducer } from 'react'
const initialState = {
firstName: '',
email: '',
password: '',
}
const reducer = (state = initialState, action) => {
switch (action.type) {
case 'SET_FIRSTNAME':
return { ...state, firstName: action.payload }
case 'SET_EMAIL':
return { ...state, email: action.payload }
case 'SET_PASSWORD':
return { ...state, password: action.payload }
default:
return state
}
}
export default function SignUp() {
const [state, dispatch] = useReducer(reducer, initialState)
let sign = (event) => {
event.preventDefault();
console.log(state);
};
return (
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign up
</Typography>
<form className={classes.form} noValidate>
<Grid container spacing={2}>
<Grid item xs={12} sm={6}>
<TextField
autoComplete="fname"
name="firstName"
variant="outlined"
required
fullWidth
id="firstName"
label="First Name"
autoFocus
onChange={(event) => dispatch({ type: 'SET_FIRSTNAME', payload: event.target.value })}
/>
</Grid>
<Grid item xs={12}>
<TextField
variant="outlined"
required
fullWidth
id="email"
label="Email Address"
name="email"
autoComplete="email"
onChange={(event) => dispatch({ type: 'SET_EMAIL', payload: event.target.value })}
/>
</Grid>
<Grid item xs={12}>
<TextField
variant="outlined"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
autoComplete="current-password"
onChange={(event) => dispatch({ type: 'SET_PASSWORD', payload: event.target.value })}
/>
</Grid>
</Grid>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
onClick={sign}
>
Sign Up
</Button>
You can do something like this :
console.log({ firstName , email , password });

Categories