Set min/max on TextField type="number"?
Solution 1:
The redux-form Field will pass props through to the component:
All other props will be passed along to the element generated by the component prop.
The TextField has a property named InputProps
which can be used to pass props to the Input component it renders. This is also true if you're using redux-form-material-ui
. Its TextField is simply a wrapper for the material-ui component.
The material-ui Input
component has a property named inputProps
which can be used to pass props to the input
element it renders.
Ok, so what do I do?
You need to pass props all the way through, from Field
, to TextField
, to Input
, to the input
element.
So if we set InputProps
on Field, it will be passed to TextField, which will pass it to the Input
component. If the object we pass contains an inner inputProps
(intentional lowercase 'i'), the Input component will pass it to the input
element.
A game of hot-proptato:
Basically, define an inputProps
object within InputProps
and apply it to Field
:
<Field
name="maxNodeSelectedCount"
component={TextField}
label="Max Node Selected Count"
type="number"
InputProps={{ inputProps: { min: 0, max: 10 } }}
format={formatOption}
normalize={normalizeOption}
{...propertyFieldDefaults}
/>
- Field passes InputProps to
TextField
- TextField passes the contents of InputProps to the
Input
component - Input passed the contents of inputProps to the
input
element
There is a caveat with this:
The current implementation of TextField sets its own value for inputProps
so that the inputClassName
is applied to the input
element.
By handing your own value of inputProps to TextField, you will overwrite the version applied by TextField, leaving inputClassName
unset. If are using inputClassName
you will need to include it in the inner inputProps
object.
EDIT: I have submitted an issue and pull request to address this caveat in a future release.
Solution 2:
Simply use your inputprops well
<TextField
type="number"
InputProps={{
inputProps: {
max: 100, min: 10
}
}}
label="what ever"
/>
notice the upper and lower case in the inputprops
credit to Ken Gregory
Solution 3:
You can use inputProps
to apply any attributes to the native input
element, including min
and max
.
<TextField type="number" inputProps={{ min: 4, max: 10 }} />
Edit: Please note that the min
/max
attributes do not prevent the user from typing invalid values in the TextField
. To restrict what the user can type, you can validate the value by adding onclick
handler like below:
const min = 0;
const max = 10;
export default function BasicTextFields() {
const [value, setValue] = useState<number>();
return (
<div>
<TextField
type="number"
inputProps={{ min, max }}
value={value}
onChange={(e) => {
var value = parseInt(e.target.value, 10);
if (value > max) value = max;
if (value < min) value = min;
setValue(value);
}}
/>
</div>
);
}
Solution 4:
The other answers didn't work for me.
Material UI has a section for 3rd party integration here
It really does the job of writing only numbers and not allowing negatives.
import NumberFormat from 'react-number-format';
function NumberFormatCustom(props) {
const { inputRef, onChange, ...other } = props;
return (
<NumberFormat
{...other}
getInputRef={inputRef}
allowNegative={false}
onValueChange={(values) => {
onChange({
target: {
name: props.name,
value: values.value,
},
});
}}
isNumericString
/>
);
}
<TextField
label="react-number-format"
value={values.numberformat}
onChange={handleChange}
name="numberformat"
id="formatted-numberformat-input"
InputProps={{
inputComponent: NumberFormatCustom,
}}
/>