Material-UI Select component with many menu items is slow - Alternative solutions - reactjs

I am trying to make a select element for cities with material-UI. The problem is that I need to have the same design as the Textfields I have above that element. I used the following
<FormControl variant='outlined' className={classes.city}>
<InputLabel>City</InputLabel>
<Select
label='City'
value={city}
onChange={(event) => setCity(event.target.value)}
>
{cities.map((storeCity, key) => <MenuItem key={key} value={storeCity.id}>{storeCity.name}</MenuItem>)}
</Select>
</FormControl>
Before clicking the element
This gives me the perfect visual output and generally works well. The only problem is that it is slow as the cities array contains more than 200 cities. What should I do to have the same visual effect with faster rendering?

Related

MUI Two Object literals in label for checkbox

I am using MUI.
I have checkboxes for which I would like to have a label consisting of two object literals. This is my FormGroup.
<FormGroup>
{data.map((item, index) => {
return (
<FormControlLabel
key={index}
control={<Checkbox />}
// I need {item.title} (item.value) here
label={item.title}
name={item.title}
value={item.title}
onChange={() => handleChange(index)}
disabled={disabledItems[index]}
checked={checkedItems[index]}
color="default"
/>
)
})}
</FormGroup>
My data is as follows:
const data = [{title: 'Something', costs: '1 million'}]
But more of those ;).
I've tried everything I could think of but it seems not to be necessary.
In the end I need a list of checkboxes which shows the name and how much it will cost behind it (e.g. Pizza ($1,50))
Hope somebody knows a solution (or google search option, I cant find anybody else with this issue but maybe I'm using the wrong terminology)
Can't you just use template string?
label={`${item.title} (${item.costs})`}

How to fix Material-UI Select w/ MenuItem where MenuItem being rendered horizontally?

I've been playing with Material-UI with React/Next.js and I'm running across a weird and persistent bug. I can't get the <Select> to render a regular vertical dropdown menu. How do I get the <MenuItem>s to render vertically?
I searched the docs and can't find anything. It's also worth noting my code is pretty much the same as the example:
render (
<div>
<FormControl
fullWidth
style={{
paddingBottom: formError
? `${paddingBeneathFormControls}px`
: `${paddingBeneathFormControls + 22}px`,
}}
>
<InputLabel id="demo-simple-select-label">Age</InputLabel>
<Select
className="test"
labelId="demo-simple-select-label"
label="Age"
value={10}
>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
{formError && (
<FormHelperText error>
Please enter a valid value.
</FormHelperText>
)}
</FormControl>
</div>
)
There may be some unexpected side-effects for others, but I found a solution to my problem. I was using #mui/material library, which I figured was the more modern version - they say NASA, Netflix, Spotify and others use this library. I simply changed my import to #material-ui/core, which exposes the same elements I was using (Select, MenuItem, FormControl, FormHelperText, InputLabel, TextField). I'm not entirely sure where these two libraries differ but in my case simply switching that made all my code work.
It's worth noting that using both adds some conflicting styling behavior - I tried at first to only borrow the Select and MenuItem components from #material-ui/core, but when I imported that library it broke the component styling for #mui/material components.

Create Multiple Select Using Bootstrap Form.Control

I'm trying to create a select using React.Form from React-Bootstrap. I expected something like this(this ss is from react-bootstrap-multiselect):
But I got this kind of result:
This is my code:
<Form.Control
required
as="select"
type="select"
id="instructors"
value={instructors}
onChange={handleChange}
multiple
>
<option hidden value key="blankChoice">
Pilih Instruktur...
</option>
{items
? items.map((item, index) => {
return <option value={item.id}>test{index}</option>;
})
: null}
</Form.Control>
Actually I can just use React-Select library, but I try not using too many libraries, and since I already use React-Bootstrap, it will be take another effort to match the style with another library that I will use.
Thanks!

how to set helperText in react-select

I am using react-select and TextField Material-UI.
Is there possibility to set helperText (small text below component) in react-select like it is made in TextField?
Thank You for help in advance.
P.S. I do not think my question is duplication of this question. The other post is about how to custom component which is a part of react-select, I want to add an option that react-select doesnt have.
TextField is mainly a convenience wrapper around several lower-level components including FormHelperText.
Here is the Autocomplete demo in the Material-UI documentation using react-select: https://material-ui.com/demos/autocomplete/#react-select
Here is a modified version of that demo using FormHelperText: https://codesandbox.io/s/rynvn8po5p
Here's the relevant snippet from that code:
<Select
classes={classes}
styles={selectStyles}
options={suggestions}
components={components}
value={this.state.single}
onChange={this.handleChange("single")}
placeholder="Search a country (start with a)"
isClearable
/>
<FormHelperText>Here's my helper text</FormHelperText>
The Material-UI demos for Select also show many examples of using FormHelperText without using TextField: https://material-ui.com/demos/selects/#simple-select
Here is the API documentation for FormHelperText: https://material-ui.com/api/form-helper-text/
Do you mean placeholder?
I think You can set this way:
const MyComponent = () => (
<Select placeholder="Select..." options={options} />
)
But if you want the same look why do you use controls from different libraries. I think you can use FormHelperText with Select from Material-Ui. So you might as well this select instead of react-select.
<FormControl className={classes.formControl}>
<InputLabel shrink htmlFor="age-native-label-placeholder">
Age
</InputLabel>
<NativeSelect
value={this.state.age}
onChange={this.handleChange('age')}
input={<Input name="age" id="age-native-label-placeholder" />}
>
<option value="">None</option>
<option value={10}>Ten</option>
<option value={20}>Twenty</option>
<option value={30}>Thirty</option>
</NativeSelect>
<FormHelperText>Label + placeholder</FormHelperText>
</FormControl>

Label of Multiple Select is crossed out by the outline of the input field

I made a multiple select list with Material-UI. But when I select an item the label should shrink and fit into the outline of the input field. The problem is the outline stays the same and the label shrinks behind it.
I tried looking for a solution in the Material-UI docs. It seems like there isn't any multiple select list outlined variant. So I wonder if it is because there is no outlined variant of the multiple select list or that it is due to something else.
<FormControl
variant="outlined"
fullWidth
>
<InputLabel
ref={ref => {
this.InputLabelRef = ref;
}}
htmlFor="members"
error={this.props.touched.members && Boolean(this.props.errors.members)}
>
Members
</InputLabel>
<Select
onChange={this.change.bind(null, "members")}
multiple
value={this.state.members}
error={this.props.touched.members && Boolean(this.props.errors.members)}
input={
<OutlinedInput
labelWidth={0}
name="members"
id="members"
/>
}
>
<MenuItem value={'Baspa'}>Baspa</MenuItem>
<MenuItem value={'Plorky'}>Plorky</MenuItem>
<MenuItem value={'Rizzels'}>Rizzels</MenuItem>
</Select>
I also made a CodeSandBox:
https://codesandbox.io/s/jnlx1vky39
This is how it looks like:
https://imgur.com/a/Wpf7OE0
You were missing a couple pieces that are shown in the documentation that allow the outline to know the label width:
componentDidMount() {
this.setState({
labelWidth: ReactDOM.findDOMNode(this.InputLabelRef).offsetWidth
});
}
...
<OutlinedInput labelWidth={this.state.labelWidth} name="members" id="members" />
Here's the full code:
The original answer is no longer correct. According to this resolved MUI issue, labelWidth is no longer supported. Instead, set the label on the <OutlinedInput> to match the label on the <InputLabel>. Ex:
<InputLabel id="foo">{tag}</InputLabel>
<Select
input={<OutlinedInput label={tag} />}
Full example in the MUI Docs

Resources