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

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:

Related

Material ui Autocomplete endInputAdornment custom elements not centered

When setting material ui <Autocomplete /> with variant='filled' The endInputAdornments does not center to the AutoComplete.
Codesandbox with both variants for reference here
<Autocomplete
disablePortal
id="combo-box-demo"
options={top100Films}
sx={{ width: 300, mt: 2 }}
renderInput={(params) => (
<TextField
{...params}
label="Movie"
variant="filled" //With filled it does not center anymore
InputProps={{
...params.InputProps,
endAdornment: (
<React.Fragment>
{params.InputProps.endAdornment}
<IconButton
color="primary"
aria-label="upload picture"
component="span"
>
<PhotoCamera />
</IconButton>
</React.Fragment>
)
}}
/>
I found a github issue where they fixed it for the inputProps internally but I cant seem to find a way to do the same with my own adornment elements.
The only prop that seems relevant is popupIcon but i still want that default feature. I just want to be able to add more IconButtons to the endInputAdornments
You can style the container for the icon by using a <div> instead of <React.Fragment>:
endAdornment: (
<div style={{ marginTop: "-19px" }}>
{params.InputProps.endAdornment}
<IconButton
color="primary"
aria-label="upload picture"
component="div"
>
<PhotoCamera />
</IconButton>
</div>
)
Here's the sandbox link
Why -19px? Because with variant="filled" the container for the text and icon is shifted down by 19px:
The popup icon of Autocomplete is vertically centered because of this styles. You can add your own styles to center the icon next to it by modifying the styles from the source a bit:
<Autocomplete
options={top100Films}
renderInput={(params) => (
<TextField
{...params}
label="Movie"
variant="filled"
InputProps={{
...params.InputProps,
sx: {
// this is necessary if you don't want to input value to be
// placed under the icon at the end
'&&&': { pr: '70px' },
},
endAdornment: (
<React.Fragment>
{params.InputProps.endAdornment}
<IconButton
color="primary"
sx={{
position: 'absolute',
p: 0,
right: 40,
top: 'calc(50% - 12px)', // Center vertically
}}
>
<PhotoCamera />
</IconButton>
</React.Fragment>
),
}}
/>
)}
/>

How to remove the second x button, the left one inside a TextField inside a Autocomplete?

I have a search bar that uses Autocomplete from material ui to provide suggestions, and inside of it i have text field where I take text as input.
The only problem is that when i type anything in the TextField I can see 2 clear buttons (x button) one on the left of the loading screen and one on the right, and when the loading screen disappears i get 2 clear buttons next to each other. I want to remove the one on the left as it looks bad, and I don't know why it's there.
Search.jsx:
<div className={searchClasses.search}>
<Autocomplete
options={isEmpty ? [] : suggestionsList}
freeSolo
style={{width: "100%"}}
getOptionLabel={(option) => option.title}
renderInput={(params) => (
<TextField
{...params}
variant="outlined"
margin="normal"
required
fullWidth
autoFocus
loading={loading}
style={{margin: 0}}
classes={{ notchedOutline: classes.input }}
onChange={handleOnChange}
onKeyDown={e => handleKeyDown(e)}
placeholder="Search..."
type="search"
InputProps={{
...params.InputProps,
startAdornment: (
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
),
endAdornment: (
<React.Fragment>
{loading ? <CircularProgress color="inherit" size={20} /> : null}
{params.InputProps.endAdornment}
</React.Fragment>
),
classes: { notchedOutline: classes.noBorder }
}}
/>
)}
renderOption={(option, { inputValue }) => {
const matches = match(option.title, inputValue);
const parts = parse(option.title, matches);
return (
<div>
{parts.map((part, index) => (
<span
key={index}
style={{ fontWeight: part.highlight ? 700 : 400 }}
>
{part.text}
</span>
))}
</div>
);
}}
/>
</div>
Solution
Create a new CSS stylesheet (let say styles.css) and add the following code:
input[type="search"]::-webkit-search-cancel-button {
-webkit-appearance: none;
}
Next, import this stylesheet at the beginning of your Search.jsx:
import "./styles.css";
/* Your code here ... */
Explanation
The left "X" cancel button is present because Webkit-based browsers such as Chrome and Safari automatically adds the cancel button to all <input type="search"> elements. Since your TextField element has the prop type="search", it renders <input type="search"> to the screen and hence your browser automatically adds the "X" button.
The default "X" button can be selected using the ::-webkit-search-cancel-button psuedo-element selector. In our style.css, we select all default "X" buttons in all <input type="search"> elements and we hide them using -webkit-appearance: none;

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

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

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.

Search button to activate autocomplete googl maps places (React.js)

I am using AutoComplete button from material/ui for searching Google Maps Places. Everything is working properly so when user clicks on the one offered field in autocomplete it leads him to next page.
My question is: is it possible to add search button to active autocomplete if user clicks on button?
Here is code for autocomplete and I have added button but still nothing happens if someone clicks on it.
<div className="search">
<Autocomplete
id="google-map-demo"
key={reset}
ListboxProps={{ style: { maxHeight: 400, overflow: 'auto',fontSize:'0.7rem' } }}
getOptionLabel={(option) =>
typeof option === "string" ? option : option.description
}
filterOptions={(x) => x}
options={options}
onChange={(e, l) => {
customer.setMyaddress(l.description);
getMyDestination(l.place_id);
}}
renderInput={(params) => (
<TextField
{...params}
className={classes.root}
variant="standard"
fullWidth
onChange={(e, v) => {
setInputValue(e.target.value);
}}
/>
)}
renderOption={(option) => {
const matches =
option.structured_formatting.main_text_matched_substrings;
const parts = parse(
option.structured_formatting.main_text,
matches.map((match) => [
match.offset,
match.offset + match.length,
])
);
return (
<Grid container alignItems="center">
<Grid item>
<LocationOnIcon className={classes.icon} />
</Grid>
<Grid item xs>
{parts.map((part, index) => (
<span
key={index}
style={{ fontWeight: part.highlight ? 700 : 400 }}
>
{part.text}
</span>
))}
<Typography variant="body2" color="red" className={classes.noOptions} >
{option.structured_formatting.secondary_text}
</Typography>
</Grid>
</Grid>
);
}}
/>
<button className="btn btn-primary" style={{position: "absolute",
right: "0"}}
onClick={(e, v) => {
setInputValue(e.target.value);
}}>Find</button>
</div>
Anyone has idea how to fix this so when clicked on button I got same result as clicked on autocomplete field?
Thank you
you use the open prop which is in the Autocomplete , i've forked the Autocomplete example from material-ui check it out:
https://codesandbox.io/s/material-demo-forked-3n5lw?file=/demo.js

Resources