Handling onChange event for MaterialUI drop down element - javascript

I'm trying to validate the MaterialUI TextField (Country list) component wrapped with Autocomplete using onChange event and use it to enable the Submit button if the field (the country) is filled in. But I'm facing an issue once I'm not entering the country name by hands but selecting it from the dropdown. It looks like onChange event does not see the change in case of selecting from the drop down. (Sorry for formatting issues)
// countries: [a,b,c,d];
<Autocomplete
options={countries as CountryType[]}
<TextField
onChange={(event)=>{setFormValue({
...formValue,
country: event.target.value
})}}
/>
After this I'm using it on enabling the button:
<Button
disableElevation
disabled={formValue.country===""}
>
Submit
</Button>
Would be very appreciated on some suggestions.

While TextField's onChange method is obviously handling changes of the TextField. It doesn't fire on value selection. You're better off removing TextField's onChange handler and assign onInputChange property of the Autocomplete component that does exactly what you're looking for:
<Autocomplete
id="combo-box-demo"
options={countries}
...
onInputChange={(_, value) => {
setFormValue({
...formValue,
country: value
})
}}
renderInput={(params) => (
<TextField ... /> {/* without onChange handler */}
)}
/>

Related

MUI Autocomplete - Make all options selected by default

I've be using this example to try and get the values in the autocomplete drop down to be automatically selected by default. I'm looking to get all the values to be selected when the page is loaded. Does anyone know how to do this?
Sandbox code :
https://codesandbox.io/s/s26gz?file=/demo.js:504-523
You can pass a defaultValue props to Autocomplete like this
<Autocomplete
options={options}
value={value}
defaultValue={top100Films}
...
/>
You can control the value of the Autocomplete by overriding the value/onChange props and use useState to set the initially selected options:
const [value, setValue] = React.useState(options);
return (
<Autocomplete
options={options}
value={value}
onChange={(e, v) => setValue(v)}
{...}
/>
);
Or if you're using uncontrolled mode, simply pass a defaultValue:
<Autocomplete
defaultValue={options}
{...}
/>

React with Ant Design - How to share state between multiple <Select> on a <Form>?

I am new to ReactJS and AntDesign.
I am trying to get a set of <Select> components to share state, so when you select the first one, it populates the options of the next ones on the form, it has to be a <Select>, I cannot use a <Cascade> as it is going to complicate UI too much ( users are not very versed with computers ).
Here is an example of what I am trying to achieve, the data on useEffect will come from the backend in a single request
https://stackblitz.com/edit/react-xarwcj-sghpze?file=index.js
After you select the first option, I expected the second dropdown to be filled up with the child array, but instead I get an empty dropdown.
I am pretty sure the value is being set but React or Ant is not rerendering it because of some misconfiguration on my part, but I cannot understand why.
If you use antd Form then you must wrap your input elements in Form.Item components. And Form.Item components have a name prop. When you use any formInstance methods that name that you give to your Form.Item is how you can reference the given input component. So when you were doing formInstance.setFieldsValue({ subList: value.list }); you didn't actually have a subList form item, so I think that's why antd didn't set it's value.
With that said, your second select should look something like this:
<Form.Item name="subList">
<Select ... >
{formInstance.getFieldValue("subList")?.map ... }
</Select>
</Form.Item>
Don't forget to wrap that first Select too, and any other input components in your Form for that matter. The names you give to the Form.Item is how you will be able to read the values in the Form's onFinish method.
For a working example of such usage you can check this example from the antd form docs: https://codesandbox.io/s/n1zdn.
I should mention that to me it seems erronous when you do formInstance.setFieldsValue({ subList: value.list }); in your first Select's onChange (because value is a number, so value.list is undefined), but I believe that's because what you provided is only a rough, incomplete copy of your actual code. However, If you have further difficulties with this issue please drop a comment and I'll do my best to help out more!
Edit
To answer your comment, the problem I managed to identify was that, when selecting an option from the first select, you were setting the value of the second select as an array. What you actually wanted to do was set the available options of the second select, not it's value.
So the changes I propose is for you to set the options of the second select in a state variable, like so:
const [list, setList] = useState([]);
const [secondList, setSecondList] = useState([]);
// ...
return (
<>
<Form form={formInstance}>
<Form.Item>
<Select
style={{ width: 120 }}
onSelect={value => {
console.log(list.find(o => o.id === value).list);
setSecondList(list.find(o => o.id === value).list);
}}
>
{list.map(value => {
return (
<Option key={value.id} value={value.id}>
{value.name}
</Option>
);
})}
</Select>
</Form.Item>
<br />
<br />
<Form.Item name="subList">
<Select
style={{ width: 120 }}
onChange={value => {
console.log(value);
}}
>
{secondList?.map(value => {
return (
<Option key={value.id} value={value.id}>
{value.desc}
</Option>
);
})}
</Select>
</Form.Item>
</Form>
</>
);

