How to show an inputlabel/placeholder/label permanently? - reactjs

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.

Related

stopPropogation not working consistently in React

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>
);
}

Warning: Failed prop type: Invalid prop `children` supplied to `ForwardRef(Select)`, expected a ReactNode

I'm trying to render certain inputs if a variable is true but when the component render displays the warning Warning: Failed prop type: Invalid prop `children` supplied to `ForwardRef(Select)`, expected a ReactNode.
Here is the code of the Material-ui Dialog which receive some props, one of them is the one that I validate to show or not a pair of select inputs.
What I'm doing is validate if the variable is true, show them if not, don't show them.
states...
requests...
onSubmit...
return (
<Box component="form" onSubmit={handleSubmit} sx={{ mt: 1 }}>
<Collapse in={open}>
<Alert severity={severity}>{alertMsg}</Alert>
</Collapse>
<DialogTitle>Proceso de factura.</DialogTitle>
<DialogContent>
<Container>
<TextField
autoFocus
margin="dense"
id="vus"
name="vus"
label="Valor unitario de servicio."
fullWidth
variant="outlined"
onChange={handleChange}
value={vus}
/>
<TextField
margin="dense"
id="discount"
name="discount"
label="Descuento"
fullWidth
variant="outlined"
onChange={handleChange}
value={discount}
/>
<TextField
margin="dense"
id="paymentMeth"
name="paymentMeth"
label="Método de pago"
fullWidth
variant="outlined"
onChange={handleChange}
value={paymentMeth}
/>
<TextField
margin="dense"
id="payment"
name="payment"
label="Forma de pago"
fullWidth
variant="outlined"
onChange={handleChange}
value={payment}
/>
{requiresCCP ? (
<>
<Box className={classes.formInputs}>
<FormControl fullWidth>
<InputLabel id="select-vehicle">
Vehículo
</InputLabel>
<Select
labelId="select-vehicle"
id="vehicleSelect"
name="vehicleSelect"
value={vehicle}
label="Vehículo"
onChange={handleChange}
>
{allVehicles.map((vehicle, index) => {
return (
<MenuItem
value={vehicle._id}
key={index}
>
{vehicle.PlateNumber} -{" "}
{vehicle.VehicleName} Modelo{" "}
{vehicle.Model}
</MenuItem>
);
})}
</Select>
</FormControl>
</Box>
<Box className={classes.formInputs}>
<FormControl fullWidth>
<InputLabel id="select-contact">
Contacto
</InputLabel>
<Select
labelId="select-contact"
id="contactSelect"
name="contactSelect"
value={contact}
label="Contacto"
onChange={handleChange}
>
value={contact}
onChange={handleChange}
{allContacts.map((contact, index) => {
return (
<MenuItem
value={contact._id}
key={index}
>
{contact.LastNameFather}{" "}
{contact.LastNameMother}{" "}
{contact.FirstName} -{" "}
{contact.OfficialNumber}
</MenuItem>
);
})}
</Select>
</FormControl>
</Box>
</>
) : (
""
)}
</Container>
</DialogContent>
<DialogActions>
<Button onClick={handleClose}>Cancelar</Button>
<Button variant="contained" type="submit">
Completar viaje
</Button>
</DialogActions>
</Box>
);
};```
Children you are passing inside the sectect element is incorrect. Just remove value and onchange from its children as you are already passing them as props
<Select
labelId="select-contact"
id="contactSelect"
name="contactSelect"
value={contact}
label="Contacto"
onChange={handleChange}
>
{allContacts.map((contact, index) => {
return (
<MenuItem
value={contact._id}
key={index}
>
{contact.LastNameFather}{" "}
{contact.LastNameMother}{" "}
{contact.FirstName} -{" "}
{contact.OfficialNumber}
</MenuItem>
);
})}
</Select>
If you are working with dates and passing them down as {item.date}
then instead use {item.date.toLocaleDateString()} or {item.date.toString()}
{item.date.toLocaleDateString()} or {item.date.toString()} - This worked for me
<Select
labelId="select-contact"
id="contactSelect"
name="contactSelect"
value={contact}
label="Contacto"
onChange={handleChange}
{allContacts.map((contact, index) => {
return (
<MenuItem
value={contact._id}
key={index}
>
{contact.LastNameFather.toString()}{" "}
{contact.LastNameMother.toString()}{" "}
{contact.FirstName.toString()} -{" "}
{contact.OfficialNumber.toString()}
</MenuItem>
);
})}
Just add toString()

React JSX - inject br tag in loop

How can I add a tag between selected options in jsx?
<Select
labelId="demo-mutiple-checkbox-label"
id="demo-mutiple-checkbox"
multiple
value={preferences}
onChange={handleChangePreferences}
input={<Input />}
renderValue={(selected) => selected.join(<br />)}
// MenuProps={MenuProps}
style={{width: "100%", whiteSpace: "break-spaces"}}
>
I've tried br , \n, "\n" - i can't find a way that works.
The Material UI docs show an example with a comma - I'm trying to use a br
Update the Select component to this. E.g https://codesandbox.io/s/material-demo-40jg3
<Select
labelId="demo-mutiple-checkbox-label"
id="demo-mutiple-checkbox"
multiple
value={personName}
onChange={handleChange}
input={<Input />}
renderValue={selected => (
<>
{selected.map(value => (
<>
{value}
<br />
</>
))}
</>
)}
MenuProps={MenuProps}
>

variant="filled" does not work on <Select multiple>

I don't know why the style is not applied.
Can anyone solve this problem?
<FormControl className={classes.formControl} variant="filled">
<InputLabel id="input-label">Multiple Select</InputLabel>
<Select
variant="filled"
fullWidth={true}
labelId="input-label"
multiple
value={value}
onChange={event => setValue(event.target.value)}
input={<Input />}
renderValue={() => value.join(", ")}
>
<MenuItem value="AAAAA">
<Checkbox checked={value.indexOf("AAAAA") !== -1} />
<ListItemText primary="AAAAA" />
</MenuItem>
<MenuItem value="BBBBB">
<Checkbox checked={value.indexOf("BBBBB") !== -1} />
<ListItemText primary="BBBBB" />
</MenuItem>
<MenuItem value="CCCCC">
<Checkbox checked={value.indexOf("CCCCC") !== -1} />
<ListItemText primary="CCCCC" />
</MenuItem>
</Select>
</FormControl>
Full Code:
https://codesandbox.io/s/select-multiple-tags-variant-filled-hc9y7
Who can help I thank!
Instead of adding the variant to the FormControl, use mui's <OutlinedInput /> component and not the <Input /> component for the input prop on Select
<Select
variant="filled"
fullWidth={true}
labelId="input-label"
multiple
value={value}
onChange={event => setValue(event.target.value)}
input={<OutlinedInput />}
renderValue={() => value.join(", ")}
>
I had the same issue and I got around using the AutoComplete component (albeit it is only in the lab section of Material UI): https://material-ui.com/components/autocomplete/
Hope that works out for you.

Add element inside TextField component - Material UI

I want to create input element which will have select property but also to be able to write custom text in it. I'm using React and Material-UI.
Is it possible to add element inside TextField component (inside div just below input) in Material-UI.
Currently:
Usluga
grupni
Pos
....
With added element:
<div class="MuiFormControl-root-142 ...>
<label class="MuiFormLabel-root-151 ...>Usluga</label>
<div class="MuiInput-root-156 ...>
<input aria-invalid="false" ... list="services" value="">
<datalist id="services">
<li tabindex="-1" ...>grupni<span class="MuiTouchRipple-root-82"></span>
</li>
<li tabindex="-1" ...>Pos<span class="MuiTouchRipple-root-82"></span>
</li>
....
</div>
</div>
React currently:
<TextField
id="service"
label="Usluga"
className={classes.textField}
margin="normal"
onChange={handleChange}
inputProps={{
list: "services"
}}
/>
<datalist id="services">
{
services.map(option => (
<MenuItem key={option.id} value={option.service}>
{ option.service }
</MenuItem>
))
}
</datalist>
If that's not possible, what is the other way to make this?
You can try this method, it worked for me :)
<TextField
required
id='password'
label='Password'
onChange={handleOnChange}
type={toggle.passwordVisibility ? 'text' : 'password'}
InputProps={{
endAdornment: (
<InputAdornment position='end'>
<IconButton
aria-label='toggle password visibility'
onClick={handlePasswordVisibility}
onMouseDown={handleMouseDownPassword}>
{toggle.passwordVisibility && <Visibility />}
{!toggle.passwordVisibility && <VisibilityOff />}
</IconButton>
</InputAdornment>
),
}}
/>
You can do it this way: InputProps={{ endAdornment: <YourComponent /> }}
https://material-ui.com/api/input/
You can try this method, it worked for me :)
<TextField
variant="outlined"
name="rfc"
size={'small'}
label="RFC"
InputProps={{
endAdornment: (
<datalist id="rfc">
<option value="XAXX010101000"></option>
<option value="XEXX010101000"></option>
</datalist>
),
inputProps: {
list: "rfc"
}
}}
/>

Resources