Cross browser code to restrict user input using Javascript - javascript

I found this code through Stack Overflow to restrict users from putting numbers in a textbox, however it only works in Chrome and IE. Anyone know of any cross browser code to do this?
Note: we've already added the global attribute and it didn't work at all, this was the only one that fully worked in Chrome and IE.
<input type="text" onkeyup="this.value = this.value.replace(/[^a-z]/, '')" />

You want to catch onkeydown that is when the character gets inserted, not on onkeyup. You should also instead of removing the number, just prevent it from getting inserted with event.preventDefault()
<p>
<input type="text" onkeydown="event.key.match(/\d/) && event.preventDefault()" />
</p>
One thing I would recommend is removing the code from the html and putting it in a function so it is reusable like this:
// Wait till the dom is loaded
document.addEventListener('DOMContentLoaded', function(e) {
// Add the event to each input that has `data-type="number"`
document.querySelectorAll('[data-type=number]').forEach(function(input) {
// Add the event to the input
input.addEventListener('keydown', number)
})
})
function number(event) {
event.key.match(/\d/) && event.preventDefault()
}
<p>
<input type="text" data-type="number" />
</p>

Related

Element.focus() doesn't work when called within a function handler for addEventListener()

Here is my code. For some reason, this code does not give focus to the textbox with the id "dude" even though the paragraph tag with id "answer" does get the key code of the button that I clicked. It is like the line with the focus() command gets completely ignored.
document.getElementById("thing").addEventListener("keypress", function() {
myFunction(event);
});
function myFunction(event) {
document.getElementById("answer").innerHTML = event.keyCode;
document.getElementById("dude").focus();
}
<!DOCTYPE html>
<html>
<body>
<input type="text" id="thing">
<input type="text" id="dude">
<p id="answer"></p>
</body>
</html>
However, if I were to make a slight modification and put the line with the focus() outside of the addEventListener(), then the focus() would work. For example, the following code works:
document.getElementById("dude").focus();
document.getElementById("thing").addEventListener("keypress", function() {
myFunction(event);
});
function myFunction(event) {
document.getElementById("answer").innerHTML = event.keyCode;
}
<!DOCTYPE html>
<html>
<body>
<input type="text" id="thing">
<input type="text" id="dude">
<p id="answer"></p>
</body>
</html>
The above code would actually start by giving the "dude" textbox focus.
Is there any reason for this and anything that I can do about this?
The keypress event handler fires too early - the user hasn't finished pressing the key down and entering in the value at that point, so the focus reverts to the initial input field. See how if you change the focus after a setTimeout it'll work:
document.getElementById("thing").addEventListener("keypress", function() {
myFunction(event);
});
function myFunction(event) {
document.getElementById("answer").innerHTML = event.keyCode;
setTimeout(() => document.getElementById("dude").focus());
}
<input type="text" id="thing">
<input type="text" id="dude">
<p id="answer"></p>
Or watch for the keyup event instead:
document.getElementById("thing").addEventListener("keyup", function() {
myFunction(event);
});
function myFunction(event) {
document.getElementById("answer").innerHTML = event.keyCode;
document.getElementById("dude").focus();
}
<input type="text" id="thing">
<input type="text" id="dude">
<p id="answer"></p>
For example, the following code works:
Not exactly, because with that code, you're focusing the dude input on pageload, rather than when the thing input has stuff typed into it.
You also should avoid using keypress in modern code, it's deprecated:
This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.
Since this event has been deprecated, you should look to use beforeinput or keydown instead.
keyCode is too, technically, but the replacement for it - .code - isn't compatible everywhere.
Use the keyup event instead of keypress, because the default action of the keypress event sets the focus back to that input element.
document.getElementById("thing").addEventListener("keyup", function() {
myFunction(event);
});
function myFunction(event) {
document.getElementById("answer").innerHTML = event.keyCode;
document.getElementById("dude").focus();
}
<!DOCTYPE html>
<html>
<body>
<input type="text" id="thing">
<input type="text" id="dude">
<p id="answer"></p>
</body>
</html>
It seems like you are trying to shift focus from input "thing" to input "dude" after you complete a "keypress" or "keyup" on input "thing".
I don't understand the use case for this. But, IMO if you are trying to change the focus state after you input a value, I would recommend placing an event listener on the "change" event. You could simply press your "TAB" key on your keyboard after you are done inputting data into input "thing" and focus will be shifted to the input "dude" and the function will execute. Both achieved!
document.getElementById('thing').addEventListener('change', function (event) {
myFunction(event.target.value)
})
function myFunction(answer) {
document.getElementById('answer').innerText = answer
}
<input type="text" id="thing" />
<input type="text" id="dude" />
<p id="answer"></p>

