Put length constraint in a TextField in react js
JavascriptReactjsEvent HandlingReact RouterJavascript Problem Overview
I am taking an input from the user of the card number and wants that the length entered by user must not be less than and more than 12. Here is the declaration of my textfield.
<TextField
id="SigninTextfield"
label="Aadhaar number"
id="Aadhar"
lineDirection="center"
required={true}
type="number"
maxLength={12}
style={styles.rootstyle}
erorText="Please enter only 12 digits number"
/>
Now I am not understanding whether to use javascript or any event handler for restricting the length.
Javascript Solutions
Solution 1 - Javascript
You can set the maxLength
property for limiting the text in text box.
Instead of onChange
method you can pass maxLength
to the inputProps
props of material-ui
TextField
.
<TextField
required
id="required"
label="Required"
defaultValue="Hello World"
inputProps={{ maxLength: 12 }}
/>
Basically we can edit all input element's native attrs via inputProps
object.
Link to TextField Api
Solution 2 - Javascript
I found another solution here.
<TextField
required
id="required"
label="Required"
defaultValue="Hello World"
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}/>
Solution 3 - Javascript
<TextField
autoFocus={true}
name="name"
onChange={handleChange}
placeholder="placeholder"
id="filled-basic"
variant="filled"
size="small"
fullWidth
inputProps={{
maxLength: 25,
}}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
),
}}
/>
Solution 4 - Javascript
<TextField
id="username"
name="username"
label={translate('username')}
onChange={handleChange}
onBlur={handleBlur}
value={values.username}
error={Boolean(errors.username) && touched.username}
helperText={(errors.username && touched.username && translate(errors.username))}
required
inputProps={{maxLength :20}}
/>
Solution 5 - Javascript
Is it worth noting that Material-ui <TextField />
component doesn not have a maxlength
property. However, the original html <input>
does. So you don't really need to create any extra function to get this to work. Just use the base <input>
attributes using inputProps
.
The actual answer is this:
inputProps={
{maxLength: 22}
}
// Result => <input maxlength="yourvalue" />
What this does is it sets the maxlength
attribute of the underlying <input>
resulting in: <input maxlength="yourvalue" />
. Another important thing to note here is that you use inputProps
and not InputProps
. The one you're targeting is the small letter inputProps
.
Solution 6 - Javascript
I discovered something weird on the behavior between TextField
and Input
from Material UI
They are very similar to each other, the problem I see is the following:
On the TextField component, if you use InputProps with capital "I"
, the Adorments are shown, but in the other hand if you use it as lowercase "inputProps
", the maxLength
Html attribute is TAKEN as valid
, but not the adorments
I ended up using INPUT
instead of a TextField
so you can use adorments
in
<TextField
variant="outlined"
required
fullWidth
error={errors.email}
id="email"
label={t("signup-page.label-email")}
name="email"
onChange={handleChange}
inputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton aria-label="toggle password visibility">
<EmailIcon />
</IconButton>
</InputAdornment>
),
maxLength: 120,
}}
/>
in the above code the adorment
is ignored, but maxLength
taken used as "inputProps
" camel case
The below code is a working example, as you might see, I embraced it as in the old style within a Form Control
, the input label and the input "outlinedInput
"
<FormControl variant="outlined" fullWidth>
<InputLabel htmlFor="firstName">Password</InputLabel>
<OutlinedInput
value={values.firstName}
autoComplete="outlined"
name="firstName"
variant="outlined"
required
fullWidth
error={errors.firstName}
id="firstName"
label={t("signup-page.label-firstname")}
onChange={handleChange}
autoFocus
inputProps={{ maxLength: 32 }}
/>
</FormControl>
Solution. My final recommendation, use an OutlinedInput
instead of a TextField
, so you can put in a separated way Adorments
and also maxLength
Below a working example with FormControl
OutlinedInput
, inputProps
- maxLength
and an end Adorment
Icon
<FormControl variant="outlined" fullWidth>
<InputLabel htmlFor="password">Password</InputLabel>
<OutlinedInput
value={values.passwordConfirm}
variant="outlined"
required
fullWidth
error={errors.passwordConfirm}
name="passwordConfirm"
label={t("signup-page.label-password-confirm")}
type={values.showPasswordConfirm ? "text" : "password"}
id="password-confirm"
onChange={handleChange}
inputProps= {{maxLength:32}}
endAdornment= {
<InputAdornment position="end">
<IconButton
aria-label="toggle password visibility"
onClick={handleClickShowPassword("passwordConfirm")}
onMouseDown={handleMouseDownPassword}
>
{values.showPasswordConfirm ? (
<Visibility />
) : (
<VisibilityOff />
)}
</IconButton>
</InputAdornment>
}
/>
{errors.passwordConfirm && (
<p className="error"> {errors.passwordConfirm} </p>
)}
</FormControl>
Solution 7 - Javascript
If you're using MUI 5, version 5.0.6
, due to a support for legacy, you will have to do something like this,
<TextField
id="standard-textarea"
label="A label"
placeholder="Some text here"
multiline
variant="standard"
defaultValue={"Hello"}
inputProps={{
maxLength: 255,
}}
InputProps={{
disableUnderline: true,
}}
/>
The TextField
supports both inputProps
and InputProps
, but some properties don't work vice versa.
maxLength
does not work as expected in InputProps
, and a property like disableUnderline
for the MUI 5 does not work as expected in inputProps
.
Be careful with a possible typo
with the i
.
See the API for more information, https://mui.com/api/text-field/.
Solution 8 - Javascript
The accepted answer won't work in Firefox for large numbers (greater than 16 digits). Numbers just behaves in a weird way.
For a 22 length field we ended up using this:
<TextField
required
validateOnBlur
field="cbu"
label="22 dígitos del CBU"
validate={validate.required}
type="text"
inputProps={
{maxLength: 22}
}
onInput={(e) => { e.target.value = e.target.value.replace(/[^0-9]/g, '') }}
/>
Basically, native maxLength
constraint for text fields, plus a conversion from string to numbers "on the fly".
Improvement
Also you may prefer to make this reusable and more semantic.
# constraints.js
const onlyNumbers = (e) => { e.target.value = e.target.value.replace(/[^0-9]/g, '') };
# form.js
<TextField
field="cbu"
label="22 dígitos del CBU"
inputProps={
{maxLength: 22}
}
onInput={(e) => onlyNumbers(e) }
Solution 9 - Javascript
The material-design <TextField />
component haven't any length
property.
You can create yours in the onChange()
method.
updateTextField(event,value){
if(value.length <= 12){
//Update your state
}
else{
//Value length is biggest than 12
}
}
<TextField
id="SigninTextfield"
label="Aadhaar number"
id="Aadhar"
lineDirection="center"
required={true}
type="number"
onChange={(e,v) => this.updateTextField(e,v)}
style={styles.rootstyle}
erorText="Please enter only 12 digits number"
/>
Solution 10 - Javascript
In your change handler, just write.
if (event.target.value.length !== maxLength ) return false;
Solution 11 - Javascript
I had a similar issue, but with TextareaAutosize. Unfortunately,
inputProps={{ maxLength: 12 }}
doesn't work with TextareaAutosize.
The below workaround works for TextareaAutosize and for both text and numbers. Inspired by the accepted answer to this question - https://stackoverflow.com/a/49130234/5236534
onInput = {(e) =>{
e.target.value = (e.target.value).toString().slice(0,10)
import * as React from 'react';
import TextareaAutosize from '@mui/material/TextareaAutosize';
export default function MinHeightTextarea() {
return (
<TextareaAutosize
aria-label="minimum height"
minRows={3}
placeholder="Minimum 3 rows"
style={{ width: 200 }}
onInput = {(e) =>{
e.target.value = (e.target.value).toString().slice(0,10)
}}
/>
);
}
Link to demo: Limiting character length in MUI TextareaAutosize