react-select function call on click event on the chip

Hi I am trying to change a state in my component when there is a click event on a particular chip rendered in the search bar. Is that possible to do?
I am aware of the multiValue multiValueLabel and I can for example change the background color of the chip with that, so I thought I could use those tags to change the state but I didn't have any luck.
I have attempted to find a solution with isSelected tag but I am always reading undefined in the states.isSelected when console.logged it.
I feel like I need a onClick() functionality somewhere but I can't figure it out. A bit of a guidance would be much appreciated!
I am sharing a live code here so maybe we can discuss over it.
if you want to validate if an option is selected you could use the prop: isOptionSelected
or
const onChange = selectedOptions => setSelected(selectedOptions);
with props
isMulti
value={selected}
onChange={onChange}
components={{
MultiValue: SortableMultiValue,
}}
You can attach onClick listener in MultiValueLabel component
<Select
isMulti={true}
components={{
MultiValueLabel: (props) => {
return (
<div onClick={() => console.log(props.data)}>
<components.MultiValueLabel {...props} />
</div>
);
}
}}
{...}
/>
Live Demo

How do I get an event when any option is selected for a Material UI Autocomplete React component?

I have an autocomplete. I need to intercept when an option is selected. The onChange event I have bound works only when the selection, is different than the last one. I just want to know whenever one is selected, period. I can think of a few strategies for this, none of which seem to be provisioned by the Autocomplete API.
Just catch an event whenever something is selected. This doesn't exist that I know of.
Always set the "current selected" option to null so everything is a change. This doesn't exist that I know of.
Maybe some custom options rendering that encompasses all of the interaction logic that I am trying to avoid by using the Material UI control...is this the only way?
<Autocomplete
className={classes.textfield}
id={entityId}
freeSolo
open={showSuggestions}
onClose={handlePopoverClose}
onChange={handleOptionSelected}
options={options}
filterOptions={(options, state) => options}
renderInput={(params) => (
<TextField inputRef={textfieldRef} {...params} id={entityId} margin="normal"
onKeyPress={handleKeyPress} onInput={handleInputChanged} value={controlText}/>
)}
/>
According to the material ui documentation, you can actually filter out the type of onChange event by accessing the second optional parameter (reason).
This is how you can check when any of the options are selected:
const handleOptionSelected = (event,value, reason) => {
if (reason === 'select-option') {
// do the rest
};
};

Using Controller component of react-hook-form doesn't allow custom Antd Select to show label

I'm using Antd Select component to build a custom component which gives me the ability to return an object instead of a primitive value and show nested value in object item in the select dropdown options, it works fine and it can be validated using react-hook-form :
<Form.Item ... >
<SpringSelect style={{ width: "200px" }} options={departments} placeholder="Department 2"
name="department2" onChange={e => {setValue("department2", e);}}/>
</Form.Item>
This also works with Controller component however it doesn't show the label inside the select input :
<Controller as={<SpringSelect style={{ width: "200px" }} />}
placeholder="Department 1" name="department1" options={departments}
onChange={([e]) => {return { value: e };}} control={control} />
for more details check the whole code in the codesandbox playground
I think the problem is due to your SprintSelect innerProps
have a look my CSB below:
https://codesandbox.io/s/suspicious-platform-tlr55
<Select onChange={props.onChange}>
When the component is inside the controller a value prop is send to it. And your are just deleting the onChange and onBlur from the props.
Select will use this prop value, but it's a object, that is why it doesn't show the label.
To fixed you can just delete delete tmp.value; before add the props to innerProps
Exemple: https://codesandbox.io/s/vibrant-river-8r4dt
I place a console.log, as you can see department1 has a value field

Categories