oninvalid attribute not rendering in React js - html

I am trying to add oninvalid attribute in HTML element under React js code. (using react hooks not class based)
const openEndedAnswer = answer => {
return (<>
<input type="text" className="form-control"
required="required"
oninvalid="this.setCustomValidity('Enter User Name Here')"
oninput="this.setCustomValidity('')"
maxLength="255"
id={`answer_${question.id}`}
name={`answer_${question.id}`}
onChange={e => updatePostForm(e)}
pattern=".*[^ ].*"
title=" No white spaces"
/>
</>)
}
But it never renders in the browser. all other attributes can be seen in F12 source view.

The attribute names should onInvalid instead of oninvalid and onInput instead of oninput. Additionally, you need to call the setCustomValidity function on the input field as follow (because the input field is the target of the event):
onInvalid={e => e.target.setCustomValidity('Enter User Name Here')}
onInput={e => e.target.setCustomValidity('')}

If you are using React with javascript this should work:
onInvalid={e => e.target.setCustomValidity('Your custom message')}
onInput={e => e.target.setCustomValidity('')}
But if you are working with React with typescript you also need to add this:
onInvalid={e => (e.target as HTMLInputElement).setCustomValidity('Enter User Name Here')}
onInput={e => (e.target as HTMLInputElement).setCustomValidity('')}

Try onInvalid instead:
export default function App() {
return (
<form>
Name:{" "}
<input
type="text"
onInvalid={() => console.log("working!")}
name="fname"
required
/>
<input type="submit" value="Submit" />
</form>
);
}

Related

AutoFocus on Text Input in React Using Styled Components

How do you make the TextInput in React using Styled Components to be autoFocus on page load?
I did using useEffect but it seems it doesn't autoFocus on the TextInput. I wanted the email text input to be focus outlined on page load.
Codesandbox -> CODESANDBOX
function App() {
const emailInput = useRef(null);
useEffect(() => {
if (emailInput.current) {
emailInput.current.focus();
}
}, []);
return (
<div>
<Input type="text" placeholder="Name" />
<Input type="email" placeholder="Email" innerRef={emailInput} />
</div>
);
}
As per styled-components documentation, in innerRef section, the innerRef is deprecated as of v4:
NOTE
The "innerRef" prop was removed in styled-components v4 in favor of the React 16 forwardRef API. Just use the normal ref prop instead.
Before React 16, there was no nice way to pass references up to the parent (except using callbacks). In React 16.3 createRef and forwardRef have been introduced for doing that, along with useRef hook later. Styled Components v4, has started to use that mechanism.
Therefore, you may use ref directly:
function App() {
const emailInput = useRef(null);
useEffect(() => {
if (emailInput.current) {
emailInput.current.focus();
}
}, []);
return (
<div>
<Input type="text" placeholder="Name" />
<Input type="email" placeholder="Email" ref={emailInput} />
</div>
);
}
On the other side, if the intent is only for focusing, as stated by #Andy, the autoFocus property may be a better choice:
function App() {
return (
<div>
<Input type="text" placeholder="Name" />
<Input type="email" placeholder="Email" autoFocus />
</div>
);
}
The React's autoFocus attribute is doing exactly the same thing as the code above (focus programmatically element on the mount). Do not confuse it with HTML's autofocus attribute, which behavior is inconsistent between browsers.

Input text no longer editable when using register with react-hook-form

I'm trying to set up react-fook-form to validate my forms, but when I use the register function on a text input (in my case the username input), this input is no longer editable, I can't type anything inside.
const {register, handleSubmit, formState: { errors }} = useForm();
const [username, setUsername] = useState('');
.....
<form onSubmit={handleSubmit(onSubmit)}>
<label htmlFor="username">Username : </label>
<input type="text" value={username}
onChange={e => setUsername(e.target.value)}
{...register('username', { required: 'Please, type in your username' })}
/>
{errors.username && <span style={{color: 'red'}}><br/>{errors.username.message}</span>}
<br/>
<label htmlFor="password">Password : </label>
<input type="password" value={password} onChange={e => setPassword(e.target.value)}/>
<br/>
<button type="submit">Login</button>
</form>
Ok I finally found the solution myself.
Since the version 7 of react-hook-form library, we have to place "onChange" inside the register function like so :
<input type="text" value={username} {...register('username', {
required: 'Please, type in your username',
onChange: e => setUsername(e.target.value)
})}/>

HTML password input still listening to key bindings while other inputs ignore the bindings

