How do I create dynamic select fields? - javascript

I have these 2 fields size and design in which the user can add more of these 2 fields as many times as they want.
Example:
I selected M for the size. It does show in the console:
Additionally, why is it rendering two of size and design at the first load of the screen? Also, add
And now selecting a design:
It will remove the value that was previously selected in the size field.
And in the console, the value of size has been replaced with design2
codesandbox link: https://codesandbox.io/s/form-1-ls6rx?file=/demo.js
import React, { useState, useEffect } from "react";
import Box from "#mui/material/Box";
import InputLabel from "#mui/material/InputLabel";
import MenuItem from "#mui/material/MenuItem";
import FormControl from "#mui/material/FormControl";
import Select from "#mui/material/Select";
import { TextField, Button } from "#mui/material";
export default function BasicSelect() {
const [prod, setProd] = useState("");
const [qty, setQty] = useState(0);
const [design, setDesign] = useState("");
const [sizeList, setSizeList] = useState([{ size: "", design: "" }]);
const handleChange = (event) => {
setProd(event.target.value);
};
const handleSubmit = async (e) => {
e.preventDefault();
console.log(prod, qty, sizeList, design);
};
//helper method
const handleAdd = () => {
setSizeList([...sizeList, { size: "", design: "" }]);
};
const handleRemove = (index) => {
const list = [...sizeList];
list.splice(index, 1);
setSizeList(list);
};
const handleSizeChange = (e, index) => {
const { value } = e.target;
setSizeList((prev) =>
Object.assign([...prev], {
[index]: { size: value }
})
);
};
useEffect(() => {
console.log(sizeList);
}, [sizeList]);
return (
<Box sx={{ minWidth: 120 }}>
<form onSubmit={handleSubmit}>
<FormControl fullWidth>
<InputLabel id="demo-simple-select-label">Product</InputLabel>
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={prod}
label="Product"
onChange={handleChange}
>
<MenuItem value="Item1">Item1</MenuItem>
<MenuItem value="Item2">Item2</MenuItem>
<MenuItem value="Item3">Item3</MenuItem>
</Select>
</FormControl>
<br />
<br />
<br />
<br />
{sizeList.map((singleSize, index) => (
<div key={index}>
<FormControl fullWidth>
<InputLabel id="demo-simple-select-label">Size</InputLabel>
<Select
labelId="demo-simple-select-label"
id="size"
value={singleSize.size}
label="Product"
onChange={(e) => handleSizeChange(e, index)}
>
<MenuItem value="S">Small</MenuItem>
<MenuItem value="M">Medium</MenuItem>
<MenuItem value="L">Large</MenuItem>
</Select>
</FormControl>
<FormControl fullWidth>
<InputLabel id="demo-simple-select-label">
Choose Design
</InputLabel>
<Select
labelId="demo-simple-select-label"
id="design"
value={singleSize.design}
label="Product"
onChange={(e) => handleSizeChange(e, index)}
>
<MenuItem value="Design1">Design1</MenuItem>
<MenuItem value="Design2">Design2</MenuItem>
<MenuItem value="Design3">Design3</MenuItem>
</Select>
</FormControl>
<br />
<br />
{sizeList.length > 1 && (
<Button
onClick={() => handleRemove(index)}
variant="contained"
color="secondary"
>
Remove{" "}
</Button>
)}
<br />
<br />
{sizeList.length - 1 === index && (
<Button variant="contained" onClick={handleAdd}>
{" "}
Add Quantity
</Button>
)}
</div>
))}
<br />
<br />
<br />
<br />
<Button type="submit">Submit </Button>
</form>
<Button>Add more Product </Button>
</Box>
);
}

You are using the same handler that is supposed to handle and update states for both the design and size, also there lies a problem in how you are updating the state using Object.assign, this is also leading to additional warnings in the console regarding the value passed, the issue is most likely due to the event conflict.
To put things in place, simply use different handlers to handle updates of different object attributes. A simple solution is to create a new array, make the necessary updates and set the new array to be the updated state, I tested this and it works as expected.
const handleSizeChange = (e, index) => {
const { value } = e.target;
console.log(value)
const arr = [...sizeList] //Shallow copy the existing state
arr[index].size = value //Update the size to the selected size
setSizeList([...arr]); //Set the updated array to be the new state
};
Add a new handler for updating the design value.
const handleDesignChange = (e,index)=>{
const { value } = e.target;
console.log(value)
const arr = [...sizeList]
arr[index].design = value
// console.log(arr)
setSizeList([...arr]);
}
Alternatively, you could club both the handlers into a single handler by adding conditional checks.

