ng-change is only working for backspace and first entry - html

<input type="email" ng-keypress="testFunc()" ng-model="text"
id="femail" class="form-control margin" name="femail"
placeholder="Email*"/>
<p style="color: red;">The input field has changed {{count}} times.</p>
JS
$scope.count = 0;
$scope.testFunc = function() {
$scope.count++;
};
HTML
<input type="email" ng-change="testFunc()" ng-model="text"
id="femail" class="form-control margin" name="femail"
placeholder="Email*"/>
<p style="color: red;">The input field has changed {{count}} times.</p>
JS
$scope.count = 0;
$scope.testFunc = function() {
$scope.count++;
};
If I input : "abc". Result should be : 3 but I'm getting : 0 if i delete using backspack I'm getting: 1 I should get count++ on each input which i'm not getting. I'm trying this example:
https://w3schools.com/angular/tryit.asp?filename=try_ng_ng-change
in my code. Thank you
Clarification:
In the above provided w3school example and my code difference was that I was using
<input type="email">
and w3 was using
<input type="text">
So for "text input" each button press was considered as a change but in my case each change occurs when the email is changed or it has some different functionality for ng-change with
"input type="email".
So I got the counting right now by taking
<input type="text" />

I just copy/pasted the example from W3(you provided) to test.txt file and renamed it test.html and run in Firefox. All worked fine. I did not have to edit anything. Try what I did first then you will know if it a typo or anything else. But the code is working correctly.

You can use
<input type="text" />
This is much better solution for your counter to work on.
If you want a counter use type="text" not "email". Browser treat both of them differently.

Related

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.

ng-model binding not updating

