React.JS FormControl: how to set properly default value - reactjs

I have the following Control written for ReactJs app. The app and the code is not written by me, but I have to modify it. However, I am new to ReactJs.
function FormSelectNative({ name, label = null, defaultValue = '', options, valueKey = 'value', labelKey = 'label', ...props }) {
return (
<FormControl variant="outlined" size="small" fullWidth>
<InputLabel id={name}>
{label || name}
</InputLabel>
<Select
name={name}
labelId={name}
label={label || name}
defaultValue={defaultValue}
{...props}
>
{options.map(option =>
<MenuItem key={option[valueKey]} value={option[valueKey]}>{option[labelKey]}</MenuItem>
)}
</Select>
</FormControl>
);
}
I need to pass defaultValue parameter correctly.
I am trying to set it like this:
<FormSelectNative
options={games}
valueKey="id"
labelKey="name"
onChange={handleGameSelect}
defaultValue={games[0]}
/>
But it doesn't work (default value is not set). I need to set default value to be first element of "games". However, here I believe is some mismatch of types, so it is not set.
Games element example:
{id: 1, name: "Name of Game", description: "Some test description", helper: "test.png", created_at: "2021-08-24T16:06:13", ... some other properties}

The defaultValue has to be one of the possible value that you pass to the MenuItem. Each of those values is the game.id of each game, not the game object as a whole (a number, not an object). That's because you are doing value={option[valueKey]} where valueKey is id.
Therefore this is what you should do instead to set the default value correctly:
<FormSelectNative
options={games}
valueKey="id"
labelKey="name"
onChange={handleGameSelect}
defaultValue={games[0].id} // <<<--- get the id of the first item
/>

Related

State is not upating in the react-select library

I'm using react-select library and I'm calling the function in the options and that function takes one parameter. But when countryCode state is updated, it does not update in select tag.
When I pass hardcoded value in the function like options={getSortedState("US")}, it works fine but when I get value from API and set state of parameter then it does not work.
<Controller
control={control}
name="options"
render={({ field }) => (
<Select
value={field.value}
options={getSortedState(countryCode)}
onChange={(state) => field.onChange(state)}
placeholder="Select State"
defaultValue={field.value}
onInputChange={() => {
console.log('A', countryCode);
setCountryCode('');
setCountryCode(countryCode);
}}
// options={getLiDepartments()}
/>
)}
/>

MUI Select label not hiding properly

I have a MUI Select which I want to hide the label, but it's not working:
<FormControl fullWidth>
<Select
value={selectedEntry}
onChange={(e) => handleSelectEntry(e.target.value)}
inputProps={{ 'aria-label': 'Without label' }}
>
{dropDownList?.map((entry) => (
<MenuItem key={entry.key} value={entry.key}>{entry.value}</MenuItem>
))}
</Select>
</FormControl>
It display this: output 1
You can set the displayEmpty prop of Select, if true, a value is displayed even if no items are selected.
In order to display a meaningful value, a function can be passed to the renderValue prop which returns the value to be displayed when no items are selected. But you can don't provide any renderValue and no "label" (actually its more like a default displayed value) will be shown.
Empty select:
<Select
value={selectedEntry}
displayEmpty
onChange={(e) => handleSelectEntry(e.target.value)}
>
Select with default displayed value:
<Select
value={selectedEntry}
displayEmpty
onChange={(e) => handleSelectEntry(e.target.value)}
renderValue={value => value || 'there\'s nothing selected'}
>

I can't assign a input select value from a fetch with react-hook-form

Basically I have a function onBlur that fetches some data, then I place the data into some fields that are being controlled with react-hook-form.
Everything but selects are being set, I don't know if there's something wrong with the libs, or it's just me not doing it right.
This would be the flow:
Filling up the CEP Field would return an object (1st is the object that returns,2nd is the object that should be set on the Form):
This is how the form data is set after the data fetch:
addressReset({
cep: res.cep,
bairro: res.bairro,
localidade: res.localidade,
address: res.logradouro,
uf: res.uf,
});
And this would be my controller component:
<Controller
control={control}
name={name}
render={({ field }) => (
<TextField
{...field}
disabled={disabled && true}
select={select ? true : false}
fullWidth={fullWidth ? true : false}
autoComplete={name}
type={type}
label={label}
error={Boolean(errors[name])}
helperText={errors[name] ? errors[name].message : ""}
variant="outlined"
required={required ? true : false}
id={name}
name={name}
InputLabelProps={InputLabelProps}
InputProps={InputProps}
size={size}
onBlur={onBlur}
>
{children && children}
</TextField>
)}
/>
It takes some props, but more importantly it's name is uf, I don't see anything wrong here.
On a Select component you need to pass an object with keys label and value.
https://mui.com/api/select/

