stopPropogation not working consistently in React - reactjs

I am working with 2 dropdown menus using stopPropogation to prevent the menu shifting up and down when items are checked and unchecked.
One menu works great but the other is still jumping up and down when checking and unchecking items, although I am confident that I'm using stopPropogation in the same way for both instances. I am wondering what I am doing wrong in the faulty dropdown menu that's causing this issue.
Working dropdown menu:
return (
<div onClick={(e) => {
e.stopPropagation();
}}>
<FormControl
variant="outlined"
size="small"
className={classes.formControl}
>
<InputLabel id="demo-mutiple-checkbox-label" align="left" margin="dense">
Select Models
</InputLabel>
<Select
multiple
labelId="demo-mutiple-checkbox-label"
label="SelectModels"
value={modelIds}
onChange={handleChange}
renderValue={(selected) =>
selected
.map(
(id) =>
deviceModelData.find((model) => model.alg_id === id).alg_name
)
.join(', ')
}
MenuProps={MenuProps}
className={classes.rootSelect}
>
{deviceModelData.map((model, index) => (
<MenuItem key={model.alg_id} value={model.alg_id}>
<Checkbox checked={modelIds.includes(model.alg_id)} />
<ListItemText primary={model.alg_name} />
</MenuItem>
))}
</Select>
</FormControl>
</div>
);
}
Problematic dropdown menu:
return (
<div
onClick={(e) => {
e.stopPropagation();
}}
>
<FormControl
variant="outlined"
size="small"
className={classes.formControl}
>
<InputLabel id="demo-mutiple-checkbox-label">Select Classes</InputLabel>
<Select
labelId="demo-mutiple-checkbox-label"
label={label}
id="demo-mutiple-checkbox"
multiple
value={classIds}
onChange={handleClassIdsChange}
renderValue={(selected) =>
selected
.map((id) => marketplaceModelClasses[id].original_label)
.join(', ')
}
MenuProps={MenuProps}
>
{allClassIds.map((classId) => {
return (
<MenuItem key={classId} value={classId}>
<Checkbox
value={classId}
checked={classIds.indexOf(classId) > -1}
/>
<ListItemText
primary={marketplaceModelClasses[classId].original_label}
/>
</MenuItem>
);
})}
</Select>
</FormControl>
</div>
);
}

Related

React Menu is closing on element click

I have a menu which applies filter to my list and when I click on an element inside the menu is closing and I can not set more filters. I should click the stepper or the selection box many times and the menu should close on click on submit or cancel and not on click of stepper or selection box
`
<Menu matchWidth={true} isOpen={isOpen} onOpen={handleOpen} onClose={handleCancel} closeOnBlur={false} closeOnSelect={false} >
<ChakraSelectButton headline={'Who?'} information={information} />
<MenuList p={4} onClick={e => e.stopPropagation()} >
<VStack
alignItems={'flex-start'}
// #ts-ignore
ref={ref}
<Stepper
title={'How many people?'}
handleChange={handleChange}
name={people}
value={numberOfPeople ? numberOfPeople : 0}
boxSize={10}
/>
{numberOfPeople > 0 && (
<VStack w={'100%'} onClick={e => e.preventDefault()}>
<Text
alignSelf={'flex-start'}
Please insert the age!
</Text>
{Array.from(Array(numberOfPeople)).map((a, idx) => {
return (
<Select
key={idx}
userSelect={'none'}>
<option value={24}>24</option>
<option value={25}>25</option>
<option value={26}>26</option>
<option value={27}>27</option>
</Select>
);
})}
</VStack>
)}
<Stepper
title={'Pets'}
handleChange={handleChange}
value={numberOfPets ? numberOfPets : 0}
boxSize={10}
/>
<Divider />
<CtaFilterButtons
size={'sm'}
handleCancel={handleCancel}
handleFilterChange={handleSubmit}
/>
</VStack>
</MenuList>
</Menu>
`
I only want to close the menu when I click on submit.

Getting the same value for dropwown on Oncahange event on react

