getting error in console MUI: children must be passed when using the TextField component with select.
<TextField
select
id="outlined-basic"
label="User Name"
name="user"
size="small"
{...teamForm.getFieldProps("user")}
error={teamForm.touched.user && teamForm.errors.user}
helpertext={teamForm.touched.user && teamForm.errors.user}
>
{list?.map((option) => (
<MenuItem key={option.username} value={option.name}>
{option.name}
</MenuItem>
))}
</TextField>
Adding some other content when no list provided might help for this:
<TextField
select
id="outlined-basic"
label="User Name"
name="user"
size="small"
{...teamForm.getFieldProps("user")}
error={teamForm.touched.user && teamForm.errors.user}
helpertext={teamForm.touched.user && teamForm.errors.user}
>
{list ? list.map((option) => (
<MenuItem key={option.username} value={option.name}>
{option.name}
</MenuItem>
)) : <div></div>}
</TextField>
Related
I am designing a form in react in which I have two categories of dropdown. one is named as "What include" and the other is "What is not include". Now I want that if the user to select any option from the menu of "What Include", then that option(item) will be disabled in the other drop-down named "What not Include".
Here is the code for handle change and UI:
const [personwhatIncludeItems, setPersonwhatIncludeItems] = React.useState(
[]
);
const [personnotIncludeItems, setPersonnotIncludeItems] = React.useState([]);
const handlenotIncludeItemsChange = (event) => {
const {
target: { value },
} = event;
setPersonnotIncludeItems(
// On autofill we get a stringified value.
typeof value === "string" ? value.split(",") : value
);
};
const handlewhatIncludeItemsChange = (event) => {
const {
target: { value },
} = event;
setPersonwhatIncludeItems(
// On autofill we get a stringified value.
typeof value === "string" ? value.split(",") : value
);
};
<div className="col-6 mt-2 mb-2">
<FormControl fullWidth>
<InputLabel id="multiple-include-label">
{" "}
Includes
</InputLabel>
<Select
labelId="whatInclude-multiple-checkbox-label"
id="whatInclude-multiple-checkbox"
multiple
value={personwhatIncludeItems}
onChange={handlewhatIncludeItemsChange}
input={<OutlinedInput label="Tag" />}
renderValue={(selected) => selected.join(", ")}
MenuProps={MenuProps}
>
{whatIncludeArr.map((whatIncludeItems) => (
<MenuItem
key={whatIncludeItems}
value={whatIncludeItems}
>
<Checkbox
checked={
personwhatIncludeItems.indexOf(
whatIncludeItems
) > -1
}
/>
<ListItemText primary={whatIncludeItems} />
</MenuItem>
))}
</Select>
</FormControl>
</div>
<div className="col-6 mt-2 mb-2">
<FormControl fullWidth>
<InputLabel id="multiple-not-include-label">
{" "}
Not Includes
</InputLabel>
<Select
labelId="whatnotInclude-multiple-checkbox-label"
id="whatnotInclude-multiple-checkbox"
multiple
value={personnotIncludeItems}
onChange={handlenotIncludeItemsChange}
input={<OutlinedInput label="Not Include" />}
renderValue={(selected) => selected.join(", ")}
MenuProps={MenuProps}
>
{WhatNotIncludeArr.map((notIncludeItems) => (
<MenuItem
key={notIncludeItems}
value={notIncludeItems}
>
<Checkbox
checked={
personnotIncludeItems.indexOf(notIncludeItems) >
-1
}
/>
<ListItemText primary={notIncludeItems} />
</MenuItem>
))}
</Select>
</FormControl>
</div>
Not sure if I fully understand the logic, but if the goal is to disable the options if selected else where, perhaps consider to add conditional disabled for each mapped option (if the other selected state already has the value, disable the option), perhaps such as:
Minimized demo of below example: stackblitz
Although not tagged as it, the posted code looks like MUI so the example will use MUI components, but otherwise the approach could still work with other libraries provided that a disabled property is supported.
"What Include" select:
<div className="col-6 mt-2 mb-2">
<FormControl fullWidth>
<InputLabel id="multiple-include-label"> Includes</InputLabel>
<Select
labelId="whatInclude-multiple-checkbox-label"
id="whatInclude-multiple-checkbox"
multiple
value={personwhatIncludeItems}
onChange={handlewhatIncludeItemsChange}
input={<OutlinedInput label="Tag" />}
renderValue={(selected) => selected.join(", ")}
MenuProps={MenuProps}
>
{whatIncludeArr.map((whatIncludeItems) => (
<MenuItem
key={whatIncludeItems}
value={whatIncludeItems}
// 👇 Added disable condition here
disabled={personnotIncludeItems.includes(whatIncludeItems)}
>
<Checkbox
checked={personwhatIncludeItems.indexOf(whatIncludeItems) > -1}
// 👇 Added disable condition here
disabled={personnotIncludeItems.includes(whatIncludeItems)}
/>
<ListItemText primary={whatIncludeItems} />
</MenuItem>
))}
</Select>
</FormControl>
</div>
"What is not include" select:
<div className="col-6 mt-2 mb-2">
<FormControl fullWidth>
<InputLabel id="multiple-not-include-label"> Not Includes</InputLabel>
<Select
labelId="whatnotInclude-multiple-checkbox-label"
id="whatnotInclude-multiple-checkbox"
multiple
value={personnotIncludeItems}
onChange={handlenotIncludeItemsChange}
input={<OutlinedInput label="Not Include" />}
renderValue={(selected) => selected.join(", ")}
MenuProps={MenuProps}
>
{WhatNotIncludeArr.map((notIncludeItems) => (
<MenuItem
key={notIncludeItems}
value={notIncludeItems}
// 👇 Added disable condition here
disabled={personwhatIncludeItems.includes(notIncludeItems)}
>
<Checkbox
checked={personnotIncludeItems.indexOf(notIncludeItems) > -1}
// 👇 Added disable condition here
disabled={personwhatIncludeItems.includes(notIncludeItems)}
/>
<ListItemText primary={notIncludeItems} />
</MenuItem>
))}
</Select>
</FormControl>
</div>
In my project, using Textfield to add tags. But my requirement is to add an endAdornment to pass the values to be added or edited. But I don't know how to use it, please help me to do this, give me some suggestions to fix this problem.
render() {
return (
<>
<TextField id="outlined-basic" variant="outlined"
InputProps={{
startAdornment: this.state.items.map(item => (
<Chip
key={item}
tabIndex={-1}
label={item}
onDelete={() => this.handleDelete(item)}
onClick={() => this.handleItemEdit(item)}
/>
)),
// endAdornment:
}}
ref={this.state.items}
className={"input " + (this.state.error && " has-error")}
value={this.state.value}
placeholder="Type or paste email addresses and press `Enter`..."
onKeyDown={this.handleKeyDown}
onChange={this.handleChange}
onPaste={this.handlePaste}
/>
{this.state.error && <p className="error">{this.state.error}</p>}
</>
);
}
}
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("");
}}
>
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>
I have a TextField that is disabled and I'm updating it with React Hooks useState by changing the value property of the TextField.
const [employee , setEmployee] = React.useState('')
<TextField
fullWidth
disabled
value={employee}
variant="outlined"
InputProps={{
startAdornment: (
<InputAdornment position="start">
<BackupIcon onClick={handleClick}/>
</InputAdornment>
),
}}
/>
It's only clickable on the Icon BackupIcon.
How can we make it clickable all over the TextField ?
Have you tried putting the onClick like this:
handleClick: function(e) {
this.setState({
textFieldValue: e.target.value
});
},
<TextField fullWidth
disabled
value={employee}
variant="outlined"
onChange={handleClick}
>
<BackupIcon />
<TextField />