Centralized way/system for defining input mask - javascript

We currently use the following logic to mask the inputs:
Set a specific class to several inputs <input type="text" class="typenumdec" />
In document.ready() bind a propertychange event with the rules:
$('table tbody > tr > td.tiponumdec').children('input[type=text], input[type=number]')
.add('input[type=text].tiponumdec, input[type=number].tiponumdec').bind('input propertychange', function () {
$(this).val($(this).val().replace(/[^0-9,]/g, ''));
});
But we wanted to centralize the logic and make it more streamlined for our developers so they dont have to add/modify the bindings.
Something like this:
Developer defines somewhere the format and its name (javascript globals? key/value array?):
var formatmoney1 ='5.2'; //5 integers and 2 decimals
var formatmoney2 ='5.3'; //5 integers and 3 decimals
var formatdays ='3'; //3 integers
Developer sets the format to a data-atribute or css class (recommended option?)
<input type="text" class="formatmoney1" data-formatx="formatmoney1" />
On document.ready() a generic function parses the format definitions and the inputs in order to mask them depending on its assigned format
PS: we saw this plugin that seems interesting in order to cover part of the mask logic (your opinions?): http://igorescobar.github.io/jQuery-Mask-Plugin/

We are currently using HTML 5 to make 99% of all validations. You can use them in a very understandable and developer-friendly way.
For example this code will prevent entering everything else then an email address:
<input type="email" />
Or use this with custom regex:
<input type="text" name="dutch_zip_code" pattern="[A-Za-z]{4}[0-9]{2}" />
You can also set the pattern in javascript / jquery like this:
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript" src="jquery.mask.js"></script>
</head>
<body>
<input type="text" name="dutch_zip_code" data-validation-type="dutch_zip_code" />
<script>
$(document).ready(function()
{
$('input[type=text]').each( function()
{
var type = $(this).data('validation-type');
if (type == 'dutch_zip_code')
{
$(this).attr('pattern', '[A-Za-z]{4}[0-9]{2}');
//
// Use jquery mask plugin:
// https://plugins.jquery.com/mask/
//
$(this).mask('0000SS');
}
}
);
});
</script>
</body>
</html>
You can use modernizr for backwards compatibility.

