Extra Number during Currency Masking in Javascript - javascript

I am trying to make a quick function for currency masking without the use of a jquery plugin. The environment I am in is using requirejs and any attempt to add plugins typically results in this problem:
MISMATCHED ANONYMOUS DEFINE() MODULES
Regardless, here is my code below, I am trying to get rid of the 3rd digit after the decimal so that there is only 2 digits after the decimal but for the life me can't figure out why nothing I'm doing is making it go away.
currencyMask("#test");
function currencyMask(fieldID) {
$(fieldID).on('keypress click', function() {
if (this.value != '') {
if (this.value.length == 1) {
this.value = '0' + this.value
}
this.value = parseFloat(this.value.replace(/[^\d]/g, '').replace(/(\d\d?)$/, '.$1')).toFixed(2).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,').replace(/(\d{2})(\d$)/, '$1');
}
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input id='test'>

After some discussion, some testing, and a bit of research. I changed my code a bit and resolved the issue as mentioned by Kevin B about keyup vs keypress.
After some research it appears the keypress triggers when "The key is pressed down" while
keyup is triggered when "The key is released". -W3 Schools
Because of that, I opted for keyup instead.
In addition, Kevin B said:
What makes the whole thing weird is that you're typing at the last position the moment your code does anything to the input because you're entirely replacing the value.
So I changed the code so that the user is typing at the beginning instead of the end. He also mentioned:
Regardless of how you change the value, if you're changing it at all while the input is still focused, it impacts the usability of the input because it will change the insertion point in one way or another. I prefer changing it after the fact rather than live as to not interfere with the user's input. for example, on blur.
This part here is definitely preference. I brought an admin over to my desk just now and asked which one they liked more. Most of them don't like ones that change after the fact. They find it confusing and to them, the whole point of the currency mask is to clearly see what they are typing as they are typing it.
To be clear, there isn't a 'wrong' way to do it. You can do .blur instead and that works too. This is more about what our specific users prefer.
Here is my updated code below:
currencyMask("#test");
function currencyMask(fieldID) {
$(fieldID).keyup(function() {
if (this.value != '' && this.value.length >= 3) {
this.value = this.value.replace(/[^\d]/g, '').replace(/(\d{2}$)/, '.$1').replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,');
}
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input id='test'>

Related

password input masking with delay, android style in javascript/jquery

Let me start by saying that my task is complete. But I'm trying to get an understanding of how it's working, and one thing is confusing to me. In other words, I stumbled on the answer by accident.
My task was simple: in an input box, mask the input as the user types, by changing each character to * after a delay. This is how android phones handle masked input, slightly different than iPhone.
I used a combination of jQuery/javascript and regex. My working code:
$('.room_input').focus(function () {
currentFocus = $(this);
});
$('.key').click(function () {
setTimeout(function () {
currentFocus.val(currentFocus.val().replace(/[^\*]/, '*'));
}, 2000);
});
It's pretty simple, and it works great. When each key is pressed, it changes to * after 2 seconds. Each key is on its own timer. But there is one major thing I don't understand. When the callback from setTimeout triggers, the code above seems like it would set the entire contents of the textbox to *'s. Because the "replace" above replaces the entire content of the value with any characters not *.
But it doesn't. Each key changes after 2 seconds from when it was clicked (as it should).
Why is that? I'm thinking it might be the regex - does it only change the first match it finds? Did I just answer my own question?
UPDATE: I did.
It's the regex. It only replaces the first matched character in the string. I was thinking it maybe had something to do with single-threading issues... as usual, I'm making a problem much more difficult than it is. :)
Yep you are correct.
Every key click adds a character, and then starts a timer that later turns the first non-asterisk into an asterisk. It's far simpler than you might expect.

JavaScript Max Length Validation with Overtype/Insert Key

I am trying to edit some existing JavaScript validation code.
Using the onkeydown event, the code checks that the value in a textbox does not go past a maximum length. I cannot use <input maxlength="value" /> as there may be some formatting characters in the string that I can safely exclude from the maximum length.
The code works fine apart from when the user has pressed the insert key to turn overtype on and they have reached the maximum length. When this occurs if they place the cursor before a character and try to overwrite it the validation thinks that this will go over the limit and doesn't realise that a character will actually be replaced.
This answer states that I cannot detect if overtype is on, but doesn't provide any references. So assuming that I cannot detect overtype, is there anyway in the onkeydown event to detect if a character is going to be replaced.
I am happy with an IE only solution.
Update: onblur is not appropriate as this will let them go many characters over the limit before warning them of the maximum length. I would like to prevent them from going over the limit.
Your handler should look at the entire value and check the length. If the length is legal, return. If not, you can update the value with a substring. You may have to use caret position to determine exactly how to manipulate the string which can be tricky as it's slightly different in IE and other browsers.
This is different from what you have now which is probably preventing keypress when max length is reached. Don't prevent keypress, just trim the resulting string.
I don't think your problem is with the onblur validation, but an event you calling on key press by the sounds of it (eg preventing the user to key any more once they reach the limit) or I have misunderstood.
IF your validation is indeed onblur, you shouldn't have to worry about things like insert/overwrite being enabled, you are only interested in what the value of the input element is once the user has completed their input.
IF you are trying to stop the user if they reach this limit as they type, I would write a function to compute the actual length you are testing. For eg,
function validateMyInput() {
var myInputField = document.getElementById('myInput');
var removeAllExcludedCharsResult = myInputField.value.replace('&','');//exclude &
var totalLength = removeAllExcludedCharsResult.length;
if(totalLength < 500) { //limit of this test is 500
return true;
}
else {
return false;
}
}
Obviously change this function to what you need and maybe make it more generic by passing in the element of the input, max length and array of excluded chars to make it reusable.
UPDATE
I have tested this problem is Chrome and the insert key seems to be ignored. IE on the other hand does overkey. However, it seems page specific, for eg, if i have enabled insert on Page A, it doesn't seem to affect Page B. I found this page which seems to be able to grab the keycode event even when insert has been pressed. It might be due to the following code?
if(window.event) {
event = window.event; //where event is the javascript key event.
}
Either way, the link above seems to have accounted for the problem, hopefully it will have the answer if the above is not correct.
Hope I haven't misunderstood what the problem was and this helped.

How can I prevent entry of non-numerals a text field?

I found this question. However, most of the answers intercept the key press, check the key code, and stop the event if it isn't an acceptable key code.
There are a some problems with that.
A common bug among all the answers is that shift key combinations are not prevented so users can enter stuff like "#" or "&".
Users can still paste in bad values from the clipboard.
When you start messing around with the key press event, the webpage starts doing weird, unexpected things. For example if the field has focus and the user tries to reload the page by pressing command-R it won't work. Or they can't tab out of the field.
I would like a solution that allows the keypress, then checks the entered value against a regex and removes unwanted characters.
I'm looking for a solution along these lines:
Doesn't intercept the keypress event.
Ideally uses a regex after the keypress.
OK if it uses jQuery.
Doesn't require installing a plug-in.
I tried this function:
$('input.numerals_only').keypress(function() {
var v = $(this).val();
var no_nonnumerals = v.replace( /[^0-9]/, '' );
$(this).val(no_nonnumerals);
});
But that doesn't work. I'm still able to type in letters.
Any info on why it doesn't work? How could I modify it so it works? Other suggestions?
If you use keyup and also blur you should handle most cases. Someone keys in text and also if they paste in a value into the text box. As the blur function will remove the bad values as well.
$('input.numerals_only').keyup(AllowOnlyNumber).blur(AllowOnlyNumber);
function AllowOnlyNumber()
{
var v = $(this).val();
var no_nonnumerals = v.replace(/[^0-9]/g, '');
$(this).val(no_nonnumerals);
}
Of course if html5 is an option you could always do:
<input type="number"/>
jsfiddle example.
The thing your regexp is missing, which is why it didn’t work for keypresses neither, is the g flag for a global regexp check.
Use var no_nonnumerals = v.replace( /[^0-9]/g, '' );
If you use keyup instead of keypress it will always remove the incorrect characters.
You can also use this to actually block the events:
$('input.numerals_only').keypress(function(event) {
if(event.keyCode < 48 || event.keyCode > 57){
return false;
}
});
Use the keyup event. It is triggered after the key is processed by the browser:
$('#txtInput')
.keyup(function(ev) {
var newValue = this.value.replace(/[^0-9]/, '');
$(this).val(newValue);
});
I wrote a jQuery plugin to do this. Demo and code here http://brianjaeger.com/process.php
It uses a regular expression to validate whatever you want.
There are a few issues:
it's a plugin (however, you could suck out the code and plunk it into your other JavaScript if you want. -its easier just to use as plugin)
Unfortunately there is no way to limit pasted information directly (across all browsers) - My solution to this was to add validation on focus change as well as keypress.

JS/jQuery : Best way to get typed characters after '#' in textarea

I am creating a smart textarea that needs to recognise a term typed after the '#' symbol.This needs to be able to work for the term CURRENTLY being typed and be able to work for multiple instances of the '#' symbol in a single textarea.
It is designed to work the same way as Facebook when you type the '#' symbol to tag a person in a post. A drop down list will appear and list items will get filtered depending on the term after the '#' symbol.
This also needs to work if the user were to type a term then amend it later. I understand this complicates things a little.
What is the best way to achieve this functionality?
I don't know if it helps but here's i small script to find the hashes.
http://jsfiddle.net/aNgVV/
I suggest you look at the jQuery UI demo for the Autocomplete widget, specifically the demo for using a remote datasource with cache. Specifically for the following reasons:
It automatically takes care of the drop-down widget you mentioned.
It demonstrates how you can populate that drop-down with items based on an AJAX call (which I presume you need).
The demo for Autocomplete caching parses the text in the INPUT element, as it tries to determine whether or not the value the user is currently typing has already been cached, and reacts accordingly. I assume you can do something similar to check for the # types, and to check if a previous # tag is being modified as well.
Initially you need to catch the '#' key being pressed and then capture the subsequent key presses and pass them to a function to handle your auto completion requirements. A rough outline to of the code is below. You may need to catch whitespace key presses as well to stop the auto-completion.
var hashKeyPressed = false;
$('#TextArea').keyup(function(event) {
if(event.keyCode == '222') {
// this will catch the '#' key
hashKeyPressed = true;
}
if(hashKeyPressed) {
// Here you can start build up subsequent key presses into a string
// and pass them to a function to handle the auto-completion
}
});
You can capture the keyup event and check what has been entered last like so:
$('#myTextArea').keyup(function () {
var len = $(this).val().length;
if ($(this).val().substring(length - 1, 1) == '#') {
// Do whatever you want to do here
}
});
EDIT:
You are right - you could do it this way instead:
$('#myTextArea').keypress(function (e) {
if (e.which == 222) {
// do something here
}
});

Javascript events

I am completely confused here. So I am looking for a solution for the following problem:
I want to trigger some function(for now an alert box) using jQuery on an input field. Conditions are:
Input field always maintains the focus.
Input is fed from a USB device, which acts just like a keyboard input. So for 10 characters, there will be 10 keydown and keyup events.
Once input is filled with 10 characters, respective alert box should pop out.
Now the problem I am facing, how do I find out that input fed in is not equal to 10 characters, so throw an error alert box.(lets say just 5 chars came in input, how do I figure out the final count is 5, because there will be 5 keyup events)
You could show a message underneath/beside the input box instead of popping an alert box.
E.g. on every keyup event, check the string length, and if it's not 10, show that message.
If you really, really have to resort to alert box, you could do a timeout check, e.g. only perform the validation after 1000ms of key event inactivity. This could get very annoying on the user though.
You really have two problems here. One is just understanding the jQuery syntax (see the second part to my answer), and the other is - what is the best way to understand WHEN to throw up an error box.
To answer the second question first, my recommendation would be to not use an alert box to warn the user as they tend to be modal and really interrupt the flow of input. Secondly, as you said - how do you know when the person has stopped "typing." Unless you use some sort of timing mechanism (which is more trouble than it's worth), you don't. My suggestion would be to utilize a "div" within your HTML that shows there is an error UNTIL you reach 10 characters. Once that happens, you can hide the div. (And, of course, the div can be styled to look pretty in the meantime.)
So...how to do this...
Let's assuming your input field has an id of "myField." If you are using jQuery (which is in your tags), you would do something like this.
$(function() {
var keypresses = 0;
$('#myField').keyUp(function () {
keypresses++;
if(keypresses == 10) {
$('#error').hide(); // This is your div error with some error text in it.
// Do other stuff.
} else {
// Display an error.
}
});
Alternatively, if you don't want to use the keypresses variable, you can also use..
if($(this).val().length == 10) { }
The real issue is the fact that you are measuring in key press events, because not all key presses (even when the field has focus) will insert a character into field (for example returnesc). Therefore, you will need to measure the string length in order to validate the code before you start executing functions.
In actuality you don't even need jQuery to accomplish what you need, just bind the function call to a key press event, and only execute the function call if yourstring.length = 10
yourInput.onKeyPress(yourString.length = 10 && yourFunction());
Try -
$('#idofinputfield').keyUp(function () {
var length = $('#idofinputfield').val().length;
if(length <= 10){
alert("less than 10");
}else{
alert("greaterthan 10");
}
});

Categories