I am trying to do something extremely simple, something that in JS I can do in a fraction of a second, but that for some reason is not working in the React
I am trying to change the dropdown value and capture the target element in the event, so I could assign it to the state with a certain index (idx)
However, no matter what I do, the event target comes up as undefined. I did already try to apply bind but in that case the event wouldn't fire at all
Please help, thank you in advance
Here is the dropdown
<Dropdown onChange={event => this.handleRoleChange(event, idx)}
placeholder="Staff Member Roles"
options={options}
styles={dropdownStyles}
/>
Here is handleRoleChange event
private handleRoleChange(event, idx) {
alert(idx);
alert(event.target.value);
}
Found an answer
<Dropdown onChange={this.handleRoleChange}
placeholder="Staff Member Roles"
options={options}
styles={dropdownStyles}
id={idx.toString()}
/>
public handleRoleChange = (event, option, index) => {
let idx = parseInt(event.target.id);
alert(idx);
alert(option.key);
}
Related
I've created one Demo Application where I've been able to add comments while clicking on the chat icon textarea will be expanded, currently, the functionality is I've created a reference using useRef of that particular text area using unique id, and I'm saving comments to that reference array, & rendering on UI using ref.current Method, everything is working as I expected but when I click on those filter buttons, the reference is getting null! my requirement is even though I do filter comments should be persisted!
Any suggestion, Any new Approach except using useRef would be Appreciated! Thanksyou!!
Here's my codesandbox link
https://codesandbox.io/s/proud-resonance-iryir7?file=/src/App.js
Your comment ref should only contains comments, not includes textarea element. So you should create a component to handle textarea value
const TextArea = ({ value, handleSaveComment }) => {
const ref = useRef(null);
return (
<>
<textarea
placeholder="Enter Here"
ref={ref}
defaultValue={value}
></textarea>
<div
className="save-button"
onClick={() => {
handleSaveComment(ref.current.value);
}}
>
Save
</div>
</>
);
};
and use it in table
const handleSaveComment = (fsValidationId, value) => {
comment.current[fsValidationId] = value;
setExpandedId((prev) => (prev === fsValidationId ? "0" : fsValidationId));
};
<AccordionDetails>
<TextArea
handleSaveComment={(value) =>
handleSaveComment(row.id, value)
}
value={comment.current[row.id]}
/>
</AccordionDetails>
You can check full code in my codesandbox. Hope it help!
Codesandbox with minimal working example: https://codesandbox.io/s/mystifying-lake-m0oxc?file=/src/DemoForm.tsx
Essentially, I have a AutoComplete dropdown which is tied into a Formik form with the useField hook. This sets the value correctly on any change, but the validation doesn't seem to trigger when I expect it to.
Validation runs successfully and removes the error if:
Another field is changed
I click on the "background" after selecting a value in the dropdown
What I expected and wanted was that the validation should run immediately when a value is selected.
To reproduce:
Click the category dropdown
Select a value, which closes the dropdown
Confirm that the error is still indicated (on the field and in the printout)
Click elsewhere on the screen. This should trigger validation and clear the error.
Any suggestions?
Edit:
I've tested an equivalent implementation with react-select as the dropdown and had the same issue, so I don't think it's directly tied to MUI.
I just reproduced based on the working example what you provided and realized that you set helpers.setTouched manually.
Just don't overuse the setTouched and also you need to handle if you remove the selected item from the autocomplete.
<Autocomplete
disablePortal
id="category-selector"
options={options}
onBlur={() => helpers.setTouched(true, true)}
isOptionEqualToValue={(option, value) => option.id === value.id}
onOpen={() => helpers.setTouched(true, true)}
onChange={(_, option) => {
if (option) {
helpers.setValue(option.id);
} else {
helpers.setValue(0);
}
}}
renderInput={(params) => (
<TextField
{...params}
label="Category"
error={meta.touched && Boolean(meta.error)}
/>
)}
/>
I have a group of react selects using the react-select package – https://react-select.com/home.
I have a component that wraps three react-selects – something basically like this:
import Select from "react-select"
function SelectGroup(){
const ref1 = useRef(null);
const ref2 = useRef(null);
const ref3 = useRef(null);
return (
<div>
<Select ref={ref1} />
<Select ref={ref2} />
<Select ref={ref3} />
</div>
)
}
I need to perform some checks to see what's in focus. The reason I am doing this is because the group of selects is a single component that needs to be able to allow the user to navigate in multiple ways through the keyboard. Spacebar, and enter keys should allow the user to shift the focus to the next select element. Arrow keys should allow the user to go to the next or previous select. So, focus needs to be managed somehow, and this means knowing what's currently in focus.
Normally, I would do that like this:
function isActiveElement(ref){
return ref?.current === document.activeElement
}
However, for ref.current react-select returns an object called StateManager – https://react-select.com/props#statemanager-props
So, ref.current === document.activeElement always returns false.
How, can I check to see which react-select is in focus? I was unable to find anything about this in the react-select docs. Maybe, I'm missing it? I have solved this problem others ways, but I was curious if there is a way to do it this "simpler way" I describe above, which may be the more common approach.
You can listen to the focus and the blur event to keep track of the currently focused Select:
export default function App() {
const [focus, setFocus] = useState(-1);
const onBlur = () => setFocus(-1);
return (
<div>
<div>Current focus: {focus}</div>
<Select
onFocus={() => setFocus(0)}
onBlur={onBlur}
options={colourOptions}
/>
<Select
onFocus={() => setFocus(1)}
onBlur={onBlur}
options={colourOptions}
/>
<Select
onFocus={() => setFocus(2)}
onBlur={onBlur}
options={colourOptions}
/>
</div>
);
};
Live Demo
I'm trying to create a search form with autocomplete suggestions that pulls data from API. I got everything to work in terms of displaying data and selection, but I would like to automatically take the user to the related page once they select one of the suggestions.
<Autocomplete
id="search-input"
freeSolo
disableClearable
options={playerList}
getOptionLabel={(option) => option.nickname}
style={{ width: 200}}
**onClick={console.log("you clicked")}
onSelect={(val)=> window.location.href = "/player-statistics/"+val.nickname+"-"+val.account_id+"-"+server}**
onInputChange={(event, newInputValue) => {
setInputValue(newInputValue);
if (newInputValue.length >= 3) {fetchPlayers(newInputValue)}
}}
renderInput={(params) => <TextField {...params} label="Search Players" variant="outlined" margin="normal" />}
/>
I have tried with onChange and onSelect, but they are both reloading the page continuously whenever you press the search field or start typing.
The idea is to skip the need to click "search" button.
When you select a suggested name, onInputChange is triggered.
There you need to put the logic for changing the location.
Then the user does not have to click anything else.
If you do not want the page to change when the user only types a single character,
then you need to write logic for that inside onInputChange.
sth. like
// inside onInputChange
if(isASuggestedName(newInputValue)) {
//...change location
}
I figured it out after going through the API.
onChange call has 3 parameters - function(event: object, value: T | T[], reason: string) => void
I basically set it up so relocation is triggered only if reason is select-option and it works perfectly.
Thank you everyone
Thanks for reading. I'm using Material-UI Autocomplete and trying to figure out how to capture a user choice. Here's the code. For now, I'm trying to console.log the user choice or deletion of a movie from the selection list. If I can get this to work I'll probably use a state settor in handleChange to capture the movie and read the state value for processing once the dialog is submitted. Since this is a multiple Autocomplete there may be several selected values.
Currently event.target.value in handleChange displays a zero when selecting a movie from the list, and undefined when removing. I need it to display the actual title.
Happy to consider any suggestion to get to the objective of being able to process all autocomplete selections upon dialog submission. Thanks in advance!
React version: 16.8
Resolved by sending the parameters (event, value) from onChange. Please see the onChange value in the below snippet.
export default function App() {
const classes = useStyles();
const handleChange = (value) =>
{
const x = value.map(function(a){return {title:a.title};});
console.log(x);
};
return (
<div className={classes.root}>
<Autocomplete
multiple
id="tags-outlined"
options={top100Films}
onChange={(event, value) => handleChange(value)}
getOptionLabel={(option) => option.title}
defaultValue={[top100Films[14]]}
filterSelectedOptions
renderInput={(params) => (
<TextField
{...params}
variant="outlined"
label="filterSelectedOptions"
placeholder="Favorites"
/>
)}
/>
</div>
);
}