IE 11 submit button click event not working under form tag?

I have one submit button .ButtonDownload inside form tag. Invoking this function is not causing any form submission. But it works in another browser like Chrome, Firefox.
function downloadrefinementlogs() {
$('form:first').data('postdata', 1);
$('.ButtonDownload').click(); }
I have tried solutions like inserting a dummy button before this button, return false/stopping event propagation. The button also has a name property but nothing works.
Surprisingly, if I create a exact replica of this button with changed name & id that also didn't work.
Edit 1 :
Some HTML captured from the DEV tool around the button
<input name="ZS_SG_Theme_wt1$block$wtMainContent$wt18$SilkUIFramework_wt2$block$wtContent$wt8$wt139" tabindex="26" class="Button ButtonDownload Hidden ThemeGrid_MarginGutter" id="ZS_SG_Theme_wt1_block_wtMainContent_wt18_SilkUIFramework_wt2_block_wtContent_wt8_wt139" type="submit" value="ButtonDownload">
The Hidden element, whom after removing fixes the issue somehow.
<input name="ZS_SG_Theme_wt1$block$wtMainContent$wt18$SilkUIFramework_wt2$block$wtContent$wt8$wtMultiGeoStateFieldInput" tabindex="70" class="Hidden MultiGeoStateField ThemeGrid_Width1 ThemeGrid_MarginGutter" id="ZS_SG_Theme_wt1_block_wtMainContent_wt18_SilkUIFramework_wt2_block_wtContent_wt8_wtMultiGeoStateFieldInput" aria-invalid="false" onkeydown="return OsEnterKey('ZS_SG_Theme_wt1_block_wtMainContent_wt18_SilkUIFramework_wt2_block_wtContent_wt8_wt334', arguments[0] || window.event);" type="text" maxlength="50">
As per the above comment from #Yu Zhou,
After observing the field I found that max-length attribute was causing the issue. The max length was set to 50 chars and the JSON that got stored was more than that, which caused the form submission to invalidate and block the download. But still I am unsure of how the it worked in Chrome even though the hidden field value had more characters than the max length.
check if your submit button has the attribute name, if not, try to add it to your submit button.
<input name="MyButton" type="submit" value="Submit">

setCustomValidity Bootstrap keep error popup