Related

How to get the field values in react material ui components

This works but the when i console log the object it gives
{ "week":undefined, "name":undefined, "code":undefined }
Moreover does wrapping all the material ui component in form tag and treating the whole code as a form, is it appropriate?
here is my code:
const ExamSimulatorForm = () => {
const weekNumber = useRef();
const examSub = useRef();
const examCode = useRef();
const handleSubmit = (event) =>{
event.preventDefault()
const week = weekNumber.current.value
const subject = examSub.current.value
const code = examCode.current.value
const examSimulatorPayload = {
week:week,
subject:subject,
code:code
}
console.log(examSimulatorPayload)
}
const [code, setCode] = useState('Quiz');
const [examSubject, setExamSubject] = useState('');
const [field, setField] = useState(1)
const handleESubjectChange = (event) => {
setExamSubject(event.target.value);
};
const handleCode = (event) => {
setCode(event.target.value);
};
return (
<form >
<CardActions onSubmit={handleSubmit}>
<Grid container spacing={2} justifyContent='center' alignItems='center' direction='column'>
<Grid item>
<TextField
InputProps={{
inputProps: {
max: 12, min: 1
}
}}
label='Week'
type='number'
onChange={(event)=>setField(parseInt(event.target.value))}
style={{minWidth:250}}
ref = {weekNumber}
required
/>
</Grid>
<Grid item>
<FormControl style={{minWidth:250}}>
<InputLabel>Subject</InputLabel>
<Select
value={examSubject}
onChange={handleESubjectChange}
ref={examSub}
required
>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
</Grid>
<Grid item>
<FormControl style={{minWidth:250}}>
<InputLabel id="exam-code" >Exam Code</InputLabel>
<Select
labelId="exam-code"
id="exam-code-select"
value={code}
onChange={handleCode}
ref={examCode}
required
>
<MenuItem value={'Q'}>Q</MenuItem>
<MenuItem value={'M'}>M</MenuItem>
<MenuItem value={'F'}>F</MenuItem>
</Select>
</FormControl>
</Grid>
<Grid item>
<Button variant='contained' color='primary' style={{marginTop:94}} >Take Exam</Button>
</Grid>
</Grid>
</CardActions>
</form>
)
}
export default ExamSimulatorForm;
I have a similar form for attendance simulation, attendance dataset generation and exam dataset generation
I think this is good for you.
Please try this.
const ExamSimulatorForm = () => {
const [state, setState] = useState({
code: 'Quiz',
subject: '',
week: 1
});
const handleSubmit = (event) =>{
event.preventDefault()
const examSimulatorPayload = state;
console.log(examSimulatorPayload)
}
const handleChange = (evt, name) {
const { value } = evt.target;
setState({
...state,
[name]: value
});
}
return (
<form onSubmit={handleSubmit}>
<CardActions>
<Grid container spacing={2} justifyContent='center'
alignItems='center' direction='column'>
<Grid item>
<TextField
InputProps={{
inputProps: {
max: 12, min: 1
}
}}
label='Week'
type='number'
value={state.week}
onChange={(event)=>handleChange( event, "week")}
style={{minWidth:250}}
required
/>
</Grid>
<Grid item>
<FormControl style={{minWidth:250}}>
<InputLabel>Subject</InputLabel>
<Select
value={state.subject}
onChange={(event)=>handleChange( event, "subject")}
required
>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
</Grid>
<Grid item>
<FormControl style={{minWidth:250}}>
<InputLabel id="exam-code" >Exam Code</InputLabel>
<Select
labelId="exam-code"
id="exam-code-select"
value={state.code}
onChange={(event)=>handleChange( event, "code")}
required
>
<MenuItem value={'Q'}>Q</MenuItem>
<MenuItem value={'M'}>M</MenuItem>
<MenuItem value={'F'}>F</MenuItem>
</Select>
</FormControl>
</Grid>
<Grid item>
<Button variant='contained' color='primary' style=
{{marginTop:94}} >Take Exam</Button>
</Grid>
</Grid>
</CardActions>
</form>
)
}
export default ExamSimulatorForm;
Please check it above code, and let me know your idea.
State updates in react are asynchronus, which means they don't occur as soon as you call them. You have to wait until the state updates to console.log because otherwise, nothing has changed and you are getting the initial value. You could do something like this:
useEffect(() => {
const subject = examSub.current.value
console.log(subject)
}, [examSubject])
useEffect() executes an action every time a state changes. Notice how at the end there is an array, with [examSubject]. This signifies the state that will trigger the effect. So when examSubject changes (when you assign a value to it), the effect will execute (in this case, it will log the subject).
When writing code, at least in my case, you don't need to worry about this. You can chnage the state and write your code as normal, but react might take a second or two to update the state. The only time I really notice this is when I console.log.
You can define the state for your inputs :
const [code, setCode] = React.useState('');
const [subject, setSubject] = React.useState('');
const [week, setWeek] = React.useState('');
const setExamCode = event => {
setCode(event.target.value);
};
const setSubject = event => {
setSubject(event.target.value);
};
const setWeek = event => {
setWeek(event.target.value);
};
Then call these methods from onChange event like : onChange={setExamCode} or {setSubject}
In case you want to handle data from single event and defining it's initial state try below approach :
const initialData = Object.freeze({
code: "",
subject: "",
week: ""
});
const [data, updateData] = React.useState(initialData );
const handleChange = (e) => {
updateData({
...data,
[e.target.name]: e.target.value
});
};
const handleSubmit = (e) => {
e.preventDefault()
console.log(data);
};
Then call these methods from onChange event like onChange={handleSubmit}

