I'm encountering some peculiar behavior while working on my website. I'm currently in the process of creating a dialog for the user registration form on my site. The website is built using Next.js, and for the user interface elements, I'm utilizing Material-UI's TextField components.
Password Autofill Issue: When Chrome suggests a password for my registration form, it doesn't seem to be correctly inserted into the input field Password and Confirm password. Consequently, the "Show Password" feature doesn't work as expected. Upon pressing Enter, I get an error message saying "Field required", which indicates that the input field is detected as empty, in fact I confirmed via Chrome's Inspect Element feature that the value is indeed empty.
Bizarre Chrome Popup Behavior: Another odd situation occurs when I accept Chrome's password suggestion but don't click on the "update password" prompt that appears in the top right corner. This results in some bizarre bugs. Immediately after accepting the password update, the "Password" text field functions perfectly, but the "Confirm Password" field exhibits the same issues as "Password Autofill Issue" (so Chrome writes above the textfield the password, but doesn't actually enter it). It appears to be placed above the text as if it's not actually inserted into the input.
Popup "Update Password" on Registration Form: I'm also puzzled as to why the "Update Password" popup appears when it's a registration form, not a login form.
Has anyone encountered similar issues with Chrome's password autofill and Next.js + MUI? I would greatly appreciate any insights or solutions to these problems.
Thank you in advance for your help!
Here is the registration form code:
<BlockDialog OnClose={props.OnClose} open={props.open}>
<div>
<Text
type={TextType.H1}
bold={TextBold.BOLD}
className="text-center italic mb-12">
REGISTRAZIONE
</Text>
<form className="w-full max-w-md" onSubmit={handleSubmit} noValidate>
<div className={FormField}>
<div className="md:w-6/12">
<Text
type={TextType.BlockTitle}
bold={TextBold.LIGHT}
className={TextForm}>
Nome
</Text>
</div>
<div className="md:w-6/12">
<TextField
autoComplete="given-name"
sx={CssTextField}
variant="outlined"
id="name"
name="name"
required
onFocus={(event) => {
setNameError(false);
setNameErrorHelperText(" ");
}}
onBlur={(event) => {
if (event.target.value.length === 0) {
setNameError(true);
setNameErrorHelperText("Il campo è obbligatorio");
} else {
setNameError(false);
setNameErrorHelperText(" ");
}
}}
onChange={(e) => setFirstName(e.target.value)}
error={nameError}
InputProps={{
inputProps: { maxLength: 1000 },
classes: {
input: InputField,
root: InputRoot,
},
}}
helperText={nameError ? nameErrorHelperText : " "}
/>
</div>
</div>
<div className={FormField}>
<label htmlFor="surname" className="md:w-6/12">
<Text
type={TextType.BlockTitle}
bold={TextBold.LIGHT}
className={TextForm}>
Cognome
</Text>
</label>
<div className="md:w-6/12">
<TextField
autoComplete="family-name"
sx={CssTextField}
variant="outlined"
id="surname"
name="surname"
required
onFocus={(event) => {
setSurnameError(false);
setSurnameErrorHelperText(" ");
}}
onBlur={(event) => {
if (event.target.value.length === 0) {
setSurnameError(true);
setSurnameErrorHelperText("Il campo è obbligatorio");
} else {
setSurnameError(false);
setSurnameErrorHelperText(" ");
}
}}
onChange={(e) => setLastName(e.target.value)}
error={surnameError}
InputProps={{
inputProps: { maxLength: 1000 },
classes: {
input: InputField,
root: InputRoot,
},
}}
helperText={surnameError ? surnameErrorHelperText : " "}
/>
</div>
</div>
{/* Alert: Se email non inserita dopo evento onBlur -> error text = Error, Helper text: Il campo è obbligatorio. */}
<div className={FormField}>
<label htmlFor="email" className="md:w-6/12">
<Text
type={TextType.BlockTitle}
bold={TextBold.LIGHT}
className={TextForm}>
Email
</Text>
</label>
<div className="md:w-6/12">
<TextField
autoComplete="email"
sx={CssTextField}
id="email"
name="email"
required
onFocus={(event) => {
setEmailError(false);
setEmailErrorHelperText(" ");
}}
onBlur={(event) => {
const emailRegex =
/^[A-z0-9\.\+_-]+@[A-z0-9\._-]+\.[A-z]{2,6}$/; // Regular expression for basic email validation
if (!emailRegex.test(event.target.value)) {
console.log("Email non valida");
setEmailError(true);
setEmailErrorHelperText("Email non valida");
} else {
setEmailError(false);
setEmailErrorHelperText(" ");
}
if (event.target.value.length === 0) {
setEmailError(true);
setEmailErrorHelperText("Il campo è obbligatorio");
}
}}
onChange={(e) => setEmail(e.target.value)}
error={emailError}
InputProps={{
inputProps: { maxLength: 1000 },
classes: {
input: InputField,
root: InputRoot,
},
}}
FormHelperTextProps={{
classes: "text-md",
}}
helperText={emailError ? emailErrorHelperText : " "}
/>
</div>
</div>
<div className={FormField}>
<label htmlFor="password" className="md:w-6/12">
<Text
type={TextType.BlockTitle}
bold={TextBold.LIGHT}
className={TextForm}>
Password
</Text>
</label>
<div className="md:w-6/12">
<TextField
sx={CssTextField}
required
variant="outlined"
id="password"
name="password"
value={password}
autoComplete="new-password"
type={showPassword ? "password" : "text"}
onFocus={(event) => {
setPasswordError(false);
setPasswordHelperText(" ");
}}
onChange={handlePasswordChange}
onBlur={handlePasswordOnBlur}
error={passwordError}
InputProps={{
inputProps: { maxLength: 1000 },
classes: {
input: InputField,
root: InputRoot,
},
endAdornment: (
<InputAdornment position="end">
<IconButton onClick={handleTogglePassword}>
{showPassword ? (
<Visibility className="text-white" />
) : (
<VisibilityOff className="text-white" />
)}
</IconButton>
<Tooltip
title={
<div>
<Typography className="text-white text-sm font-[Poppins]">
{getPasswordStrengthLabel(passwordStrength)}
</Typography>
</div>
}>
<IconButton onClick={handleInfoOpen}>
<Info className="text-white" />
</IconButton>
</Tooltip>
</InputAdornment>
),
}}
helperText={passwordError ? passwordHelperText : " "}
/>
</div>
</div>
<div className={FormField}>
<label htmlFor="confirmPassword" className="md:w-6/12">
<Text
type={TextType.BlockTitle}
bold={TextBold.LIGHT}
className={TextForm}>
Conferma Password
</Text>
</label>
<div className="md:w-6/12">
<TextField
autoComplete="new-password"
sx={CssTextField}
variant="outlined"
id="confirmPassword"
name="confirmPassword"
value={confirmPassword}
required
type={showConfirmPassword ? "password" : "text"}
onBlur={handleConfirmPasswordUguality}
onChange={handleConfirmPasswordUgualityOnChange}
error={confirmpasswordError}
InputProps={{
inputProps: { maxLength: 1000 },
classes: {
input: InputField,
root: InputRoot,
},
endAdornment: (
<InputAdornment position="end">
<IconButton onClick={handleToggleConfirmPassword}>
{showConfirmPassword ? (
<Visibility className="text-white" />
) : (
<VisibilityOff className="text-white" />
)}
</IconButton>
</InputAdornment>
),
}}
helperText={
confirmpasswordError ? passwordConfirmHelperText : " "
}
/>
</div>
</div>
I've tried a few things to address these issues:
To address the Password Autofill Issue, I added autocomplete="new-password" to indicate to the browser that it's a new password field. Despite these adjustments, the autofill feature doesn't work as expected, and the "Show Password" feature fails.
To address the Bizarre Chrome Popup Behavior, I reviewed my code to ensure that the registration form was correctly implemented, and the fields were labeled appropriately. However, the issue persists, and I can't seem to figure out why the "Update Password" popup appears in the context of a registration form.
It's worth noting that on websites like Epic Games, which also use MUI (Material-UI), when I click to accept the password suggestion, the field gets filled normally, and there is no "Update Password" popup.
For both issues, I was expecting Chrome's autofill to seamlessly insert suggested passwords into the input fields, and I was also anticipating normal behavior when accepting Chrome's password update prompt.