As mentioned in comments, if you use bootstrap (http://getbootstrap.com/), there is the excellent Jazny Bootstrap (http://jasny.github.io/bootstrap/) plugin which makes input masks extremely easy and tidy.
Here is a fiddle which demonstrates your 3 formats: http://jsfiddle.net/JNfxa/9/
Here is the HTML:
<label>formatmoney1</label>
<input type="text" class="form-control" data-mask="99999.99" data-placeholder=" ">
<label>formatmoney2</label>
<input type="text" class="form-control" data-mask="99999.999" data-placeholder="0">
<label>formatdays</label>
<input type="text" class="form-control" data-mask="999" data-placeholder="#">
And that is it, no extra CSS or JS required.
I have used three different examples for the data-placeholder attribute, this is the character that appears for the empty digits that the user must complete, default is '_'. Where I have used '9', this will restrict the user to enter a number, there are other options detailed here: http://jasny.github.io/bootstrap/javascript/#inputmask
Now, to centralise the data-mask to a single, maintainable variable, you could bind it to an observable ViewModel property using KnockoutJS. (http://knockoutjs.com/index.html)
You can do a lot more than this, but here is an updated fiddle: http://jsfiddle.net/JNfxa/11/
Now there is some JS, to declare our observable properties containing each of the masks:
vm = {};
vm.formatmoney1Mask = ko.observable("99999.99");
vm.formatmoney2Mask = ko.observable("99999.999");
vm.formatdaysMask = ko.observable("999");
ko.applyBindings(vm);
Knockout has an attr binding, which lets you bind the value of an observable property to a custom HTML attribute of your choice. More details here: http://knockoutjs.com/documentation/attr-binding.html
The HTML changes slightly to bind the data-mask attribute instead of setting it directly:
<label>formatmoney1</label>
<input type="text" class="form-control" data-bind="attr: { 'data-mask': vm.formatmoney1Mask }" data-placeholder=" ">
<label>formatmoney2</label>
<input type="text" class="form-control" data-bind="attr: { 'data-mask': vm.formatmoney2Mask }" data-placeholder="0">
<label>formatdays</label>
<input type="text" class="form-control" data-bind="attr: { 'data-mask': vm.formatdaysMask }" data-placeholder=" ">
What's great about this, is you can update the mask observable on the fly, and the HTML will automatically update without refreshing the page, so you could have e.g. a radio button control to choose different input mask types.

I would HIGHLY recommend taking a look at this plugin- Robin Herbots inputMask
This plugin is robust, has alot of callbacks/options and is actively developed. One of the major advantages of this plugin are the extensions which is where you define masks and aliases.
You can define a mask however you want..if you wanted to extend the out of box decimal mask definition you could do it like this...
$.extend($.inputmask.defaults.aliases,
{
'formatmoney1':
{
mask: "99999.99",
placeholder: "_____.__",
alias: "decimal"
},
'formatmoney2':
{
mask: "99999.999",
placeholder: "_____.___",
alias: "decimal"
}
}
Once you have defined your mask, and extended the out of box decimal definition then you could pick up all elements and apply the inputmask.
$(document).ready(function()
{
$('.formatmoney1').inputmask('formatmoney1');
$('.formatmoney2').inputmask('formatmoney2');
});
This mask allows you to have a very high amount of control through the numerous callbacks and is highly configurable by setting default options.
Another option you have with using this plugin is to take advantage of the data-inputmask attribute. For example,
<input type="text" data-inputmask="'alias':'formatmoney1'" />
Be sure you look through the Usage page as well as the extension files, there are a few of them but it looks like you will want to use the jquery.inputmask.numeric.extensions.js

Related

characters in field

I've been doing a lot of research on this and still can't find a good solution. Basically, I have this field in my form that should ONLY allow numbers. However, I'm able to enter mac special characters inside that field by doing:
Hold down option + shift and then pressing any button from keyboard (example: h j k l u i , etc).
Please see attached picture.
Can anyone help me on NOT allowing such characters inside the ID field? Thanks a lot in advance!
Here's my code:
LIVE DEMO
ID: <input formControlName="userid" type="text" pKeyFilter="num" placeholder="Numbers" pInputText>
There are many approaches to this problem. All of the provided solutions should work. My recommendation is Approach 2.
Approach 1
You can try to remove non number characters on the input event like this
<input
formControlName="userid"
type="text"
placeholder="Numbers"
oninput="javascript: this.value = this.value.replace(new RegExp('[^0-9]', 'gm'), '')"
pInputText
/>
Modified Demo
I tested this in Firefox and Chrome on MacOS and it seems to work fine.
Approach 2
To do this from your angular module:
Use a simple text input
<input
formControlName="userid"
type="text"
placeholder="Number"
pInputText
/>
Listen to changes and patch the value accordingly. Don't forget to register your observers on init.
registerChangeObservers() {
this.registrationFormGroup.get("userid").valueChanges.subscribe(val => {
this.registrationFormGroup.patchValue({
'userid': val.replace(new RegExp('[^0-9]', 'gm'), '')
}, { emitEvent: false });
});
}
ngOnInit() {
this.registerChangeObservers();
}
Especially note the { emitEvent: false } part. You need to set this to avoid recursion. This approach can fail if your model becomes invalid and therefore it's value changes to nil. For example this can happen if you set your input type to number, but a user manages to input a non number character. To avoid this make sure the input validation doesn't fail on special characters, e.g. by setting the input type to text.
Demo here
Approach 3
To avoid the display of modifying characters you can also listen to input events (i.e. key presses) instead of actual value changes. This is equivalent to approach 1.
To do so use this input
<input
formControlName="userid"
type="text"
placeholder="Number"
pInputText
(input)="onPress($event)"
/>
and add this function to your controller
onPress($event) {
this.registrationFormGroup.patchValue({
'userid': $event.target.value.replace(new RegExp('[^0-9]', 'gm'), '')
}, { emitEvent: false });
}
Demo 3
Note: I would generally avoid this approach because in my experience the suppression of modifying characters can have unintended side effects with some uncommon input methods, especially on mobile. The approach above (Approach 2) also works and is safer in my opinion. Although modifying characters are displayed, they will disappear on the next user action and will never be present in your model data.
You have already tried with:
<input type="number" pattern="[0-9]{10}" />
the following validates a 10-digit number, and I also think you should do a validation with JavaScript:
<input type="text" id="text" onblur="validaNumericos();" />
Function Javascript:
function validaNumericos(){
var inputtxt = document.getElementById('text');
var valor = inputtxt.value;
for(i=0;i<valor.length;i++){
var code=valor.charCodeAt(i);
if(code<=48 || code>=57){
inputtxt.value="";
return;
}
}
}
<input type="text" id="text" onblur="validaNumericos();" />
Use input type=number.
ID: <input formControlName="userid" type="number" pKeyFilter="num" placeholder="Numbers" pInputText>
If you don't like the dial controls on the right side, you can disable them with this in your css:
input[type=number]::-webkit-inner-spin-button {
-webkit-appearance: none;
}
input[type=number] {
-moz-appearance:textfield;
}
Here is a fork of your demo with all the changes.
Well, if you are looking for a regex answer (based on your tag), you can test on the length of the pre-regex value vs. the length of the post regex value.
if there are extra characters, the lengths will not match.
[0-9]+

Using a CSS class, but can't find where it is defined

I have been searching for an easy way to make a month/year picker for an ASP.NET Core application I'm making. I found this fantastic one on jsfiddle. It uses the following resources:
bootstrap-datepicker.min.js
datepicker.min.css
bootstrap.min.js
bootstrap.min.css
Here is the code:
var startDate = new Date();
var fechaFin = new Date();
var FromEndDate = new Date();
var ToEndDate = new Date();
$('.from').datepicker({
autoclose: true,
minViewMode: 1,
format: 'mm/yyyy'
}).on('changeDate', function(selected) {
startDate = new Date(selected.date.valueOf());
startDate.setDate(startDate.getDate(new Date(selected.date.valueOf())));
$('.to').datepicker('setStartDate', startDate);
});
$('.to').datepicker({
autoclose: true,
minViewMode: 1,
format: 'mm/yyyy'
}).on('changeDate', function(selected) {
FromEndDate = new Date(selected.date.valueOf());
FromEndDate.setDate(FromEndDate.getDate(new Date(selected.date.valueOf())));
$('.from').datepicker('setEndDate', FromEndDate);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.3.0/css/datepicker.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.3.0/js/bootstrap-datepicker.min.js"></script>
<div class="form-group">
<label>First check in:</label>
<input type="text" class="form-control form-control-1 input-sm from" placeholder="CheckIn">
</div>
<div class="form-group">
<label>First check out:</label>
<input type="text" class="form-control form-control-2 input-sm to" placeholder="CheckOut">
</div>
<br/>
<div class="form-group">
<label>Second check in:</label>
<input type="text" class="form-control form-control-1 input-sm from" placeholder="CheckIn">
</div>
<div class="form-group">
<label>Second check out:</label>
<input type="text" class="form-control form-control-2 input-sm to" placeholder="CheckOut">
</div>
I have made this work in my project in Visual Studio, however, it doesn't seem to be able to find the classes "form-control-1" (and 2) and "from" and so it gives me a little squiggly line indicating so.
I started looking through all the css files included and I cannot find a reference to those classes in any file. If I remove them, the month selector does not work. Can someone help me understand where that functionality is coming from? Does anyone know where those classes are defined?
The from and to are not being used for styling, they are being used in the code that you posted. $('.from').datepicker() $('.to').datepicker().
You can safely delete the form-control-1 and form-control-2 classes.
Those classes can be fuctional classes, not attached to any styling but used to select or manipulate the elements.
Thats probably why you wont find anything. Search through the js files and you will find something.
Since removing the class breaks the functionality, it's probably being referenced from JS. It may be that the JS is calculating the name of the class, something like "form-control " + i for example.
Your best bet to see where this is defined is to use the browser inspector. For example, in Chrome, right-click the page and choose "inspect" to get this UI, which shows you each css class and where they are declared or re-declared in the css hierarchy.
When using Javascript it can be very useful to use CSS classes which are not attached to any styling, but are instead used as semantic references for jQuery selectors to use later.
This can be very useful when trying to attach multiple semantic meanings to an element. You can have one element can have many semantic tags. I use this in complex components to be able to dynamically tag elements that I can later manipulate or check the class name. This is especially useful if you are generating elements from a server-side language and trying to tag them semantically so that they can be manipulated later from Javascript/jQuery. It think it is much easier to add a dynamic class string from the server side than to put in data attributes.
One example of this that I use is for validation information to be attached to an element. I generate the elements in a server-side class (including what type of validation it should have) which outputs a CSS class string, then when I submit the form in Javascript, I get all elements with specific classnames and check if their contents match the validation type.
The code sample you posted does a similar thing, where it wants to use a jQuery plugin on all elements with a certain class. Instead of direct styling, it uses them as semantic markers that those elements should be transformed in a certain way to be datepickers (which are documented here: https://jqueryui.com/datepicker/). Code for jQueryUI uses this a lot to be able to simplify which elements should be used-- and it can be easier to add new elements that are datepickers, since you simply add a class to the new one instead of having to add a new jQuery reference to it (especially if you don't know exactly how many of them there will be on the page when you write the Javscipt code).
If you are ever in a similar instance and looking for a different way to store data on elements without inadvertent effects and it is pure Javascript without server side rendering, data-* attributes in HTML5 are a way to do it (and a simple library could be developed to add them to elements from a server side language). Just use jQuery selectors with jQuery("[data-mytagname=someValue]") to select.
A word of caution that if you use classes like this as semantic tags, I would be careful to avoid commonly used class names, since you could inadvertently get extra styling when a co-worker (or yourself) decides to use that in an element. ;)

jquery form validation allow only standard USA numbers

I found this plugin good so far Jquery Form Validator as so far it has fulfilled all my requirements but i am stuck to set validation for the users to enter only USA mobile number format something like this 1-(XXX)-XXX-XXXX . It should allow only this number to enter else it should not accept and should show form validation error.
I have researched but unable to find any tutorial or demo code which is showing how to achieve this particular thing and hence i had to put this question.
Can someone guide me or show me some code if possible how to achieve this using data-* attributes in html tags (i.e. <input data-validation="creditcard" data-validation-allowing="visa, mastercard, amex">) or any other way with the help of utilizing this plugin..
I am trying to utilize this Configuration Callbacks but i am bit confused how to utilize this as i have multiple forms and i have only put this code in my common.js file for all the forms which works well using for all the forms.
$.validate({
modules : 'security, file'
});
So i want something like common data-* attribute (if its available) which can work in a parcular html form which can be feasible for me as i do not need to type different code based on different form like this $.validate({form : '#LoginForm'}); as above common method will be feasible for me ..
Can someone help me to achieve this thing please ?
Any help will be highly appreciated.
Thanks.
Eventually I have sorted out this thing with ease thanks to #mplungjan who provided me a link and shown me a way how to accomplish this.
I simply went here to the library Default validation custom and I see they actually are providing the facility to make regex validation on the go ..
I searched regex to check US mobile numbers Phone Number Regex US
And then after finding a regex to work with, I used this HTML code,
<input name="user_mobile_no" class="form-control error" placeholder="Mobile No."
data-validation="required custom"
data-validation-error-msg-required="Please Enter Mobile Number"
data-validation-regexp="\D*([2-9]\d{2})(\D*)([2-9]\d{2})(\D*)(\d{4})\D*"
data-validation-error-msg-custom="Invalid Mobile Number (i.e. +1 XXX-XXX-XXXX)"
maxlength="50" id="user-mobile-no" value="+1 215-555-1212"
style="border-color: rgb(185, 74, 72);" type="text">
And voila, its working.
Notice these lines I have put above, data-validation="required custom" custom is required to put there to make custom validation.
Then after I put
data-validation-regexp="\D*([2-9]\d{2})(\D*)([2-9]\d{2})(\D*)(\d{4})\D*"
which checks valid phone numbers and last but not the least, i have put two different validation error messages to show to the users for required data-validation-error-msg-required="Please Enter Mobile Number" and invalid number data-validation-error-msg-custom="Invalid Mobile Number (i.e. +1 XXX-XXX-XXXX)" .
Thanks guys for support. I hope it helps someone who needs to deal with similar thing. Really appreciated.
Thank you.
/*
It works for these number formats:
1-234-567-8901
1-234-567-8901 x1234
1-234-567-8901 ext1234
1 (234) 567-8901
1.234.567.8901
1/234/567/8901
12345678901
1-234-567-8901 ext. 1234
(+351) 282 433 5050
*/
jQuery.validator.addMethod("usPhoneFormat", function (value, element) {
return this.optional(element) || /^\(*\+*[1-9]{0,3}\)*-*[1-9]{0,3}[-. /]*\(*[2-9]\d{2}\)*[-. /]*\d{3}[-. /]*\d{4} *e*x*t*\.* *\d{0,4}$/.test(value);
}, "Enter a valid phone number.");
$(document).ready(function(){
$("#sampleForm").validate({
rules: {
phoneNumberRegEx: {
usPhoneFormat: true,
required: true
}
},
submitHandler: function (form) {
alert("submitted.");
}
});
$(".phone").mask("0-000-000-0000", {placeholder: "_-___-___-____"});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.15.0/jquery.validate.min.js"></script>
<script type="text/javascript" src="http://igorescobar.github.io/jQuery-Mask-Plugin/js/jquery.mask.min.js"></script>
<form id="sampleForm" method="POST">
<fieldset>
<label for="phoneNumberRegEx">Phone: </label>
<input type="text" id="phoneNumberRegEx" name="phoneNumberRegEx" class="phone" />
</fieldset>
<input type="submit" value="Submit" />
</form>
If u wanna have advanced validation with specific series codes, u can try to use data from this package https://www.npmjs.com/package/dialcodes

Custom input mask in HTML

I want to generate an input type of text with custom mask like --day/--night and user replace - just with numbers. any suggestion? Please help me out here.
duration: --day/--night
Using two inputs is much more efficient.
But if you really want to do this, yes you can do it. You would need to check the input value every time user inputs a character and format the value to what you would like. You can also manipulate the cursor position using selectionStart and selectionEnd properties.
There are also a number of mask plugins for inputs.
http://plugins.jquery.com/tag/mask/
You can do following:
Make a placeholder "--" where the user can write the things in. Here is a short example what I mean:
duration: <input placeholder="--" maxlength="2">day/<input placeholder="--" maxlength="2">night
Telerik offer a free version of their "Kendo UI" JavaScript code. Here's an example of what you want: http://demos.telerik.com/kendo-ui/maskedtextbox/index
Here's the free code: http://www.telerik.com/download/kendo-ui-core
Here's their masked input code hosted on Github: https://github.com/telerik/kendo-ui-core/blob/master/src/kendo.maskedtextbox.js
It is very hard to write this type of code but you can use this code for this type of formatting.
<div>
<label for="phone">Phone</label>
<!-- or set via JS -->
<input id="phone" type="text" />
</div>
jquery code
$(":input").inputmask();
$("#phone").inputmask({"mask": "99/99"});
see the codepen link click here

Accessing an array of HTML input text boxes using jQuery or plain Javascript

I'm looking to create a form which contains a dynamic number of input text boxes. I would like each text box to form part of an array (this would in theory make it easier for me to loop through them, especially as I won't know the number of text fields that will eventually exist). The HTML code would like something like:
<p>Field 1: <input type="text" name="field[1]" id="field[1]"></p>
<p>Field 2: <input type="text" name="field[2]" id="field[2]"></p>
<p>Field 3: <input type="text" name="field[3]" id="field[3]"></p>
<p>Field 4: <input type="text" name="field[4]" id="field[4]"></p>
<p>Field 5: <input type="text" name="field[5]" id="field[5]"></p>
This data would then be sent to a PHP script and would be represented as an array - or at least, that's the theory.
So my first question is, is this achievable using HTML? Are forms designed to work that way?
If the answer to that is "yes", how would I then go about accessing each of those using jQuery or failing that, plain old JavaScript?
I've attempted to achieve this using the following jQuery code:
someval = $('#field[1]').val();
and
someval = $('#field')[1].val();
and the following JavaScript:
someval = document.getElementById('related_link_url')[1].value;
But I've not had any luck.
Thanks in advance.
Edit:
I should note that from a Javascript point of view, I've had it working where the ID of each element is something like field_1, field_2 etc. However, I feel that if I can achieve it by placing each text box into an array, it would make for tidier and easier to manage code.
Give each element a class and access the group using jQuery:
<p>Field 1: <input type="text" name="field[1]" class="fields"></p>
<p>Field 2: <input type="text" name="field[2]" class="fields"></p>
<!-- etc... -->
jQuery:
$("input.fields").each(function (index)
{
// Your code here
});
This will run the anonymous function on each input element with a classname of "fields", with the this keyword pointing to the current element. See http://api.jquery.com/each/ for more info.
First of all, id attribute cannot contains [ or ] character.
There is lots of ways to get jQuery/plain JavaScript references to these elements. You can use descendant selector:
<fieldset id="list-of-fields">
<!-- your inputs here -->
</fieldset>
$("#list-of-fields input");
document.getElementById("list....").getElementsByTagName("input");
You can also use attribute selector:
$("input[name^=field]");
I'm not sure whether that's the only way but I think in plain JavaScript you'll have to fetch all input elements (document.getElementsByTagName) and then loop through array of these elements and check each element (whether it has name attribute which value starts with field).

Categories

Resources