I am working on a legacy react app. There are keybindings in the project. For this example let's say when a user clicks "F", then the the app goes to full screen. The issue is that this keybinding is active for some input fields like email and password.
When I type into a non labeled input field, and i type "F", nothing happens, like:
<input
value={this.state.firstName}
placeholder="First Name"
name="firstName"
required
onChange={(event) => {return this.handleChange(event, 'firstName', event.target.value)}}/>
However if I have email or password as the label, then when i type "F", it goes full screen like
<input
value={this.state.password}
placeholder="Password"
name="password"
label="password"
required
onChange={(event) => {return this.handleChange(event, 'password', event.target.value)}}/>
private handleChange = (event: any, key: string, value: string) => {
event.preventDefault();
this.setState<never>({ [key]: value } as Partial<LoginFormState>);
}
How can i stop this behavior on password and email without undoing all of the key bindings and rebinding them?
Have you tried to use event.preventDefault() ?
<input
value={this.state.password}
placeholder="Password"
name="password"
label="password"
required
onChange={(event) => {
event.preventDefault();
return this.handleChange(event, 'password', event.target.value);
}}
/>
I'm not sure it's a clean solution though, you might want to provide more details for a better solution.
I just noticed, you should not pass event.target.value as an argument, since you already pass event. You can just access event.target.value directly into this.handleChange.

Why is OnChange not working when used in Formik?

I am trying to use Formik in React for a dummy app. I am not being able to type anything in either of the input boxes if I give value as a prop. On the other hand, if I skip the value props, then I can type in the boxes but the same is not reflected as the value while submitting.
Here's the code:
export default class DashboardPage extends React.Component {
render() {
return (
<Formik
initialValues={{ fname: "", lname: "" }}
onSubmit={(values) => {
alert(values.fname);
}}
render={({ values, handleChange, handleSubmit }) => (
<form onSubmit={handleSubmit}>
<input type="text" placeholder="First Name" name="fname" onChange={handleChange} value={values.fname} />
<input type="text" placeholder="Last Name" name="lname" onChange={handleChange} value={values.lname} />
<button type="submit>ADD<button/>
</form>
)}
/>
);
}
}
I may be very wrong here and might be over-looking a minor error, but any help/suggestion is appreciated!
export default class DashboardPage extends React.Component {
render() {
return (
<Formik
initialValues={{ fname: "", lname: "" }}
onSubmit={ (values) => alert(values.fname) }
>
{ props => (
<React.Fragment>
<form onSubmit={handleSubmit}>
<input type="text" placeholder="First Name" name="fname" onChangeText={props.handleChange('fname')} />
<input type="text" placeholder="Last Name" name="lname" onChangeText={props.handleChange('lname')} />
<button type="submit>ADD<button/>
</form>
</React.Fragment>
)}
</Formik>
)
}
}
Hi mate can you please try this?
Another possibility for this weird behavior is putting your component inside a function and sending the props as function parameters instead of using a functional component with props as parameters.
When a component is inside a function you lose react component lifecycle and the parameters will not refresh even when its values change.
Make sure your form elements are properly configured as react elements.
Mine was also not working, I gave id prop in my TextField and now it works
const formik = useFormik({
initialValues: {
username: "",
password: "",
},
onSubmit: (values) => {
console.log(values);
// onLogin(values.username, values.password);
},
});
<form onSubmit={formik.handleSubmit}>
<TextField
value={formik.values.username}
onChange={formik.handleChange}
id="username"
name="username"
variant="outlined"
style={TextField1style}
placeholder="Enter username"
fullWidth
required
//.
// .
// .
// other code
enter image description here

autocomplete= off not working in chrome

