Having a problem with PrimeReact Dropdown - reactjs

I am still a novice in React Js and recently I have been developing using PrimeReact. The Forms and DataTables are doing well for me but I cant seem to figure out how deal with the Dropdown. My state is managed by redux and after mapStateToProps I and loading my data using componentDidMount I can console.log and see my data array. With a normal react select input I have been using the following code:
const {accounttypes} = this.props;
console.log(accounttypes)
let typesOptions = accounttypes.length > 0
&& accounttypes.map((item, index) => {
return (
<option key={item.id } value={item.id}>{item.name}</option>
)
}, this);
This works as an option as I can post to my backend. However I would want to use PrimeReact for all my forms and I have been struggling on how to go about it. The following has been my attempt and its giving me a headache:
<div className="p-field p-col-12 p-md-4">
<Dropdown
value={account_type}
optionValue = {accounttypes.id}
optionLabel = {accounttypes.name}
options={accounttypes}
onChange={this.onTypeChange}
placeholder="Select an Acco"
autoFocus = {true}
editable={true}
/>
</div>
account_type is the name of my field and my django model references the accountytpe model and would like to capture account_type whilst creating an Account. May someone help. And thanks in advance

optionLabel and optionValue should point to equivalent properties of your object. In your case I guess the correct way is this
optionValue="id"
optionLabel="name"

Related

Conditionally enabling a form button with react-hook-form and material ui

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.

React Hook Form Watch on Select Field

I have trouble with the Select field.
When I use the watch on select HTML attribute and change options in it, it doesn't re-render in the console. it stays the same, but when I use onChange, its re-renders.
My example of code --->
const example = watch('skills')
console.log(watch('skills'))
console.log(example)
<select {...register( 'skills')}>
<option>1</option>
<option>2</option>
</select>
when I choose option 2, it doesn't show option 2. what should I do? thanks
React hook form does not work with select forms correctly (no optimization).
Try the following:
const watchShowAge = watch('primaryType');
...
{ watchShowAge === 10 && (<p>You are too young!</p>) }

Don't use selected Error using Material UI select component

I am getting an error:
Warning: Use the defaultValue or value props on instead
of setting selected on .
<Select
onChange={props.changecompany}
value={props.currCompany != undefined ? props.currCompany.id : -1}
>
<option key={'empty'} value={'-1'}>
None
</option>
{mapstructure()}
</Select>;
And here is my mapstructure()
const mapstructure = () => {
return companies.map((company) => (
<option key={company.Id.toString()} value={company.Id}>
{company.Name}
</option>
));
};
I'm still learning so it is probably something fairly obvious, but the google solutions havent seemed to have fixed it. TIA
Here is what I think:
React throws a warning (not error) because, Material UI is using selected instead of value.
You have done nothing wrong and should not worry about it.
This can be fixed by Material UI itself in the upcoming updates if you raise this issue.
I hope this clears your doubt.

Is there any way to integrate reactjs with postgres for creating dynamic dependent dropdown?

Am new to reactjs and am creating a form in reactjs with the use of postgresql.
I've established connection between postgres and node.js and got values in the first dropdown.
I want to get values corresponding to the first dropdown in second dropdown from the same table in the database. Can anyone tell me how can I achieve it.
<select name="fruits" value={this.state.data.fruit}>
{this.fruitData.map((e, key) => {
return <option key={key} value={e.value}>{e.fruit_name}</option>;
})}
</select>
I have attached the screenshot of database and required output:
If you want to have specific options in the second dropdown, based on what was selected in the first dropdown (like showing cities based on a country selected) then you can monitor your first selection as a value in the component's state and then handle changes in the componentDidUpdate function like so.
componentDidUpdate(prevProps, prevState) {
if(this.state.country !== prevState.country) {
this.setState((state, props) => ({
filteredCities: props.cities.filter(city => city.country === state.country)
}))
}
}
Then you can use the state value of filteredCities (or whatever you are filtering) in your second drop-down to do a map just like you did with fruitData, producing all of your dependent options.

React Redux way of handling enable-disable of DOM elements

I have a form where i have to enable/disable certain DOM elements based on the state of other DOM elements. For e.g. I have a radio button, on the click of which a drop down should be enabled.
Now for implementing this, should I again follow the redux way of disposing an action when the radio is clicked and then within the reducer change the state and then enable/disable the dropdown?
Does redux-form in any way simplify this process? What is the best practice to implement this in a react-redux setup?
I use redux-form for conditional inputs. For example, I have a checkbox that when checked, should display a text area to explain the true input. That looks like this:
<div className="checkbox">
<label for="trueInput">
<input type="checkbox" {...trueInput} />
Is this input true?</label>
</div>
<div className={!trueInput.value ? 'conditional-input' : ''}>
<label for="trueInputExplanation">Why is this input true?</label>
<input className="form-control" {...trueInputExplanation} />
</div>
The class .conditional-input has styling to hide the element. I'd imagine you could do this the same way for disabled, by way of using a ternary function that returns true or false, depending on the conditions you need.
Redux Form keeps track of everything in the store. (It's easy to see what's going on with the Redux Chrome dev tool.) Say I have a master checkbox whose enablement allows me to toggle a slave checkbox. So I want to put the master state read from the form into props:
const mapStateToProps = (state) => {
const isMasterChecked = state.mySetting.isMasterChecked;
const form_mySetting = state.form.mySetting;
const form_isMasterChecked = form_mySetting ? form_mySetting.values.isMasterChecked : null;
return {
isMasterChecked,
form_isMasterChecked
}
};
and then for the form you have
const {isMasterChecked, form_isMasterChecked} = props;
const shouldDisable_slaveCheckbox= () => {
if (form_isMasterChecked == null) return isMasterChecked; // the form is not fully built yet, so use "real" store value instead of reading the form via store
return form_isMasterChecked;
};
<Field name="isSlaveChecked" component="input" type="checkbox" disabled={shouldDisable_slaveCheckbox() ? "" : "disabled"}/>
Use sparingly, as this approach may cause entire form redraw.

Resources