The below image shows duplicate value getting in two drop down i need to manage the
drop down one by one dynamically on add button click.My requirement is I have need to add multiple experience using the add button.
I have calling a function to createExpDetails() to add the section dynamically when plus button is clicked.The value filled in the drop down is getting from database .The present issue is I am getting the drop downs but when one value in one dropdown is changed it automatically reflects to all the other dropdowns. I need to change the values in dropdown seperately.
const [addfiledexp,setFildExp]=useState('')
const handleChangeexp= (event:SelectChangeEvent,i) =>
{
setFildExp(event.target.value);
}
const createExpDetails=() =>
{
return(addexplist.map((el,i) =>
<div key={i}>
<Box mt={4}>
<Grid container >
<Grid item xs={5} mb={2} mr={8} ml={4}>
<TextField
name='title'
id="title"
variant='outlined'
fullWidth
label="Title"
//value={address}
//onChange={(e: any) => setAddress(e.target.value)}
/>
</Grid>
<Grid item xs={5} mb={2} ml={4}>
<TextField
name='helorganisation'
id="helorganisation"
variant='outlined'
fullWidth
label="Health Care Organization"
// value={address}
//onChange={(e: any) => setAddress(e.target.value)}
/>
</Grid>
<Grid container>
<Grid item xs={5} mb={2} mr={8} ml={4}>
<FormControl fullWidth>
<InputLabel id="demo-simple-select-label">Type</InputLabel>
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
name='typeselect'
//value= {console.log(addfiledexp)}
value= {addfiledexp}
label="Type"
//onChange={handleChangeexp }
onChange={(e: any) => handleChangeexp(e,i)}
>
{addexptypelist.map((typelist, key) => {
return (<MenuItem value= {typelist.name} ><option key={key} >{typelist.name}</option></MenuItem>);
})}
</Select>
</FormControl>
</Select>
</FormControl>
</Grid>
</Grid>
variant='outlined'
{ addexplist.length >1 && (
<Button className="section-add-button" onClick={()=>handleServiceexpRemove(i)}><CancelIcon className="section-add-icon" /></Button>
)
}
</Box>
</div>
));
}
{createExpDetails()}
<Button className="section-add-button" onClick={() =>addbutton('addexperiance')}><AddCircleIcon className="section-add-icon" /></Button>

Reset values in react hook forms with fields loaded in map

So i have a form that has dropdowns for companies and as many companies they are i want the values to be loaded in there. I know how to do it if its not in a map.
customerCompanyList.map(cList => {
return (
<Controller
name={`customerCompany-${cList.id}`}
control={control}
render={({ field }) => (
<FormControl
variant="outlined"
className="mt-16"
>
<InputLabel id="customerCompany-type-label">
Customer Company
</InputLabel>
<Select
labelId="customerCompany-type-label"
id="customerCompany"
label="Customer Company"
{...field}
fullWidth
>
<MenuItem value="">
<em>None</em>
</MenuItem>
{companyList.map(item => {
return (
<MenuItem key={item.id} value={item.id}>
{item.name}
</MenuItem>
);
})}
</Select>
{errors?.type?.customerCompany && (
<FormHelperText>
{errors.type.customerCompany}
</FormHelperText>
)}
</FormControl>
)}
/>
);
})
What im stuck is how do i reset the values
im using useEffect to reset the values for the ones that are not in a map. but this one i cant figure out
reset({
isCustomer: customerCompanies.length > 0,
isResource: resourceCompanies.length > 0,
isStaff: roles.length > 0,
staffRoles: roles.length > 0 ? roles : null
});

Material UI select and autocomplete box not lined up