Material-UI TextField loses focus on every onChange

I am creating the following component:
It will contain an array of objects, where each object is a prescription, with the medicine name from the select and a TextField for the Dosis.
My problem is that the TextField loses focus on every onChange() and is very frustrating because it cannot be edited on a single focus.
This is my component :
const MedicineSelect = ({ medications, setMedications, ...props }) => {
const { medicines } = useMedicines()
const classes = useStyles()
const handleChange = (index, target) => {
// setAge(event.target.value)
const newMedications = cloneDeep(medications)
newMedications[index][target.name] = target.value
setMedications(newMedications)
}
const handleAddMedicine = () => {
const newMedications = cloneDeep(medications)
newMedications.push({ medicine: '', dosis: '', time: '' })
setMedications(newMedications)
}
const handleDeleteMedicine = (index) => {
console.log('DELETE: ', index)
const newMedications = cloneDeep(medications)
newMedications.splice(index, 1)
setMedications(newMedications)
}
return (
<Paper style={{ padding: 5 }}>
<List>
{medications.map((medication, index) => (
<ListItem key={nanoid()} divider alignItems='center'>
<ListItemIcon>
<Tooltip title='Eliminar'>
<IconButton
className={classes.iconButton}
onClick={() => handleDeleteMedicine(index)}
>
<HighlightOffOutlinedIcon />
</IconButton>
</Tooltip>
</ListItemIcon>
<FormControl className={classes.formControl}>
<InputLabel
id={`${index}-select-${medication}-label`}
>
Medicamento
</InputLabel>
<Select
labelId={`${index}-select-${medication}-label`}
id={`${index}-select-${medication}`}
name='medicine'
value={medication.medicine}
onChange={(event) =>
handleChange(index, event.target)
}
>
{medicines.map((medicine) => (
<MenuItem
key={nanoid()}
value={medicine.name}
>
{medicine.name}
</MenuItem>
))}
</Select>
</FormControl>
<TextField
// fullWidth
id={`${index}-text-${medication}`}
label='Dosis'
name='dosis'
onChange={(event) =>
handleChange(index, event.target)
}
value={medication.dosis}
/>
</ListItem>
))}
<Button onClick={handleAddMedicine}>+ agregar</Button>
</List>
</Paper>
)
}
And here is where I set the component:
const [medications, setMedications] = useState([
{ medicine: '', dosis: '', time: '' },
])
...
<Grid item md={12} xs={12}>
<Accordion>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls='panel1a-content'
id='panel1a-header'
>
<Typography variant='h4'>
Tratamiento:
</Typography>
</AccordionSummary>
<AccordionDetails>
<Container disableGutters>
<MedicineSelect
medications={medications}
setMedications={setMedications}
/>
</Container>
</AccordionDetails>
</Accordion>
</Grid>
...
Adding and removing objects from the array works perfect. selecting the medicine from the select, also works perfect. the only problem I have is when editing the Dosis TextField, with every character, the focus is lost and I have to click again on the TextField.
Please help me getting this fixed!!!
After searching a lot, finally I found the solution. Actually when using nanoid() to create unique keys, on every state update React re-renders all components and since the id of both the List and the TextField component are regenerated by nanoid on every render, React loses track of the original values, that is why Focus was lost.
What I did was keeping the keys unmuttable:
<ListItem key={`medication-${index}`} divider alignItems='center'>
and
<TextField
key={`dosis-${index}`}
fullWidth
// id={`${index}-dosis-${medication}`}
label='Dosis'
name='dosis'
onChange={(event) =>
handleChange(index, event.target)
}
value={medication.dosis}
/>

