How to add only single value from Autocomplete in Material UI? - reactjs

I have an Autocomplete component for adding country calling code, but, the relevant country is added too with it. Like when clicked on Autocomplete drop-down list, all the countries and its specific codes are displayed. My intention is to add only the country code. See the code below for reference
const [countryData, setCountryData] = useState({});
const [newValue, setNewValue] = useState("");
useEffect(() => {
setCountryData(codes);
}, []);
<Autocomplete
id="size-small-standard"
size="small"
options={cities}
onChange={(event, value) => setNewValue(value)}
autoSelect={true}
getOptionLabel={(option) =>
option.country + " " + ` +` + option.calling_code {/* <-- How to display only calling code, but, should show both country name and calling code in drop down */}
}
defaultValue={cities[98]}
style={{ width: "100%" }}
renderInput={(params) => (
<TextField
{...params}
variant="standard"
placeholder="Search your country"
style={{ width: "40%" }}
/>
)}
/>
What would be best possible solution?
Following is the CodeSandbox link: https://codesandbox.io/s/material-demo-forked-3ljj2

You can change your getOptionLabel to show only the phone prefix and then use renderOption to show the name with the country's phone prefix
return (
<div className={classes.root}>
<Autocomplete
id="size-small-standard"
size="small"
options={cities}
onChange={(event, value) => setNewValue(value)}
autoSelect={true}
getOptionLabel={(option) => `+ ${option.calling_code}`}
renderOption={(option) => (
<>{`${option.country} + ${option.calling_code}`}</>
)}
defaultValue={cities[98]}
style={{ width: "100%" }}
renderInput={(params) => (
<TextField
{...params}
variant="standard"
placeholder="Search your country"
style={{ width: "40%" }}
/>
)}
/>
</div>
);
Live Demo
UPDATE:
Here is a better example, where you can still search for the country.
Live Demo

Related

How to set default value in Autocomplete Material UI?

In a React project, I have an Autocomplete component which has country name and its relevant calling codes displayed in drop-down list. When selected on list renders the desired data, but, when refreshed, data is null and doesn't show the default data.
const [newValue, setNewValue] = useState({});
const [textToggle, textToggleState] = useState(false);
render(
<div
style={{ cursor: "pointer" }}
onClick={() => {
textToggleState(!textToggle);
}}
>
<h5>+{newValue == null ? "91" : newValue.calling_code}</h5> {/* <-- Value gets null when refreshed */}
</div>
{textToggle ? (
<Autocomplete
id="size-small-standard"
size="small"
options={cities}
onChange={(event, value) => {
setNewValue(value);
textToggleState(!textToggle);
}}
autoSelect={true}
getOptionLabel={(option) =>
`${option.country}` + `+ ${option.calling_code}`
}
renderOption={(option) => (
<>{`${option.country} + ${option.calling_code}`}</>
)}
//defaultValue={cities[98]}
style={{ width: "100%" }}
renderInput={(params) => (
<TextField
{...params}
variant="standard"
placeholder="Search your country"
style={{ width: "40%" }}
/>
)}
/>
) : (
""
)}
)
Following is the CodeSandbox link: https://codesandbox.io/s/how-to-add-only-single-value-from-autocomplete-in-material-ui-forked-tu218
You can pass a value prop to autocomplete component with the newValue. But newValue is an empty object by default that doesn't exist in the options array you are passing to the autocomplete so it will show undefined + undefined in the default case. You can make that null and add null check there in the autocomplete itself or you can assign a value directly in your useState So as you are having a check for null and using 91 code so instead you can assign that value to the newValue itself directly. Check the code below I have added the value field here
<Autocomplete
id="size-small-standard"
size="small"
options={cities}
value={newValue !== null ? newValue : cities[98]}
onChange={(event, value) => {
setNewValue(value);
textToggleState(!textToggle);
}}
autoSelect={true}
getOptionLabel={(option) =>
`${option.country}` + `+ ${option.calling_code}`
}
renderOption={(option) => (
<>{`${option.country} + ${option.calling_code}`}</>
)}
//defaultValue={cities[98]}
style={{ width: "100%" }}
renderInput={(params) => (
<TextField
{...params}
variant="standard"
placeholder="Search your country"
style={{ width: "40%" }}
/>
)}
/>
Or you can just pass newValue to the value field and assign the default value in the newValue useState as shown below
const [newValue, setNewValue] = useState(cities[98]);
.
.
.
.
<Autocomplete
id="size-small-standard"
size="small"
options={cities}
value={newValue}
onChange={(event, value) => {
setNewValue(value);
textToggleState(!textToggle);
}}
autoSelect={true}
getOptionLabel={(option) =>
`${option.country}` + `+ ${option.calling_code}`
}
renderOption={(option) => (
<>{`${option.country} + ${option.calling_code}`}</>
)}
//defaultValue={cities[98]}
style={{ width: "100%" }}
renderInput={(params) => (
<TextField
{...params}
variant="standard"
placeholder="Search your country"
style={{ width: "40%" }}
/>
)}
/>

How can I set the placeholder of Autocomplete in a new line?

