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
Related
I am building a React application and using react-final-form library. I am rendering a select component, but on selecting an item it doesn't get selected. On selecting again, then only it gets selected. I'm not sure why select component state is not getting changed ? Could anyone please check and assist.
Here is the code sandbox link : https://codesandbox.io/s/broken-sunset-9ogwc8?file=/src/Components/Actors.jsx
Regards.
In your NativeSelectField.jsx, change the onChange handler as below:
<NativeSelect
...
...
onChange={(event) => {
input.onChange(event.target.value);
}}
...
...
/>
Working Demo
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>
</>
);
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
};
};
I have a very interesting situation.
This is my component:
export const checkbox = ({ data }) => {
const inputRef = useRef(null);
console.log(inputRef); // Does not appear
return (
<FormGroup>
{data.data.map(item => (
<FormGroup>
<Input
ref={inputRef}
/>
</FormGroup>
</FormGroup>
);
};
It is a child of other component which basically get values and submits to form.
but to no avail..
How can I fix this? I just need it to keep the focus, so I can continue typing. Should I use React.memo() for this?
Also, please note that I have checked all the references I could find on SO and nothing helped. I have spent 3 days on this.
Based on our chat, the root cause was elements having a dynamic key prop which changed on each render. This was causing a new textarea element to be rendered with each change event and the new element didn't have focus.
The solution is to use a deterministic key which doesn't change between renders.
i'm having a little issue here and i need your help.
I want to render a select field with chip inside of it. I successfully implement this but i'm having a little issue. When i click in one of my chip inside the dropdown the dropdown text is showing nothing. I add the propery primaryText inside the menu item and the value is shown successfully but not with the way i wish. Here is a screenshot:
And here is my code:
<MenuItem
key={id}
value={id}
style={styles.scroll}
primaryText={id}
>
<Chip
key={id}
style={styles.chip}
onClick={() => customerSessionSelector(id)}
onRequestDelete={() => handleRequestDelete(id)}
>
{id}
</Chip>
</MenuItem>
For not showing the text under the chip i remove the primaryText property but when i select the value the value is now showing? Any ideas of how to achieve something like this?