We are working on one web application in that one payment page is there.
In that we have two Text box one is for Credit Card Number and second one is for Verification Code and it type="Password".
Now problem is when page is load in google-chrome it found type="Password" it load Save email id in Credit Card Textbox and password in Verification Code.
Now try to solve this issue i was try out something like below.
<form autocomplete="off">
<asp:textbox autocomplete="off">
This above try is not work for me. i was googling it but by luck it's not work for me.
It appears that Chrome now ignores autocomplete="off" unless it is on the <form autocomplete="off"> tag since v34.
you can't cheat by create an hidden input over. Auto complete feature will get the first input text to fill data.
Method 1:
<form id="" method="post" action="" autocomplete="off">
<input type="text" style="display:none" />
<input type="password" style="display:none">
<asp:textbox autocomplete="off">
</form>
So put this before your textbox.
<input type="text" style="display:none" />
Method 2:
Change
autocomplete="off"
to
autocomplete="false"
Method 3:
Browser autofill in by readonly-mode.
<input type="password" readonly onfocus="this.removeAttribute('readonly');"/>
Method 4:
For username password combinations. Chrome heuristics looks for the pattern.
<input type="text" onfocus="this.type='password'">
Method 5:
jQuery
if ($.browser.webkit) {
$('input[name="password"]').attr('autocomplete', 'off');
$('input[name="email"]').attr('autocomplete', 'off');
}
This is the only solution that worked for me with both Autocomplete and Chrome's Autofill:
It works also after calling new this.props.google.maps.places.Autocomplete
Add autocomplete="off" on the form tag.
Set autocomplete="none" directly on the input inside the form and set the attribute again on focus.
<form autocomplete="off">
<input type="text" autocomplete="none" onfocus="this.setAttribute('autocomplete', 'none');"/>
</form>
this is works if you want to keep white as your input background color
<input type="password" class="form-control" id="password" name="password" placeholder="Password" readonly onfocus="this.removeAttribute('readonly');" style="background-color: white;">
use this solution
<input type="password" class="form-control auto-complete-off" id="password" name="password" autocomplete="new-password">
Chrome does not support autocomplete="off" at the form level for some input fields.
There are 2 solutions to do so:
In your form, if only two or three fields ignore autocomplete="off", then use the field name itself as the autocomplete value. i.e. autocomplete=
<form:input type="text" id="name" path="name" autocomplete="name"/>
Instead of defining field name manually for each field, use a script for all text typed input at the loading of the page or after.
if ($.browser.chrome) {
$(document).on('focus click tap', 'input', function() {
$(this).attr("autocomplete", 'block');
});
} else {
$(document).on('focus click tap', 'input', function() {
$(this).attr("autocomplete", 'off');
});
}
this solution is no longer working in chrome 95 and above,
Try using a normal input with type text, disable copy and pasting then add a style with property -webkit-text-security to add character mask on typing
#Not that this css property is not universal as mentionned here https://developer.mozilla.org/fr/docs/Web/CSS/-webkit-text-security
This works:
$(document).ready(function () {
setTimeout(() => {
$('input').attr("readonly", 'readonly');
$('input').attr("onfocus", "this.removeAttribute('readonly')");
}, 100);
});
This works well and also compatible with MDL (Material Design Light):
// Fix chrome's ignore on autocomplete=off
$('input[autocomplete=off]').each(function(){
var copy = $(this).clone();
copy.val('');
copy.removeAttr('autocomplete');
copy.insertAfter($(this));
$(this).hide().removeAttr('required id class');
});
This is how I solved the problem.
$("body").on('focus',':input', function (e) {
$(this).attr('autocomplete', 'off');
$(this).attr('autocapitalize', 'off');
$(this).attr('autocorrect', 'off');
$(this).attr('spellcheck', 'false');
});
OR
<input type="text" autocomplete="off" autocapitalize="off" autocorrect="off" spellcheck="false">
Is it not possible to use password type where text type is required?Regardless of the method presented above, Chrome unconditionally handles autocomplete if the name is the same.
So, I used a method to randomly change the name like this.
$(document).on('focus click tap'
, 'input[autocomplete][autocomplete!=""]:not([data-oname][data-oname!=""])'
, function() {
var oname = $(this).attr('name');
var newName = "random string"; // random string
$(this).attr({"data-oname":oname,"name":newName,autocomplete:newName});
// A random string should be set for name and autocomplete above.
}).on('blur', 'input[data-oname][data-oname!=""]', function() {
var oname = $(this).attr('data-oname');
$(this).attr({"name":oname}).removeAttr('data-oname');
});
automcomplete="off" or automcomplete="false"
or Define autocomplete inside Input field
$('input[name="password"]').attr('autocomplete', 'off');//Disable cache
very simple, you can follow this
let elements = document.querySelectorAll('[autocomplete="off"]');
elements.forEach(element => {
element.setAttribute("readonly", "readonly");
element.style.backgroundColor = "inherit";
setTimeout(() => {
element.removeAttribute("readonly");
}, 500);
})
Use autocomplete="new-password" instead of autocomplete="off". This is a newer, more specific value for the autocomplete attribute, which indicates that the field is for a new password, rather than just any input. This can help prevent the browser from auto-filling the field with old passwords.