I have some models being updated from a look-up. It is the 1st line that's not updating (but the other models are updated correctly). I tried wrapping it in an $apply but that made matters worse:
function mapRequestorToForm() {
//PrimaryCtyhocnOrInnCode binding not updating
//$scope.$apply(function() {
dmpe.form.PrimaryCtyhocnOrInnCode = dmpe.requestor.primaryInnCode;
dmpe.form.hotelName = dmpe.requestor.hotelName;
dmpe.form.requestor = dmpe.requestor;
//});
}
Here's the input element. Funny thing, the pre element is displaying the correct value.
<label for="primaryCtyhocn">Primary Inn Code/ CTYHOCN</label>
<input type="text" id="primaryCtyhocn" name="primaryCtyhocn" ng-model="dmpe.form.PrimaryCtyhocnOrInnCode"
class="form-control required disabled-bg" disabled
placeholder="Primary Inn Code/ Ctyhocn"
ng-minlength="5" ng-maxlength="7" required />
<pre>PrimaryCtyhocnOrInnCode: {{dmpe.form.PrimaryCtyhocnOrInnCode}}</pre>
this one is updated correctly (line 2 of the map method, using the same source object with similar disabled attributes:
<div class="col-md-4">
<label for="hotelName">Hotel Name</label>
<input type="text" id="hotelName" name="hotelName" ng-model="dmpe.form.hotelName"
class="form-control required disabled-bg" disabled
placeholder="Hotel Name required" required />
</div>
In case someone else runs into this and their brain is failing them as mine did. It was an issue with the incoming data, it failed the max length constraint. Thanks to Michael Perrenoud!

An invalid form control with name='' is not focusable. WITHOUT ANY REQUIRED OR HIDDEN INPUTS

I'm facing the well known Chrome's "not-focusable-input" error but my situation is different from the explained in the other post I could find there.
I have this error message duplicated first on a well pointed input, this input has no required attribute:
The code:
<fieldset>
<label>Total (montaje incl.)</label>
<input type="number" id="priceFinal" name="priceFinal"> €
</fieldset>
The error:
An invalid form control with name='priceFinal' is not focusable.
While the user is filling the form this field gets its value by a js script with jquery. The user type a size in another input, the script do its maths with the size value and then put the outcome in the 'priceFinal' input with the jquery function: .val()
In the browser we can see that the input is correctly filled and no errors are displayed at that time. And with the 'novalidate' solution everything goes fine, so it couldn't be responsible for the nofocusable error, I think.
Then I got the same error with an input with no name which I didn't write and doesn't exist in my DOM:
An invalid form control with name='' is not focusable.
This is weird because the only input without name in my form is the type:submit one
<input type="submit" class="btn btn-default" value="Ver presupuesto" />
I have a few required fields but I've always checked that their are all filled when I send the form. I paste it just in case it could help:
<fieldset>
<input type="text" id="clientName" name="clientName" placeholder="Nombre y apellidos" class="cInput" required >
<input type="text" id="client_ID" name="client_ID" required placeholder="CIF / NIF / DNI" class="cInput">
</fieldset>
<fieldset>
<input type="text" id="client_add" name="client_add" placeholder="Dirección de facturación" class="addInput" required >
</fieldset>
<fieldset>
<input type="text" id="client_ph" name="client_ph" placeholder="Teléfono" class="cInput" required>
<input type="email" id="client_mail" name="client_mail" placeholder="Email" class="cInput" required>
</fieldset>
The novalidate solution clears the error but it doesn't fix it, I mean there must be a way to solve it with no hacks.
Any one have any idea of what's might going on?
Thanks
I had the same problem, and everyone was blaming to the poor hidden inputs been required, but seems like a bug having your required field inside a fieldset.
Chrome tries to focus (for some unknown reason) your fieldset instead of your required input.
This bug is present only in chrome I tested in version 43.0.2357.124 m.
Doesn't happen in firefox.
Example (very simple).
<form>
<fieldset name="mybug">
<select required="required" name="hola">
<option value=''>option 1</option>
</select>
<input type="submit" name="submit" value="send" />
</fieldset>
</form>
An invalid form control with name='mybug' is not focusable.
The bug is hard to spot because usually fieldsets don't have a name so name='' is a WTF! but slice piece by piece the form until I found the culprid.
If you get your required input from the fieldset the error is gone.
<form>
<select required="required" name="hola">
<option value=''>option 1</option>
</select>
<fieldset name="mybug">
<input type="submit" name="submit" value="send" />
</fieldset>
</form>
I would report it but I don't know where is the chrome community for bugs.
Thanks to this post, I saw that my problem also rested with Chrome trying to focus on my fieldsets, instead of the input field.
To get a better response from the console:
Assign every DOM element a new name
Set every input & select style.display to 'block'
Changed the type of input[type="hidden"] elements to 'text'
function cleanInputs(){
var inputs = document.getElementsByTagName( 'input' ),
selects = document.getElementsByTagName( 'select' ),
all = document.getElementsByTagName( '*' );
for( var i=0, x=all.length; i<x; i++ ){
all[i].setAttribute( 'name', i + '_test' );
}
for( var i=0, x=selects.length; i<x; i++ ){
selects[i].style.display = 'block';
}
for( var i=0, x=inputs.length; i<x; i++ ){
if( inputs[i].getAttribute( 'type' ) === 'hidden' ){
inputs[i].setAttribute( 'type', 'text' );
}
inputs[i].style.display = 'block';
}
return true;
}
In the console, I ran cleanInputs() and then submitted the form.
The result, from the console, was:
An invalid form control with name='28_test' is not focusable.
An invalid form control with name='103_test' is not focusable.
Then, switching over to the Web Developer "Elements" view, I was able to find "28_test" and "103_test" (both fieldsets) -- confirming that my problem was a required input field, nested inside a fieldset.
While I was writting the question I realized one thing: the value the script was putting into the 'priceFinal' field sometimes was a decimal number.
In this case the solution was to write the step attribute for this input:
... step="any" ...
Step on w3s
So this 'nofocusable' bug is not only a required and hidden fields issue, it's also generated by format conflicts.
Nach gave me the best pointer... (y) I also had a input type="number" with step="0.1" and the console shows me this error while validating: An invalid form control with name='' is not focusable.
remove the step="0.1" on the element and now the form can be validated
I had the same issue so I removed required="required" from the troublesome fields.
If you get the error when jQuery function is executed, try to put "return false" on your function, or function(e) { e.preventDefault(); ... }
i had this issue once. to fix it, add
novalidate
as an attribute to the form. e.g
<form action="" novalidate>
....
</form>
In my case, the input element did not have a required attribute but it was hidden. and the problem was while it was hidden, it had a value in it. I guess if an input field is hidden it shouldn't have a value too, aside required attribute.
When I remove the value through my javascript code, everything works fine.
Element is hidden, No required Attribute, No value. Worked
Here is the solution....
<form>
<input type="text" ng-show="displayCondition" ng-required="displayCondition"/>
</form>
Many people do not realize that passing false into ng-required disables the directive.

How do you automatically set text box to Uppercase?

I am using the following style attribute to set the user input to uppercase so that when the user starts typing in the text box for example railway, then it should be altered to capital letters like RAILWAY without the user having to press the Caps-lock button.
This is the code I am using for the input:
<input type = "text" class = "normal" name = "Name" size = "20" maxlength = "20"> <img src="../images/tickmark.gif" border="0" style='text-transform:uppercase'/>
But I am not getting the desired output by using this attribute.
You've put the style attribute on the <img> tag, instead of the <input>.
It is also not a good idea to have the spaces between the attribute name and the value...
<input type="text" class="normal"
name="Name" size="20" maxlength="20"
style="text-transform:uppercase" />
<img src="../images/tickmark.gif" border="0" />
Please note this transformation is purely visual, and does not change the text that is sent in POST.
NOTE: If you want to set the actual input value to uppercase and ensure that the text submitted by the form is in uppercase, you can use the following code:
<input oninput="this.value = this.value.toUpperCase()" />
I think the most robust solution that will insure that it is posted in uppercase is to use the oninput method inline like:
<input oninput="this.value = this.value.toUpperCase()" />
EDIT
Some people have been complaining that the cursor jumps to the end when editing the value, so this slightly expanded version should resolve that
<input oninput="let p=this.selectionStart;this.value=this.value.toUpperCase();this.setSelectionRange(p, p);" />
The answers with the text-transformation:uppercase styling will not send uppercased data to the server on submit - what you might expect. You can do something like this instead:
For your input HTML use onkeydown:
<input name="yourInput" onkeydown="upperCaseF(this)"/>
In your JavaScript:
function upperCaseF(a){
setTimeout(function(){
a.value = a.value.toUpperCase();
}, 1);
}
With upperCaseF() function on every key press down, the value of the input is going to turn into its uppercase form.
I also added a 1ms delay so that the function code block triggers after the keydown event occured.
UPDATE
Per recommendation from Dinei, you can use oninput event instead of onkeydown and get rid of setTimeout.
For your input HTML use oninput:
<input name="yourInput" oninput="this.value = this.value.toUpperCase()"/>
The problem with the first answer is that the placeholder will be uppercase too. In case you want ONLY the input to be uppercase, use the following solution.
In order to select only non-empty input element, put required attribute on the element:
<input type="text" id="name-input" placeholder="Enter symbol" required="required" />
Now, in order to select it, use the :valid pseudo-element:
#name-input:valid { text-transform: uppercase; }
This way you will uppercase only entered characters.
try
<input type="text" class="normal"
style="text-transform:uppercase"
name="Name" size="20" maxlength="20">
<img src="../images/tickmark.gif" border="0"/>
Instead of image put style tag on input because you are writing on input not on image
Set following style to set all textbox to uppercase:
input { text-transform: uppercase; }
Using CSS text-transform: uppercase does not change the actual input but only changes its look.
If you send the input data to a server it is still going to lowercase or however you entered it. To actually transform the input value you need to add javascript code as below:
document.querySelector("input").addEventListener("input", function(event) {
event.target.value = event.target.value.toLocaleUpperCase()
})
<input>
Here I am using toLocaleUpperCase() to convert input value to uppercase.
It works fine until you need to edit what you had entered, e.g. if you had entered ABCXYZ and now you try to change it to ABCLMNXYZ, it will become ABCLXYZMN because after every input the cursor jumps to the end.
To overcome this jumping of the cursor, we have to make following changes in our function:
document.querySelector("input").addEventListener("input", function(event) {
var input = event.target;
var start = input.selectionStart;
var end = input.selectionEnd;
input.value = input.value.toLocaleUpperCase();
input.setSelectionRange(start, end);
})
<input>
Now everything works as expected, but if you have slow PC you may see text jumping from lowercase to uppercase as you type. If this annoys you, this is the time to use CSS, apply input: {text-transform: uppercase;} to CSS file and everything will be fine.
The issue with CSS Styling is that it's not changing the data, and if you don't want to have a JS function then try...
<input onkeyup="this.value = this.value.toUpperCase()" />
on it's own you'll see the field capitalise on keyup, so it might be desirable to combine this with the style='text-transform:uppercase' others have suggested.
Various answers here have various problems, for what I was trying to achieve:
Just using text-transform changes the appearance but not the data.
Using oninput or onkeydown changes the cursor position, so you can't, for instance, click in the middle of your existing input and edit it.
Saving the position works, but just seemed a bit kludgey.
It felt cleaner to me to just break the problem up into two parts: upper-casing what I'm typing while I type (text-transform), and upper-casing the submitted data (run toUpperCase onchange):
<input id = "thing" onchange="this.value = this.value.toUpperCase(); pr()" style=text-transform:uppercase /><p>
<b><span id="result"></span></b>
<script>function pr() {document.getElementById("result").innerHTML = document.getElementById("thing").value}</script>
Type something in that, hit return or click out of the input, then click in the middle of your previous entry, add some lc text, hit return...
IN HTML input tag just style it like follows
<input type="text" name="clientName" style="text-transform:uppercase" required>
in backed php/laravel use:
$name = strtoupper($clientName);
This will both show the input in uppercase and send the input data through post in uppercase.
HTML
<input type="text" id="someInput">
JavaScript
var someInput = document.querySelector('#someInput');
someInput.addEventListener('input', function () {
someInput.value = someInput.value.toUpperCase();
});
As nobody suggested it:
If you want to use the CSS solution with lowercase placeholders, you just have to style the placeholders separately. Split the 2 placeholder styles for IE compatibility.
input {
text-transform: uppercase;
}
input:-ms-input-placeholder {
text-transform: none;
}
input::placeholder {
text-transform: none;
}
The below input has lowercase characters, but all typed characters are CSS-uppercased :<br/>
<input type="text" placeholder="ex : ABC" />
<input style="text-transform:uppercase" type = "text" class = "normal" name = "Name" size = "20" maxlength = "20"> <img src="../images/tickmark.gif" border="0"/>
I went with the style text-transform:uppercase thing from poster. Then I just did the uppercase thing in php as well. Some people working too hard with that javascript.
You were close with the style being in the wrong place. You were trying to uppercase an image instead of the input.
$name = strtoupper($_POST['Name']);
I don't know why I wanted to throw in some extra stuff if it's a php page. This is something I like to do make it smoother for the person filling out the form.
<input style="text-transform:uppercase" type = "text" class = "normal" name = "Name" size = "20" maxlength = "20" value="<?php echo $name; ?>"> <img src="../images/tickmark.gif" border="0"/>
That's assuming you're using PHP as the backend and posting to the same page you are on. This will keep the user from having to fill out that part of the form again. Less annoying for the person filling out the form.
Try below solution, This will also take care when a user enters only blank space in the input field at the first index.
document.getElementById('capitalizeInput').addEventListener("keyup", () => {
var inputValue = document.getElementById('capitalizeInput')['value'];
if (inputValue[0] === ' ') {
inputValue = '';
} else if (inputValue) {
inputValue = inputValue[0].toUpperCase() + inputValue.slice(1);
}
document.getElementById('capitalizeInput')['value'] = inputValue;
});
<input type="text" id="capitalizeInput" autocomplete="off" />
Just use this oninput in your input field:
<div class="form-group col-2">
<label>PINCODE</label>
<input type="number" name="pincode" id="pincode" class="form-control" minlength="6" maxlength="6" placeholder="Enter Pincode" oninput="this.value = this.value.toUpperCase()" autocomplete="off">
</div>
Just add in your input(style="text-transform:uppercase")
<input type="text" class="normal" style="text-transform:uppercase" name="Name" size="20" maxlength="20">
<script type="text/javascript">
function upperCaseF(a){
setTimeout(function(){
a.value = a.value.toUpperCase();
}, 1);
}
</script>
<input type="text" required="" name="partno" class="form-control" placeholder="Enter a Part No*" onkeydown="upperCaseF(this)">

How can I change or remove HTML form validation default error messages?

For example I have a textfield. The field is mandatory, only numbers are required and length of value must be 10. When I try to submit form with value which length is 5, the default error message appears: Please match the requested format
<input type="text" required="" pattern="[0-9]{10}" value="">
How can I change HTML form validation errors default messages?
If the 1st point can be done, is there a way to create some property files and set in that files custom error messages?
This is the JavaScript solution:
<input type="text"
pattern="[a-zA-Z]+"
oninvalid="setCustomValidity('Please enter Alphabets.')"
onchange="try{setCustomValidity('')}catch(e){}" />
The "onchange" event needs when you set an invalid input data, then correct the input and send the form again.
I've tested it on Firefox, Chrome and Safari.
But for Modern Browsers:
Modern browsers didn't need any JavaScript for validation.
Just do it like this:
<input type="text"
pattern="[a-zA-Z]+"
title="Please enter Alphabets."
required="" />
When using pattern= it will display whatever you put in the title attrib, so no JS required just do:
<input type="text" required="" pattern="[0-9]{10}" value="" title="This is an error message" />
<input type="text" pattern="[a-zA-Z]+"
oninvalid="setCustomValidity('Plz enter on Alphabets ')" />
I found this code in another post.
HTML:
<input type="text" pattern="[0-9]{10}" oninvalid="InvalidMsg(this);" name="email" oninput="InvalidMsg(this);" />
JAVASCRIPT :
function InvalidMsg(textbox) {
if(textbox.validity.patternMismatch){
textbox.setCustomValidity('please enter 10 numeric value.');
}
else {
textbox.setCustomValidity('');
}
return true;
}
Fiddle Demo
To prevent the browser validation message from appearing in your document, with jQuery:
$('input, select, textarea').on("invalid", function(e) {
e.preventDefault();
});
you can remove this alert by doing following:
<input type="text" pattern="[a-zA-Z]+"
oninvalid="setCustomValidity(' ')"
/>
just set the custom message to one blank space
you can change them via constraint validation api: http://www.w3.org/TR/html5/constraints.html#dom-cva-setcustomvalidity
if you want an easy solution, you can rock out civem.js, Custom Input Validation Error Messages JavaScript lib
download here: https://github.com/javanto/civem.js
live demo here: http://jsfiddle.net/hleinone/njSbH/
The setCustomValidity let you change the default validation message.Here is a simple exmaple of how to use it.
var age = document.getElementById('age');
age.form.onsubmit = function () {
age.setCustomValidity("This is not a valid age.");
};
I Found a way Accidentally Now:
you can need use this: data-error:""
<input type="username" class="form-control" name="username" value=""
placeholder="the least 4 character"
data-minlength="4" data-minlength-error="the least 4 character"
data-error="This is a custom Errot Text fot patern and fill blank"
max-length="15" pattern="[A-Za-z0-9]{4,}"
title="4~15 character" required/>
I found a bug on Mahoor13 answer, it's not working in loop so I've fixed it with this correction:
HTML:
<input type="email" id="eid" name="email_field" oninput="check(this)">
Javascript:
function check(input) {
if(input.validity.typeMismatch){
input.setCustomValidity("Dude '" + input.value + "' is not a valid email. Enter something nice!!");
}
else {
input.setCustomValidity("");
}
}
It will perfectly running in loop.
This is work for me in Chrome
<input type="text" name="product_title" class="form-control"
required placeholder="Product Name" value="" pattern="([A-z0-9À-ž\s]){2,}"
oninvalid="setCustomValidity('Please enter on Producut Name at least 2 characters long')" />
To set custom error message for HTML validation use,
oninvalid="this.setCustomValidity('Your custom message goes here.')"
and to remove this message when user enters valid data use,
onkeyup="setCustomValidity('')"
As you can see here:
html5 oninvalid doesn't work after fixed the input field
Is good to you put in that way, for when you fix the error disapear the warning message.
<input type="text" pattern="[a-zA-Z]+"
oninvalid="this.setCustomValidity(this.willValidate?'':'your custom message')" />