defaultValue doesn't change... dropdown react - javascript

I have a dropdown that get it's option from a fetch, and when I select and option another fetch is requested to save that into the DB, and then it return that into the state so the selected value is now in the state.
BUT!
my dropdown doesn't update the selected value, even though it updates correctly in the DB.
the dropdown:
<Form.Field className="dropdown">
<label>{answer.answerText}</label>
<Dropdown
key={ answer.name }
value={answer.value <!--THIS IS UPDATED AFTER SELECTION, BUT DOESN'T SHOW -->}
style={{paddingLeft: pad}}
onChange={(e) => this.blurHandler(e.target.textContent,answer)}
name={ answer.name }
disabled={answer.settings.disabled}
options={answer.dropdownOptions}
/>
</Form.Field>
The method that gets called.
blurHandler(e,answer) {
var answerValue = e;
var projectId = this.props.projectId;
this.props.updateAnswer('/api/update-answer',
answer.questionId,
projectId,
answer._id,
answerValue,
answer.settings.answerType
);
}
what updateAnswer does is just a fetch to save the value to the projects answer in the DB.

Your question title says defaultValue but you do not use that prop anywhere in your Dropdown component. When you are defining a value in your Dropdown component, or on any SUIR component, that means you must control all other input interactions yourself and you lose any of the out of the box state controls that come with SUIR components. There are definitely cases where you might want this.
I'd recommend changing your value prop to a defaultValue prop on your Dropdown and that should give you what you're expecting. The Dropdown will only initialize itself with that value but it will change in the UI the way you are expecting.

Related

Pass Row ID to a custom component in MUI Datagrid Pro

I am trying to add an indeterminate state to row checkboxes based on selection status of other checkboxes inside a detail panel. To do this I am creating a custom checkbox component and doing some logic to see if indeterminate should be true, the only problem is the checkbox needs access to the row id it is associated with to do that check. Thus far I've found nothing to pass anything other than the given CheckboxProps given by MUI, which contains no row information. There is something called componentsProps where I can pass other props to a component, but I've yet to find a way to pass the particular row id to its associated checkbox. Does anyone know of a solution to this?
.
.
.
const customCheckbox = (props: CheckboxProps) => {
return <Checkbox {...props} indeterminate={someArray.includes(theRowIdThisCheckboxIsUsedIn)} />
};
<DataGridPro
{...data}
components={{
BaseCheckbox: customCheckbox,
}}
/>
hi when you use custom checkbox component you cant use onSelectionModelChange to give you rows id you must write their logic too

ReactJS - update component (generated from a list) in the same div

It's a basic question but I searched for a guide without success...
I want to have a list of dropdowns and inputs and each dropdown will change the input next to it.
var list = [{ name: "foo1"}, {name: "foo2"}];
return (
{list.map( (name) => {
return (<div>
<dropdown data={someData}
onChange={(ev) => {
if(ev.value == 'clearIt')
<CHANGE THE NEAR INPUT VALUE>
}
}/>
<input value={name.name} />
</div>)
})});
I don't want to use DOM nor ref cause I understood that it's better to avoid it.
Any suggestions?
Or maybe the ref is the only option?
Thanks
So you can achieve this by doing the following steps:
Create a new component and move the dropdown and input to this new component.
Add state to your component by following this example:
https://reactjs.org/docs/state-and-lifecycle.html#adding-local-state-to-a-class
Add an event listener onChange to the dropdown with an event handler which can update the state you created in the first step. (Remember to bind the handler in the constructor.
Add the new component within the div element of this example you gave and pass the relevant data you need to the new component you created.
This should allow you to update only the input next to the dropdown. Also it allows you to have different data for each dropdown you created.

Updating state in Reactjs?

I am trying to update my state in ReactJS. To do this I have an input field in a Reactjs class. The field is automatically filled in with data from a parent class. The field looks like this:
<input
onChange={e => this.props.store.addLego(e)}
name="piece"
value={this.props.row.original.piece}
/>
The addLego function is designed to update my state and is in a MobX store. It looks like this:
addLego = action("addLego", e => {
this[e.target.name] = e.target.value;
});
However, I can't actually edit the input field! Nothing changes in the field when I type! Thanks for your help!
If you set a value attribute to an <input> field that field becomes a controlled input. This means that whatever gets passed to value is rendered on the screen. In your case, if you are not updating this.props.row.original.piece the <input> field will never get a new value. I'll suggest to read this bit of React's documentation https://reactjs.org/docs/forms.html#controlled-components
It is basically suggesting to keep the new value somewhere (in the component's state for example) and set it back as a value to the field.
Follow this tutorial here will solve your problem. It's a good read too for handling single or multiple inputs
Basically, you'll need a state in the constructor
this.state = {value: ''};
Event handler to set the value every onchange
handleChange(event) {
this.setState({value: event.target.value});
}
And the setup for input
<input type="text" value={this.state.value} onChange={this.handleChange} />

React widget Combobox not updating onFocus with Reduxform

I actually have 2 combobox (react-widgets) on my reduxform.
My first combobox works perfectly because I fetch my datas onChange.
But when I focus the second one I want my data loaded in it depending on the value of the first one.
The problem is : I have data in the render when I console.log it but the component not rerendering. I have to type something in the field to see my data, it's like only the onchange trigger the rerendering.
Field in the form:
<Field
component={HouseComp}
name="house"
currenthouses={currenthousesValue}
onFocus={getHouses(props)}
{...props}
/>
My component render:
<Combobox id="house"
data={currenthouses}
{...input}
/>
the getHouses function is a fetch returning something like :
props.dispatch(change('form', 'currenthouses',data))
the currenthousesValue is from a selector:
const currenthousesValue = selector(state, 'currenthouses');
I tried to force the update by using componentDidUpdate but even if I see the call of my render function the UI is not refreshing.
I also tried to load the data on "onBlur" from the first one but same result.
I am new to React. But I faced a similar issue in React. In your case when the value of first combo box changes, The value of data attribute of second form also changes. But your second combobox is not re-rendering may be becuase it is not subscribed to componentWillReceiveProps event.
Something like this(taken from my code):
componentWillReceiveProps(nextProps) {
this.setState({
groups: nextProps.groups,
invoices_count: nextProps.groups.length
});
}

How do I programatically fill input field value with React?

I have a modal with some input fields. I can easily pass the data automatically with the user typing an input, using onChange function in the input field, as
<Input onChange={this.props.store.handleCategoryChange} type="text" />
and .. (Using a mobx store, irellevant though)
#observable categoryValue;
#action handleCategoryChange = (e, data) => {
this.categoryValue = data.value;
e.preventDefault();
};
However, I want to add a function where the user can pre-fill this with information elsewhere in the application. I have the data to pre-fill the input fields with, but I can't figure out how do actually input it programatically, without the user doing it?
I need to invoke the above handleCategoryChange function. But my variable would be equal to data.value .. Which presents a problem! Invoking this function by myself isn't possible, because I won't have the event e nor a value called data.value as I will "just" pass in a variable by itself.
What's the right way to programatically fill an input field automatically in React, using variables elsewhere? I need to invoke the onChange function somehow, but the input values will be different..
Use controlled component for this situation, define a value property of input element like this:
<Input value={variable_name} ....
Whenever you will update that variable, automatically that value will get populated in input element.
Now you can populate some default value by assigning a value to variable_name and user can update that value by onChange function.
As per DOC:
An input form element whose value is controlled by React in this way
is called a "controlled component".
Pass in the value property for input:
<input type="text" value={this.state.value} onChange={(e) => {this.setState({value: e.target.value })}/>
you can use the controlled component and pass the value to it.
<input type="text" value{this.state.value}
onChange={()=> {this.setState({value:e.target.value })}}
Good question. I'm having the same issue, and just found a solution.
The problem is that:
You can't just use the default state of the modal component to set the initial input value, because the modal renders one time within the parent component (starting off invisible), so the default state of the Modal wont keep up with any changes to the 'pre-filled' info in the store that the inputs within the modal require access to.
You can't use the value attribute of the input to reference some redux store prop, since this is needed to reference the onChange function so the user can make changes to that pre-filled info.
And, you can't use the onChange function to set the initial value, because it is required to update the local state with the users changes - not set an initial value. Anyway, this requires the user to click on something, and you want the modal inputs to be pre-populated before the user does anything as soon as the modal opens...
So. What we need is to update these input fields every time the Modal attribute isModalOpen (or whatever you are using) changes.
(ie, pre-populate the fields when the Modal is opened).
Again, note that opening the Modal is not RENDERING the modal, it was already rendered, once, and has sat there being invisible until that isModalOpen attribute changed to true.
The Solution:
Step 1: make a handler function in the Modal component that prefills the inputdata by updating the local state of the Modal component. Mine looks like this :
handlePreFillModalInputsOnOpen = () => {
this.setState(() => ({
orthForm: this.props.matchLexUnit['orthForm'],
orthVar: this.props.matchLexUnit['orthVar'],
oldOrthForm: this.props.matchLexUnit['oldOrthForm'],
oldOrthVar: this.props.matchLexUnit['oldOrthVar'],
source: this.props.matchLexUnit['source'],
namedEntityCheck: this.props.matchLexUnit['namedEntityCheck'],
styleMarkingCheck: this.props.matchLexUnit['styleMarkingCheck'],
artificialCheck: this.props.matchLexUnit['artificialCheck'],
error: ''
}));
};
Step 2: Make that function fire ONLY when the isOpen attribute of the modal changes from false to true.
(This is the meat of your problem I think).
Use the lifecycle method componentDidUpdate. This will execute every time the props of the modal change.
componentDidUpdate(prevProps) {
if (this.props.isModalOpen === true && prevProps.isModalOpen === false) {
this.handlePreFillModalInputsOnOpen();
}
}
Watch out
make sure that you have a conditional in componentDidUpdate, otherwise you can run into infinite-loop/performance issues
if you have the possibility of null values icoming in as the prefilled input info, make a null-check so that they will not be passed into the local state.
Hope this helps :)
How to Programmatically Prefill, Fill or Update input fields value in React or useState Hooks?
Firstly - Get and define the data from database
const **yourData** = isDataFromDatabase;
or if the data is stored in Redux, then...
const **yourData** = useSelector(isDataFromDatabase);
Secondly - append it as the default value of a useState hook
const [isDataValue, setIsDataValue] = useState(**yourData**);
Thirdly - create a function to watch and Update the changes made by the user to your data value and set it to the useState hook created above
/** handles Your Data Value */
const handleDataValue = (text) => {
setIsDataValue(text);
};
Lastly - in your input tag, use the useState State as the "Value" parameter so it can be updated with the onChange function
<input
className="css"
id="myDataInput"
type="text"
value={isDataValue}
placeholder={isDataValue}
onChange={(e) => handleDataValue(e.target.value)}
/>
Now when you load the component, the prefilled value will be shown and can be updated in the HTML Input field.
That's All.

Categories

Resources