I'm using Autocomplete of material-ui and I have the list of the selected values and the placeholder in the same area. I would like to set the placeholder in a new line. I'm able to change the style of placeholder using makeStyles but I didn't find a way to going in a new line.
const useStyles = makeStyles ({
placeholder: {
"& input::placeholder": {
display: "block",
},
})
renderInput={(params) => (
<TextField
/* eslint-disable react/jsx-props-no-spreading */
{...params}
classes={{root: classes.placeholder}}
label="Selected Options"
placeholder="Availables Options"
variant="outlined"
color="primary"
/>
)
You can override the renderTags method, add a wrapper component around all selected tags, and set the wrapper width to 100% to push the placeholder element down like this:
<Autocomplete
multiple
options={top100Films.map((option) => option.title)}
renderTags={(value: string[], getTagProps) => (
<div style={{ width: "100%" }}>
{value.map((option: string, index: number) => (
<Chip
variant="outlined"
label={option}
{...getTagProps({ index })}
/>
))}
</div>
)}
renderInput={(params) => <TextField {...params} />}
/>
Live Demo

How to open the dropdown list in Autocomplete Material-UI by default?

In an Autocomplete Form, the data for country and its relevant codes are displayed. When the input text is focused the drop-down list is populated. My intention is to pre load array of data without focus requirement. See the code for example
const [newValue, setNewValue] = useState(null);
const [textToggle, textToggleState] = useState(false);
render(
<div
style={{ cursor: "pointer" }}
onClick={() => {
textToggleState(!textToggle);
}}
>
<h5>+{newValue == null ? "91" : newValue.calling_code}</h5>
</div>
{textToggle ? (
<Autocomplete
id="size-small-standard"
size="small"
options={cities}
onChange={(event, value) => {
setNewValue(value);
textToggleState(!textToggle);
}}
autoSelect={true}
getOptionLabel={(option) =>
`${option.country}` + `+ ${option.calling_code}`
}
renderOption={(option) => (
<>{`${option.country} + ${option.calling_code}`}</>
)}
//defaultValue={cities[98]}
style={{ width: "100%" }}
renderInput={(params) => (
<TextField
{...params}
variant="standard"
placeholder="Search your country"
style={{ width: "40%" }}
/>
)}
/>
) : (
""
)}
</div>
)
Here you can see data is displayed on input text focus. What could be the best possible solution to
pre-load data?
CodeSandbox Link: https://codesandbox.io/s/how-to-add-only-single-value-from-autocomplete-in-material-ui-forked-tu218
Just take control of the open state of the Autocomplete and set the default value to true:
export default function ComboBox() {
// default value to true to open at first render
const [open, setOpen] = useState(true);
return (
<Autocomplete
open={open}
onOpen={() => setOpen(true)}
onClose={() => setOpen(false)}
options={top100Films}
getOptionLabel={(option) => option.title}
renderInput={(params) => (
<TextField {...params} label="Combo box" variant="outlined" />
)}
/>
);
}
Live Demo
I think what you need is to use AutoComplete as Combobox.
<Autocomplete
id="combo-box-demo"
options={top100Films}
getOptionLabel={(option) => option.title}
style={{ width: 300 }}
renderInput={(params) => <TextField {...params} label="Combo box" variant="outlined" />}
/>
This will pre-populate it.
Visit this: https://material-ui.com/components/autocomplete/#combo-box
Hope it helps. if not, please elaborate your question if you want something else.

How to add onClick event on the options in Autocomplete Component(Material UI)?

How is possible to add onClick event on the options - i mean when u click the selected option i want to link somewhere, not to just put in the searchField(or textField)? I search really hard on the web, but i just cant find how to do that.
<Autocomplete
freeSolo
classes={classes}
options={searchItems}
getOptionLabel={(option) =>
option.title ? option.title : option.name
}
style={{ width: 300, borderRight: "none", borderLeft: "none" }}
renderInput={(params) => {
return (
<TextField
{...params}
variant="outlined"
fullWidth
placeholder="Search for movie, tv or person"
value={value}
onChange={(e) => handleChange(e)}
/>
);
}}
/>
You need to move the onChange function inside the Autocomplete component as below:
<Autocomplete
id="combo-box-demo"
classes={classes}
options={searchItems}
getOptionLabel={(option) =>
option.title ? option.title : option.name
}
style={{ width: 300, borderRight: "none", borderLeft: "none" }}
onChange={(e, value) => console.log(e.target, value.title)}
renderInput={(params) => (
<TextField {...params} label="Combo box" variant="outlined" />
)}
/>
Here is an example that I have created. When the onChange function in the Autocomplete component is triggered, it displays values on the console. According to the doc, onchange function here pass three props called event, value and reason.

How can I change the way of selecting in a checkbox?

I'm using react and I have a checkbox created with Autocomplete where I select items. It
is the same as that provided by material:
The problem is that the function "OnChange" runs only if I select the square.
I would like it to work also by selecting the row. How can I do it? Here's my code:
<AutoComplete
multiple
id="checkboxes-tags-demo"
options={props.roles}
// disableCloseOnSelect
// getOptionLabel={(options) => `${options}`}
renderOption={(options, { selected }) => (
<React.Fragment>
<Checkbox
icon={icon}
checkedIcon={checkedIcon}
style={{ marginRight: 20 }}
value={options}
checked={selected}
onChange={updateNewRoles}
/>
{options}
</React.Fragment>
)}
style={{ width: 500 }}
renderInput={(params) => (
<TextField
{...params}
variant="outlined"
label=""
placeholder="Available Roles"
/>
)}
/>
<button type="submit" onClick={onSubmitChecked}>
Save
</button>
This is a photo of the example provided by material. The functions are performed only by clicking the icon and not the line:

Resources