How to set default value in material-UI select box in react?

I am using Select box from material-ui
I want to show "select the value" option by default selected but after that user is not able to select this option.
<FormControl required className={classes.formControl}>
<InputLabel htmlFor="circle">Circle</InputLabel>
<Select
value={circle}
onChange={event => handleInput(event, "circle")}
input={<Input name="circle" id="circle" />}
>
<MenuItem value="" disabled>
<em>select the value</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
<FormHelperText>Some important helper text</FormHelperText>
</FormControl>
Current code on sandbox: https://codesandbox.io/s/xoylmlj1qp
I want to make like this: https://jsfiddle.net/wc1mxdto/
Update
I changed the state 20 to blank string in circle
form: {
searchValue: "",
circle: '',
searchCriteria: ""
}
now expected output should be dropdown should show "please select value" but currently it showing this
You need to provide correct MenuItem value in state to be matched on render.
Here is the working codesandbox: Default Select Value Material-UI
You can just pass the displayEmpty into select
<Select
id="demo-simple-select-outlined"
displayEmpty
value={select}
onChange={handleChange}
>
and define the menuItem like
<MenuItem value=""><Put any default Value which you want to show></MenuItem>
As React introduced React-Hooks, you just need to pass your default value in React.useState() as React.useState(10).
export default function CustomizedSelects() {
const classes = useStyles();
const [age, setAge] = React.useState(10);// <--------------(Like this).
const handleChange = event => {
setAge(event.target.value);
};
return (
<form className={classes.root} autoComplete="off">
<FormControl className={classes.margin}>
<Select
value={age}
className={classes.inner}
onChange={handleChange}
input={<BootstrapInput name="currency" id="currency-customized-select" />}
>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
</form>
);
}
<FormControl variant="outlined" className={classes.formControl}>
<InputLabel id="uni">UNI</InputLabel>
<Select
key={value}
defaultValue={value}
labelId="uni"
id="uni"
name="uni"
onBlur={onChange}
label="uni"
>
{unis.map((u, i) => (
<MenuItem value={u.value} key={i}>
{u.label}
</MenuItem>
))}
</Select>
</FormControl>;
Just use the defaultValue attribute of select.
You can refer to the Material UI Select API Docs to know more.
import React from 'react';
import {useState} from 'react';
import FormControl from '#material-ui/core/FormControl';
import InputLabel from '#material-ui/core/InputLabel';
import Select from '#material-ui/core/Select';
import MenuItem from '#material-ui/core/MenuItem';
const Selector = () => {
const [Value, setValue] = useState("1"); // "1" is the default value in this scenario. Replace it with the default value that suits your needs.
const handleValueChange = event => {
setValue(event.target.value);
}
return(
<FormControl>
<InputLabel id="Input label">Select</InputLabel>
<Select
labelId= "Input label"
id= "Select"
value= {Value}
defaultValue= {Value}
onChange= {handleValueChange}
>
<MenuItem value="1">Item1</MenuItem>
<MenuItem value="2">Item2</MenuItem>
<MenuItem value="3">Item3</MenuItem>
</Select>
</FormControl>
)
};
export default Selector;
If you take a look at the Select Api of Material UI here, you could do it easily.
As explained above, you need to pass the default value in your state variable:
const [age, setAge] = React.useState(10);// <--------------(Like this).
Set displayEmpty to true:
If true, a value is displayed even if no items are selected.
In order to display a meaningful value, a function should be passed to the renderValue prop which returns the value to be displayed when no items are selected. You can only use it when the native prop is false (default).
<Select
displayEmpty
/>
I had a similar issue. In my case, I applied a function directly to onChange so I had something like this:
export default function CustomizedSelects() {
const classes = useStyles();
const [age, setAge] = React.useState(10);
return (
<form className={classes.root} autoComplete="off">
<FormControl className={classes.margin}>
<Select
value={age}
className={classes.inner}
onChange={(event) => setAge(event.target.value)}
input={<BootstrapInput name="currency" id="currency-customized-select" />}
>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
</form>
);
}
I also had a separate button to clear select value (or select the default empty value). All was working, the select value was set correctly, except the Select component did not animate to its default form - when no value is selected. I fixed the problem by moving onChange to a handleChange separate function as it is in the code example #B4BIPIN is presenting.
I am not an expert in React and still learning and this was a good lesson. I hope this helps ;-)
Take a list of objects you want to display in the Select dropdown and initialise it using useState. Use the state now to show the value and update the state on the change of the dropdown.
const ackList = [
{
key: 0,
value: "Not acknowledged",
},
{
key: 1,
value: "Acknowledged",
},
];
function AcknowledgementList() {
//state to initialise the first from the list
const [acknowledge, setAcknowledge] = useState(ackList[1]);
//update the state's value on change
const handleChange2 = (event) => {
setAcknowledge(ackList[event.target.value]);
};
return (
<TextField
select
fullWidth
value={acknowledge.key}
onChange={handleChange2}
variant="outlined"
>
{ackList.map((ack) => (
<MenuItem key={ack.key} value={ack.key}>
{ack.value}
</MenuItem>
))}
</TextField>
);
}
The problem here is all to do with some pretty poor coding on the part of the MUI folks, where on several components, they have magic strings and really are doing silly things.
Let's take a look at the state here:
const [age, setAge] = React.useState('3');
You can see that we are having to specify the VALUE as a string. Indeed the data type that the Select control takes is a string | undefined. So the fact we are having to use a number value as a string is the source of confusion.
So how does that work?
It is all to do with the MenuItem component. Let's take a look:
<MenuItem value={1}>First Choice</MenuItem>
<MenuItem value={2}>Second Choice</MenuItem>
<MenuItem value={3}>Third Choice</MenuItem>
You can see that we are indeed having to specify the VALUE of the MenuItem as a number.
So in this case, specifying '3' as the State value, as a string, will select the Third Choice on load.
You can set the VALUE in the Select control as the state value.
Don't forget, when handling the onChange event, that you will need to convert the event.target.value to string.

