I try to get the value of autocomplete in console.log()
it's posible to get the value of autocomplete after selection of title ?
find below code source
https://stackblitz.com/edit/react-tewwbp?file=demo.js
[code source[1]
You are currently using uncontrolled Autocomplete so you don't have access to the value that is currently selected. To console the value you can use something like this:
<Autocomplete
onChange={(event, newValue) => {
console.log(newValue);
// setValue(newValue);
}}
...
/>
Related
I'm creating a React form with Material UI. My goal is to force the user to answer all the questions before they can click the download button. In other words I'm trying to leave the download button in the disabled state until I can determine that values are set on each field. I've tried to get this working with and without react-hook-form.
What I've tried
Without react-hook-form...
I have my example in coding sandbox here:
https://codesandbox.io/s/enable-download-button-xwois4?file=/src/App.js
In this attempt I abandoned react-hook-form and added some logic that executes onChange. It looks through each of the formValues and ensures none of them are empty or set to "no answer". Like this:
const handleInputChange = (e) => {
// do setFormValues stuff first
// check that every question has been answered and enable / disable the download button
let disableDownload = false;
Object.values(formValues).forEach((val) => {
if (
typeof val === "undefined" ||
val === null ||
val === "no answer" ||
val === ""
) {
disableDownload = true;
}
});
setBtnDisabled(disableDownload);
The problem with this approach, as you'll see from playing with the UI in codesandbox, is that it requires an extra toggle of the form field value in order to detect that every field has been set. After the extra "toggle" the button does indeed re-enable. Maybe I could change this to onBlur but overall I feel like this approach isn't the right way to do it.
Using react-hook-form
With this approach...the approach I prefer to get working but really struggled with, I ran into several problems.
First the setup:
I removed the logic for setBtnDisabled() in the handleInputChange function.
I tried following the example on the react-hook-form website for material ui but in that example they're explicitly defining the defaultValues in useForm where-as mine come from useEffect. I want my initial values to come from my questionsObject so I don't think I want to get rid of useEffect.
I couldn't figure out what to do with {...field} as in the linked material ui example. I tried dropping it on RadioGroup
<Controller
name="RadioGroup"
control={control}
rules={{ required: true }}
render={({ field }) => (
<RadioGroup
questiontype={question.type}
name={questionId}
value={formValues[questionId]}
onChange={handleInputChange}
row
{...field}
>
but I get an MUI error of : MUI: A component is changing the uncontrolled value state of RadioGroup to be controlled.
Also, I don't see that useForm's state is changing at all. For example, I was hoping the list of touchedfields would increase as I clicked radio buttons but it isn't. I read that I should pass formState into useEffect() like this:
useEffect(() => {
const outputObj = {};
Object.keys(questionsObject).map(
(question) => (outputObj[question] = questionsObject[question].value)
);
setFormValues(outputObj);
}, [formState]);
but that makes me question what I need to do with formValues. Wondering if formState is supposed to replace useState for this.
I'm building a form with React-Hook-Form and Material-UI. Each Material-UI form component is wrapped into a react-hook-form Controller component.
The user has the option to populate the form automatically with different sets of pre-defined values when clicks on a button. I'm trying to use setValue() to achieve that and it seems to work fine for text input and select. However, for autocomplete the new value is not rendered although when submitting the form it is correctly sent. Also, when a text area is rendered the content seems to be mixed with the label.
Here is a complete example:
CodeSandbox Link
You need to cotroll the value of AutoComplete by passing value attribute to AutoComplete component, But since you are using string value you couldn't pass value to AutoComplete directly and you should to find the target option like this:
<Autocomplete
...
value={typeof value === 'string' ? options.find(o => o.name === value) : (value || null)}
/>
Your textarea problem occurs because your value by default is undefined and material considers the textare as uncotrolled input, to solve it you can pass empty string when value is undefined, like this:
<TextField
...
value={value || ''}
...
/>
I was playing with Material UI autocomplete component's github label picker example and modified it as per sandbox below:
https://codesandbox.io/s/material-demo-hwi3l?file=/demo.js
The Autocomplete works fine. When I select company names from the list they show up as chip elements after closing and when I deselect them individually, they get hidden as well. However, I am unable to figure out how to delete individual elements by clicking on chip's close button. I am unable to figure out what exactly to put in the chip's onDelete prop?
{
value.map((company, index) => (
<Chip
label={company.name}
onDelete={(event, newValue) => {
//setPendingValue(company);
}}
color="primary"
className={classes.selectedCompanies}
/>
))
}
Since the Chip as per sandbox is inside the value array, I am not sure how I could delete something from inside it while looping through it. Any help would be greatly appreciated.
One way to delete from an array is to filter where each iterated item is not the deletable item. Doing so returns a new array that omits the deletable item. So in your example:
The delete-handler:
const handleDelete = name => {
const newValue = value.filter(company => company.name !== name);
setValue(newValue);
};
The chip element:
{value.map((company) => (
<Chip
key={company.name}
label={company.name}
onDelete={() => handleDelete(company.name)}
The codesandbox with the solution
Note, in React, you should include the iterated key in each list item.
i have handler fn for handle input from Textfield.
I want use it fn for autocomplete component, but i cant get 'name' and value from it.
function handlerChange(e){
const { name, value, checked } = e.target;
return { name, value: value || checked };
}
<Autocomplete
id="distributions"
name="defaultDistr"
options={distributions}
getOptionLabel={distribution => distribution}
inputValue={defaultDistr}
defaultValue={defaultDistr}
onChange={(e, value) => {
console.log('e', e, 'value', value);
}}
renderInput={params => (
<TextField
{...params}
name="defaultDistr"
label="distributions"
margin="normal"
fullWidth
/>
)}
/>
For Autocomplete, there are many different events that can cause changes to the value. There are several different elements from which those events can come from, so you cannot rely on the target of the event to get the name. Similarly the target of the event does not necessarily have a value and even if it does, that value may not represent the current value of the Autocomplete. This is why the correct value is passed as a second parameter to your onChange handler.
Assuming there is more significant code in handlerChange than what you've shown such that it is worth trying to reuse, you can do something like shown below which creates a new object organizing the information into the structure the handler is expecting.
<Autocomplete onChange={(event, value)=> { handlerChange({target: {name: "defaultDistr", value: value}})} .../>
I am working on a ReactJS application and I am trying to get the text of a selected option in a dropdown (Semantic UI component);
exposedCampaignOnChange = (e, {value}) => {
this.props.campaignExposedSelected(value);
};
<Dropdown
placeholder='Campaign Exposed To'
fluid
search
selection
multiple
options={this.state.campaigns}
onChange={this.exposedCampaignOnChange}
/>
The above code returns the value. this.state.campaigns is made up of an array of objects with value and text properties. In addition to the value, I also want to get the textvalue of the selected options.
Appreciate any guidance on the matter.
You can use synthetic event's target property to get the text like:
exposedCampaignOnChange = (e, {value}) => {
e.persist();
console.log(e.target.textContent);
this.props.campaignExposedSelected(value);
};
<Dropdown
placeholder='Campaign Exposed To'
fluid
search
selection
multiple
options={this.state.campaigns}
onChange={this.exposedCampaignOnChange}
/>
Semantic ui react Dropdown onChange event takes two arguments -
onChange(event: SyntheticEvent, data: object). You don't need to pass them explicitly while calling the function.
exposedCampaignOnChange = (e, value) => {
e.persist();
this.props.campaignExposedSelected(value);
};
data/value should have selected option text like in semantic UI
function getSelectedTextValue() {
alert( $('.ui.dropdown').dropdown('get text') + " : " + $('.ui.dropdown').dropdown('get value') );
}