Screenshot of misaligned drop-down boxes
Hi! I'm a beginner ReactJS engineer. I added 2 drop-down boxes from material UI, the left box is the Autocomplete from materialui/labs and the right box is the Select from materialui/core. They're both placed in the same component with the same styling applied to it, but the Autocomplete is slightly off. Is there a simple fix to this misalignment?
<AutocompleteComponent
formStyle={{ width: 200 }}
label={'Build'}
options={builds}
value={selectedBuild}
handleChange={handleFilterSelectChange('selectedBuild')} />
<SelectComponent
formStyle={{ width: 120 }}
label={'Sheet Layout'}
options={sheetLayouts}
value={selectedSheetLayout}
handleChange={handleFilterSelectChange('selectedSheetLayout')} />
For select component:
const SelectComponent = props => {
return (
<FormControl
className={className}
required={required}
error={error}
margin={margin}
style={formStyle}
>
<InputLabel>{label}</InputLabel>
<Select
inputRef={inputRef}
value={value}
style={style}
onChange={handleChange}
disabled={disabled}
onClick={onClick}
onFocus={onFocus}
onBlur={onBlur}
>
{excludeNone ? null : (
<MenuItem value="">
<em>{noneLabel ? noneLabel : "None"}</em>
</MenuItem>
)}
{optionsExist(options)}
</Select>
{helperText ? <FormHelperText>{helperText}</FormHelperText> : null}
</FormControl>
);
};
For the autocomplete component:
class AutocompleteComponent extends React.Component {
render() {
return (
<FormControl
className={className}
required={required}
error={error}
margin={margin}
style={formStyle}
>
<Autocomplete
style={style}
disabled={disabled}
onClick={onClick}
onFocus={onFocus}
onBlur={onBlur}
options={options}
getOptionLabel= {option => option.label && option.label.toString()}
id="auto-complete"
autoComplete
includeInputInList
renderInput={params => (
<TextField
{...params}
label="Builds"
margin="normal"
fullWidth
position="center"
/>
)}
renderOption={(option, { inputValue }) => {
const matches = match(option.label, inputValue);
const parts = parse(option.label, matches);
return (
<div>
{parts.map((part, index) => (
<span
key={index}
style={{ fontWeight: part.highlight ? 700 : 400 }}
>
{part.text}
</span>
))}
</div>
);
}}
/>
{helperText ? <FormHelperText>{helperText}</FormHelperText> : null}
</FormControl>
);
}
}
Thanks!

How to show an inputlabel/placeholder/label permanently?

I'm using the multi-select with checkboxes from material ui v4. The provided default settings display an array of 'SELECTED' values. renderValue={selected => selected.join(', ')}. However, I would like to remove this function and only display a permanent label. It seems that the display value is being tied to the value of the component itself. Does anybody knows how to work around this?
<FormControl className={classes.formControl}>
<InputLabel htmlFor="select-multiple-checkbox">Tag</InputLabel>
<Select
multiple
value={personName}
onChange={handleChange}
input={<Input id="select-multiple-checkbox" />}
renderValue={selected => selected.join(', ')}
MenuProps={MenuProps}
>
{names.map(name => (
<MenuItem key={name} value={name}>
<Checkbox checked={personName.indexOf(name) > -1} />
<ListItemText primary={name} />
</MenuItem>
))}
</Select>
</FormControl>
Are you saying that you don't want any indication of what the selected values are?
If so, below is one way of doing that:
<FormControl className={classes.formControl}>
<InputLabel shrink={false} htmlFor="select-multiple-checkbox">
Tag
</InputLabel>
<Select
multiple
value={personName}
onChange={handleChange}
input={<Input id="select-multiple-checkbox" />}
renderValue={() => (
<span dangerouslySetInnerHTML={{ __html: "​" }} />
)}
MenuProps={MenuProps}
>
{names.map(name => (
<MenuItem key={name} value={name}>
<Checkbox checked={personName.indexOf(name) > -1} />
<ListItemText primary={name} />
</MenuItem>
))}
</Select>
</FormControl>
<InputLabel shrink={false}
This prevents the label from shrinking and moving up when the Select is focused.
renderValue={() => (<span dangerouslySetInnerHTML={{ __html: "​" }} />)}
This causes a zero-width space to be rendered as the "selected values". This ensures that the height doesn't collapse (which is what happens if you just return empty string) while still allowing the label to be displayed.

Resources