React-bootstrap FormControl Select placeholder

Trying to set up a control for a select field but even with placeholder set it still always auto selects the first item in the list.
It looks like this...
export function renderSelector({input, label, placeholder, meta:{touched, warning, error}, title, mandatory, fieldValues, fieldItemKeyFunc, fieldItemLabelFunc, props}) {
const mappedData = fieldValues.map(v => ({Id: fieldItemKeyFunc(v), Name: fieldItemLabelFunc(v)}));
let custom = props || {};
return (
<FormGroup controlId={input.name} validationState={touched && error ? 'error' : null}>
<Col xs={12}>
{renderLabel(title, label, mandatory)}
</Col>
<Col xs={12}>
<FormControl componentClass="select" placeholder={placeholder} name={input.name} {...input} {...custom}>
{
mappedData.map((item, index) => {
return (
<option key={index} value={item.Id}>{item.Name}</option>
)
})
}
</FormControl>
<FormControl.Feedback/>
{renderErrBlock(touched, warning, error)}
</Col>
</FormGroup>
);
}
When this renders the selector always starts with the first item selected, instead of the placeholder. How can I fix this?? I tried just adding a default first option and adjusting the css, but for Accessibility that doesn't work that well because the contrast levels
A bit late, but check if adding this option helps you:
<option key='blankChoice' hidden value />
Make sure to check the form value to a blank choice as well:
<Form.Control
value=''
>
You can do something like this:
Add a
<option disabled value={-1} key={-1}>
, and set your
<FormControl value={-1} ...
for a similar effect.
Just dropping a late answer, in case someone finds this useful.
React Bootstrap's Form as='select' doesn't seem to allow placeholder out of the box. Adding a blank value to Form.Control would render the input useless. Adding an extra option above mappedData.map(), as follows would work:
<option key = 'blankChoice' hidden value> --Your placeholder text-- </option>

Resources