Retrieving data from state and displaying it in dynamic form in antd

In this line {({languages}, {add, remove}) => .... I am trying to put languages from state. But I have a problem referencing the state. The message .map is not a function appears. After pressing Add another languages, more inputs should appear with the possibility of choosing another language. I use library antd.
Code here: https://stackblitz.com/edit/react-ycty22
import React from "react";
import React, {useState} from 'react';
import {
Form,
Button,
Select,
Space
} from 'antd';
import { MinusCircleOutlined, PlusOutlined } from '#ant-design/icons';
import 'antd/dist/antd.css';
const { Option } = Select;
const App = () => {
const [values, setValues] = useState({
birthCountries: ['England', 'Germany', 'France'],
birthCountry: '',
languages: [{name: "German", level: "B1"}]
});
const {languages, birthCountries} = values;
const Languages = () => {
const onFinish = values => {
console.log('Received values of form:', values);
};
return (
<Form name="dynamic_form_nest_item" onFinish={onFinish} autoComplete="off">
<Form.List name="users">
{({languages}, { add, remove }) => { //{languages} in this place I want to put languages
//from state
return (
<div>
{languages.map(language => (
<Space key={language.name} style={{ display: 'flex', marginBottom: 8 }} align="start">
<Form.Item
label="Language"
{...language}
name={[language.name, 'first']}
>
<Select defaultValue={language.name} onChange={}>
{birthCountries.map((birthCountry, index) => {
return <Option value={birthCountry} key={index}>{birthCountry}</Option>
})}
</Select>
</Form.Item>
<Form.Item
label="Level"
{...language}
name={[language.level, 'last']}
>
<Select defaultValue={language.level} onChange={}>
{birthCountries.map((birthCountry, index) => {
return <Option value={birthCountry} key={index}>{birthCountry}</Option>
})}
</Select>
</Form.Item>
<MinusCircleOutlined
onClick={() => {
remove(language.name);
}}
/>
</Space>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
block
>
<PlusOutlined /> Add another Language
</Button>
</Form.Item>
</div>
);
}}
</Form.List>
</Form>
);
};
return (
<div>
{Languages()}
</div>
);
};
export default App;
So I think I found a way throw Ant Design documentation, which is quite non-intuitive when it comes to forms.
First of all you would like to set an initialValues to the Form component (the function that you use inside Form.List is not using languages from the scope, but rather as an argument that is feed as a Composed Element.
Later the most difficult part comes, you need to read the right value from the languages field. For that you substitute name prop in the Form.item for an array that points to language.name and then the second argument is the actual name of the field.
<Form name="dynamic_form_nest_item" onFinish={onFinish} autoComplete="off" initialValues={{ languages}}>
<Form.List name="languages" >
{(languages, {add, remove}) => {
return (
<div>
{languages.map((language, index) => (
<Space key={language.name} style={{ display: 'flex', marginBottom: 8 }} align="start">
<Form.Item
label="Language"
{...language}
name={[language.name, 'name']}
fieldKey={[language.fieldKey, 'name']}
>
<Select onChange={}>
{birthCountries.map((birthCountry, index) => {
return <Option value={birthCountry} key={index}>{birthCountry}</Option>
})}
</Select>
</Form.Item>
<Form.Item
label="Level"
{...language}
name={[language.name, 'level']}
fieldKey={[language.fieldKey, 'level']}
>
<Select onChange={}>
{birthCountries.map((birthCountry, index) => {
return <Option value={birthCountry} key={index}>{birthCountry}</Option>
})}
</Select>
</Form.Item>
<MinusCircleOutlined
onClick={() => {
remove(language.name);
}}
/>
</Space>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
block
>
<PlusOutlined /> Add another Language
</Button>
</Form.Item>
</div>
);
}}
</Form.List>
</Form>
);
You can see this working
Hope this answer your question and help you. The API is a bit confusing as it is based on a formik way of doing things
Notes: In initialValues, is important that attribute that you use is name in the same way as the Form.List where you want to use the default value

React child state doesn't get updated

I have a parent component that initializes the state using hooks. I pass in the state and setState of the hook into the child, but whenever I update the state in multiple children they update the state that is not the most updated one.
To reproduce problem: when you make a link and write in your info and click submit, it successfully appends to the parent state. If you add another one after that, it also successfully appends to the parent state. But when you go back and press submit on the first link, it destroys the second link for some reason. Please try it out on my codesandbox.
Basically what I want is a button that makes a new form. In each form you can select a social media type like fb, instagram, tiktok, and also input a textfield. These data is stored in the state, and in the end when you click apply changes, I want it to get stored in my database which is firestore. Could you help me fix this? Here is a code sandbox on it.
https://codesandbox.io/s/blissful-fog-oz10p
and here is my code:
Admin.js
import React, { useState } from 'react';
import Button from '#material-ui/core/Button';
import AddNewLink from './AddNewLink';
const Admin = () => {
const [links, setLinks] = useState({});
const [newLink, setNewLink] = useState([]);
const updateLinks = (socialMedia, url) => {
setLinks({
...links,
[socialMedia]: url
})
}
const linkData = {
links,
updateLinks,
}
const applyChanges = () => {
console.log(links);
// firebase.addLinksToUser(links);
}
return (
<>
{newLink ? newLink.map(child => child) : null}
<div className="container-sm">
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
onClick={() => {
setNewLink([ ...newLink, <AddNewLink key={Math.random()} linkData={linkData} /> ])}
}
>
Add new social media
</Button>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
style={{marginTop: '50px'}}
onClick={() => applyChanges()}
>
Apply Changes
</Button>
<h3>{JSON.stringify(links, null, 4)}</h3>
</div>
</>
);
}
export default Admin;
AddNewLink.js
const AddNewLink = props => {
const [socialMedia, setSocialMedia] = useState('');
const [url, setUrl] = useState('');
const { updateLinks } = props.linkData;
const handleSubmit = () => {
updateLinks(socialMedia, url)
}
return (
<>
<FormControl style={{marginTop: '30px', marginLeft: '35px', width: '90%'}}>
<InputLabel>Select Social Media</InputLabel>
<Select
value={socialMedia}
onChange={e => {setSocialMedia(e.target.value)}}
>
<MenuItem value={'facebook'}>Facebook</MenuItem>
<MenuItem value={'instagram'}>Instagram</MenuItem>
<MenuItem value={'tiktok'}>TikTok</MenuItem>
</Select>
</FormControl>
<form noValidate autoComplete="off" style={{marginBottom: '30px', marginLeft: '35px'}}>
<TextField id="standard-basic" label="Enter link" style={{width: '95%'}} onChange={e => {setUrl(e.target.value)}}/>
</form>
<div className="container-sm">
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
style={{marginBottom: '30px'}}
onClick={() => handleSubmit()}
>
Submit
</Button>
</div>
</>
)
}
export default AddNewLink;
All I see is that links in AddNewLink would be a stale closure but in your question you never use it. Here is your code "working" since you didn't describe what it is supposed to do it always "works"
const { useState } = React;
const AddNewLink = (props) => {
const [socialMedia, setSocialMedia] = useState('');
const [url, setUrl] = useState('');
const { updateLinks, links } = props.linkData;
console.log('links is a stale closure:', links);
const handleSubmit = () => {
updateLinks(socialMedia, url);
};
return (
<div>
<select
value={socialMedia}
onChange={(e) => {
setSocialMedia(e.target.value);
}}
>
<option value="">select item</option>
<option value={'facebook'}>Facebook</option>
<option value={'instagram'}>Instagram</option>
<option value={'tiktok'}>TikTok</option>
</select>
<input
type="text"
id="standard-basic"
label="Enter link"
style={{ width: '95%' }}
onChange={(e) => {
setUrl(e.target.value);
}}
/>
<button
type="submit"
variant="contained"
color="primary"
style={{ marginBottom: '30px' }}
onClick={() => handleSubmit()}
>
Submit
</button>
</div>
);
};
const Admin = () => {
const [links, setLinks] = useState({});
const [newLink, setNewLink] = useState([]);
const updateLinks = (socialMedia, url) =>
setLinks({
...links,
[socialMedia]: url,
});
const linkData = {
links,
updateLinks,
};
const applyChanges = () => {
console.log(links);
// firebase.addLinksToUser(links);
};
return (
<React.Fragment>
{newLink ? newLink.map((child) => child) : null}
<div className="container-sm">
<button
type="submit"
variant="contained"
color="primary"
onClick={() => {
setNewLink([
...newLink,
<AddNewLink
key={Math.random()}
linkData={linkData}
/>,
]);
}}
>
Add new social media
</button>
<button
type="submit"
variant="contained"
color="primary"
style={{ marginTop: '50px' }}
onClick={() => applyChanges()}
>
Apply Changes
</button>
<h3>{JSON.stringify(links, null, 4)}</h3>
</div>
</React.Fragment>
);
};
ReactDOM.render(<Admin />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
It is not a good idea to put jsx in local state, save the data in state instead and pass that to the component every render.

Remove asterisk from only one field

I have a custom component that takes in values from an API and then displays them to a user, however within this component I give a 'required' flag to give an asterisk to the label, however I only want one field as seen below to have an asterisk not both as is currently happening.
<Grid item xs={12} sm={6}>
<SearchUsers
name="primaryOfficerId"
label="PO Responsible"
id="primaryOfficerId"
onSelect={change.bind(null, 'primaryOfficerId')}
error={touched.primaryOfficerId && Boolean(errors.primaryOfficerId)}
/>
</Grid>
<Grid item xs={12} sm={6}>
<SearchUsers
name="supportOfficerId"
label="Support Officer"
id="supportOfficerId"
onSelect={change.bind(null, 'supportOfficerId')}
/>
</Grid>
And now my custom component
const Search = (props) => {
const [data, setData] = useState([]);
const [select, setSelect] = useState(0);
const { type: TYPE, name: NAME, label: LABEL, onSelect, filter } = props;
const applyFilter = (data) => {
let result = data;
if (filter) {
result = filter(data);
}
return result;
};
useEffect(() => {
getLookupData(TYPE)
.then((response) => {
setData(response);
})
.catch((error) => {
if (error === HttpStatus.NOT_FOUND) {
setData([]);
} else {
throw error;
}
});
}, [TYPE]);
const options = applyFilter(data).map((item) => (
<MenuItem value={item.id} key={item.id}>
{item[NAME]}
</MenuItem>
));
const handleChange = (event) => {
setSelect(event.target.value);
onSelect && onSelect(event);
};
const { classes } = props;
return (
<FormControl required className={classes.formControl} id={NAME} error={props.error}>
<FormControlLabel control={<InputLabel htmlFor={NAME}>{LABEL}</InputLabel>} />
<Select
name={TYPE}
value={select}
onChange={handleChange}
disabled={props.disabled || options.length === 0}
input={<Input name={TYPE} id={NAME} />}
>
<MenuItem value="">
<em>None</em>
</MenuItem>
{options}
</Select>
</FormControl>
);
};
Below you can see an image of my problem, both PO, and So responsible have an asterisk. I need only PO to have this asterisk but my component does not currently allow for individuals
Simply make your component customizable by passing it a required prop as boolean then in your component make it dynamic :
<FormControl required={props.required}>
// ...
</FormControl>
So now you can use it with an asterisk <SearchUsers required /> or without <SearchUsers required={false} />
Add additional prop required to your Search component and then use it as a prop value for FormControl:
<FormControl required={props.required} />

Categories

Resources