I've implement localization in my application, all this stuff is saved inside a php file. So I can easy do this:
<input class="form-control" type="text" required="" placeholder="username" oninvalid="this.setCustomValidity('<?php echo $this->lang->line('field_required'); ?>')"></input>
Now if I doesn't enter any text I can see the custom message, but if I fill the input I see again the popup as the form can't get the text inside.
It's a bug of Bootstrap?
EXAMPLE
https://jsfiddle.net/DTcHh/23662/
Using the onvalid won't work in some browsers like Safari or IE below 10. Use a custom event notifier for attaching the function.
Note: As you mentioned in the comment you can print the message from the data-invalid-message attribute from php and catch it using jQuery by .data('invalidMessage').
SEE WORKING EXAMPLE:
var myobj = jQuery('input.form-control');
myobj.on('keyup keypress blur change input', function() {
var messg = ($(this).data('invalidMessage'));
if (this.validity.typeMismatch) {
this.setCustomValidity(messg);
} else {
this.setCustomValidity('');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<form>
<input class="form-control" type="email" required placeholder="username" data-invalid-message="custom message from php here">
<button type="submit">
go
</button>
</form>
a workaround that I've found is:
onkeyup="this.setCustomValidity('');
the bug will be gone now.
TL&DR
Check element.validity.typeMismatch and then element.setCustomValidity('custom error msg') or element.setCustomValidity('') if there's no mismatch. You should listen on both keyup and blur events.
Explanation in Mozilla Developer documentation about setCustomValidity: https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Forms/Data_form_validation#Customized_error_messages.
But just keyup won't work properly if focus is not inside the input box we're modyfing.
Our previous example won't transfer the current state of the input box
if the user mouses away and clicks elsewhere on the page. We update
the component's values property only when the user presses Enter while
the focus is inside the input box.
Let's fix that by listening to the input box's blur event as well.
Above is from Angular 2 docs: User Input, paragraph "On blur" https://angular.io/docs/ts/latest/guide/user-input.html.
Simplified example
Below is example from Mozilla documentation with added blur keyEvent listener. Yup, refactoring needed, but mine version in Angular 2 looks vastly different and so probably will yours.
<form>
<label for="mail">I would like you to provide me an e-mail</label>
<input type="email" id="mail" name="mail">
<button>Submit</button>
</form>
And then
var email = document.getElementById("mail");
email.addEventListener("keyup", function (event) {
if (email.validity.typeMismatch) {
email.setCustomValidity("I expect an e-mail, darling!");
} else {
email.setCustomValidity("");
}
});
email.addEventListener("blur", function (event) {
if (email.validity.typeMismatch) {
email.setCustomValidity("I expect an e-mail, darling!");
} else {
email.setCustomValidity("");
}
});

JavaScript Form Validation: understanding function call

I am a total newbie to JavaScript, trying to find my way on form validation. I have been reading books as well as online tutorials and I found the following code online that is, in my opinion, very elegant and maintainable. Unfortunately, my skills in JavaScript are not good enough to understand everything. I am here to ask your help to understand the different functions defined.
I would like also to call the InstantValidation function on an event (onSubmit event) calling it in an independent .js file (based on event listener), so might you please also help me to call the function appropriately?
Here is the code:
<html>
<body>
<form id="myform" action="#" method="get">
<fieldset>
<legend><strong>Add your comment</strong></legend>
<p>
<label for="author">Name <abbr title="Required">*</abbr></label>
<input name="author" id="author" value=""
required="required" aria-required="true"
pattern="^([- \w\d\u00c0-\u024f]+)$"
title="Your name (no special characters, diacritics are okay)"
type="text" spellcheck="false" size="20" />
</p>
<p>
<label for="email">Email <abbr title="Required">*</abbr></label>
<input name="email" id="email" value=""
required="required" aria-required="true"
pattern="^(([-\w\d]+)(\.[-\w\d]+)*#([-\w\d]+)(\.[-\w\d]+)*(\.([a-zA-Z]{2,5}|[\d]{1,3})){1,2})$"
title="Your email address"
type="email" spellcheck="false" size="30" />
</p>
<p>
<label for="website">Website</label>
<input name="website" id="website" value=""
pattern="^(http[s]?:\/\/)?([-\w\d]+)(\.[-\w\d]+)*(\.([a-zA-Z]{2,5}|[\d]{1,3})){1,2}(\/([-~%\.\(\)\w\d]*\/*)*(#[-\w\d]+)?)?$"
title="Your website address"
type="url" spellcheck="false" size="30" />
</p>
<p>
<label for="text">Comment <abbr title="Required">*</abbr></label>
<textarea name="text" id="text"
required="required" aria-required="true"
title="Your comment"
spellcheck="true" cols="40" rows="10"></textarea>
</p>
</fieldset>
<fieldset>
<button name="preview" type="submit">Preview</button>
<button name="save" type="submit">Submit Comment</button>
</fieldset>
</form>
<script type="text/javascript">
(function()
{
//add event construct for modern browsers or IE
//which fires the callback with a pre-converted target reference
function addEvent(node, type, callback)
{
if(node.addEventListener)
{
node.addEventListener(type, function(e)
{
callback(e, e.target);
}, false);
}
else if(node.attachEvent)
{
node.attachEvent('on' + type, function(e)
{
callback(e, e.srcElement);
});
}
}
//identify whether a field should be validated
//ie. true if the field is neither readonly nor disabled,
//and has either "pattern", "required" or "aria-invalid"
function shouldBeValidated(field)
{
return (
!(field.getAttribute('readonly') || field.readonly)
&&
!(field.getAttribute('disabled') || field.disabled)
&&
(
field.getAttribute('pattern')
||
field.getAttribute('required')
)
);
}
//field testing and validation function
function instantValidation(field)
{
//if the field should be validated
if(shouldBeValidated(field))
{
//the field is invalid if:
//it's required but the value is empty
//it has a pattern but the (non-empty) value doesn't pass
var invalid =
(
(field.getAttribute('required') && !field.value)
||
(
field.getAttribute('pattern')
&&
field.value
&&
!new RegExp(field.getAttribute('pattern')).test(field.value)
)
);
//add or remove the attribute is indicated by
//the invalid flag and the current attribute state
if(!invalid && field.getAttribute('aria-invalid'))
{
field.removeAttribute('aria-invalid');
}
else if(invalid && !field.getAttribute('aria-invalid'))
{
field.setAttribute('aria-invalid', 'true');
}
}
}
//now bind a delegated change event
//== THIS FAILS IN INTERNET EXPLORER <= 8 ==//
//addEvent(document, 'change', function(e, target)
//{
// instantValidation(target);
//});
//now bind a change event to each applicable for field
var fields = [
document.getElementsByTagName('input'),
document.getElementsByTagName('textarea')
];
for(var a = fields.length, i = 0; i < a; i ++)
{
for(var b = fields[i].length, j = 0; j < b; j ++)
{
addEvent(fields[i][j], 'change', function(e, target)
{
instantValidation(target);
});
}
}
})();
</script>
</body>
</html>
In particular, the following code is not toally clear to me:
function addEvent(node, type, callback)
{
if(node.addEventListener)
{
node.addEventListener(type, function(e)
{
callback(e, e.target);
}, false);
}
else if(node.attachEvent)
{
node.attachEvent('on' + type, function(e)
{
callback(e, e.srcElement);
});
}
}
Any help (even a very brief explanation) would be highly appreciated !
#1 That's an event handler abstraction layer.
That one code section acts as an event handler, but works across various different browsers.
Most browsers use the addEventListener way of adding an event handler.
Some Internet Explorer versions use attachEvent: http://msdn.microsoft.com/en-us/library/ie/ms536343(v=vs.85).aspx
The function allows both ways to be used.
It has you pass in...
... the element you want to add an event to (node)
... what type of event you want to handle (type)
... what code you want executed by an event (callback)
Browser events: http://eloquentjavascript.net/chapter13.html
Abstraction layers: http://en.wikipedia.org/wiki/Abstraction_layer
Browser events are things like a page fulling loading (onload), something being clicked (onclick), an input being changed (onchange), a cursor going over an element (onmouseover), etc...
http://www.w3schools.com/js/js_htmldom_events.asp
#2 How to go about invoking validation onSubmit...
//now bind a change event to each applicable for field
The code below that goes through each input and textarea element and adds validation to each one with the onchange event. But what you want to do is validate onsubmit, which requires something like this, below the other addEvent call:
addEvent("myform","onsubmit", function(){
//de Go field by field and validate.
//de If all the fields pass, return true.
//de If one or more fields fail, return false.
})
If you want, you can even remove the onChange events. That is your choice. The main thing here is that you need to make sure to only validate the fields inside the form itself, which you can look at this answer for more information about: Best Practice: Access form elements by HTML id or name attribute? ... loop through all the elements, and validate each one within the addEvent I mentioned above which must return true or false to either allow the form to be submitted, or stop the submission and show that there were validation errors.
Please remember! As a personal bit of advice... On the server-side you still want to do validation, even if you have client-side validation. Browsers are easy to manipulate, so you might still have bad data sent to the server. Always, always do server-side validation regardless of client-side.
It just looks like a cross-browser function that attaches a handler (instantValidation) to the "change" or "onchange" events of all input and textarea controls.
I say cross-browser because of the presence of two separate event subscription methods. attachEvent is for older IE browsers (5-8) and addEventListener is generally for all modern browsers.
This addEvent function checks for the presence of said functions and uses whatever is available, giving preference to the "modern" way.
This is cross-browser code for attaching event handlers to the events raised by a DOM element. The function (addEvent) has arguments as follows:
node: the DOM node object to which an event will be attached (retrievable via a function like getElementById)
type: The event name, such as change, focus etc.
callback: The function to call when the event is raised.
This line: if(node.addEventListener) checks whether the node has a property called addEventListener. If the property is there, it behaves the same as true and the if block is entered.
The check for addEventListener is done because different browsers implement this event attachment function differently. Namely, IE versions before IE9 use only attachEvent.

alert when user attempts to enter key into textbox

So I've been searching for a bit now for code that will alert a user with a message (I know how to do an alert) when they try to enter any sort of text into a blank textbox.
Here is my code. What do I add to cause the sendMsg() function to be called?
<script>
function sendMsg()
{
alert ("change msg content here");
}
</script>
here is the HTML:
<body>
<input type="text" name="">
</body>
This might work:
<input type="text" name="foo" onKeyUp="sendMsg()" />
i.e. if I understood your question.
Cheers.
Use the onchange event.
<input type="text" name="" onchange="inputChanged();">
Have you tried giving your input an ID:
<input id="testing" type="text" name="" />
And then your javascript would be:
document.getElementById('testing').onfocus = function() {
// alert("change msg content here");
}
The first thing you'll need to do is attach an event listener to the focus event of the text box (which is triggered when you "focus" on a text box), to do that you'll need some way of locating it in the DOM. The simplest way to do that would be to add an id attribute like so:
<body>
<input type="text" name="" id="msgContent">
</body>
Now you can use the document.getElementById method to find the element:
var textBox = document.getElementById('msgContent');
Then you can attach an event listener:
textBox.addEventListener('focus', function () {
alert('change msg content here');
});
Keep in mind that the addEventListener method isn't available in some older versions of IE, instead there are other fallbacks which are detailed here.
Finally if you're using a library like jQuery, YUI, etc you normalize the browser differences for attaching event handlers:
//jQuery example
$('#msgContent').on('focus', function () {
alert('change msg content here');
});

Categories

Resources