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

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.

Related

Prevent quick usage of tab key?

I have a functionality which forbids users to input specific symbols into <input> tags and also convert all alphabet characters to uppercase.
Everything worked fine when I found out this bug with fast tabbing between elements.
Problem:
Whenever a user inputs a character and presses the tab key really fast, the last character won't get converted to upper case.
Note:
I still want to let users tab between inputs so just e.preventDefault() is not an option here. I need to slightly slow down the tab action with 20-30 milliseconds or so.
Code:
var $inputs = $('input[type="text"]');
$inputs.on('keyup keydown keyhold paste', function(e) {
//validate_input will return true if character is allowed and transformed into upper case
if (!validate_input(e, $(this))) {
return false;
}
if (e.which == 9) {
// i need to do something here to slightly slow down the tab process
// just to make sure the above function will execute before the default tab action.
}
});
I suggest that you use input-event instead. That is fired when the value has changed. You can do you filtering of allowed values there, and convert it to upper case. That is a much easier, foolproof, less buggy, browser independent, keyboard independent, assistive technology independent, approach to solve your problem.

Use setTimeout to postpone time intensive processing while data entry taking place

I have a textarea that the user keys in some data. I need to read this data when it is changed and process it, the processing is very time consuming.
I have the textarea events: change keyup cut paste input call the function triggerProcess().
If one character only is typed into the textarea (or one character only is deleted) then needs to be get called triggerProcess().
If a word of several characters is typed in then the whole system grinds to a halt if triggerProcess() gets called for every character in that word. Even if the system did not grind to a halt it is pointless having triggerProcess() called for each character as the whole word plus the entire contents is what is required to be processed. However a single character such as "I", or a number may need to be processed.
I want to postpone the processing if the typist is typing a word or sentence (if the typist is fast ) but once they pause then their data is processed.
As soon as triggerProcess is called the first thing it does is clear a timer and then set another timer that calls the intensive processing when it expires.
My idea is to put a short timeout in triggerProcess of about 300ms so that there is always at least 300ms before the data is read from the textarea and processed. If one character say "I" is typed then that will be processed, but if several characters are typed in a sequence such as when a word is typed then triggerProcess is called by the textarea event watchers, the timer is cleared and started again for each character. When the word is finished and there is a gap in the stream from the keyboard into the text area the last started timer expires and the word is processed. I know that this will freeze the typist out while the text area contents is being processed, but that freeze out is much better than having the typist frozen out for each character.
How does my code look? Could something go terribly wrong? Could it be improved?
Thank you for taking the time to read this, all comments gratefully received.
Peter
var delayTimer; //global variable as opposed to local variable so that it can be cleared within function display.
function triggerProcess(){
clearTimeout(delayTimer);
delayTimer = 0;
delayTimer=setTimeout(function(){
// when the Timeout fires then
// read the data from the textarea and have some very time consuming work on it
},300);
}
What you are trying to achieve is called autocomplete.
Your code looks cool to me, but If I were you, I will not go for setTimeOut because that is a hack and will make the experience slow. I would think of AJAX call rather than a setTimeOut With AJAX (since the call is asynchronous), you can send request as many times as you want without user experiencing anything bad. Whenever the user types and change event will be called, it will ask for new matching words and will show the new matching words to user, when it has any.
I do not know if you use jQuery or not, but anyhow jQuery UI has one component (See here jQuery UI AUtocomplete). Since thank god jQuery UI is an open-source project, you can see the code at /ui/jquery.ui.autocomplete.js. If you open the other autocompleteEvents.js, you can see that there are four event types there: focus, close, select, change. As you can see in autocomplete example.
$.ajax({
//Where you load the data, could be a backend server instead of a
// XML file
url: "london.xml",
dataType: "xml",
success: function( xmlResponse ) {
//If matching any element from the london.xml file,
// Show the result in a menu or something
}
});
It is just calling whenever anything gets changed to get the new results (as simple as that). If you do not like AJAX, try to use callbacks, show the results after you sent the newly typed word and get a reply back and not in between.
Here is just another autocomplete example with my second suggestion in mind: complete.ly. It shares the same concept.
It just adds the onchange and keyup event:
if (txt.addEventListener) {
txt.addEventListener("input", handler, false);
txt.addEventListener('keyup', handler, false);
txt.addEventListener('change', handler, false);
}
And will make the callback whenever it is done with getting new values, checking if anything matches and will show the result:
var handler = function() {
var value = txt.value;
if (registerOnTextChangeOldValue !== value) {
callback(value);
}
};
Read the full source here: complete.ly source code
I hope I make sense and my answer helped!

Textarea charCount - Preventing user paste

The code below is working fine except that if I paste a string with more than 10 characters in it, it should only paste in the first 10 characters. Currently it does not do this, how do I prevent more than 10 characters being pasted?
http://jsfiddle.net/qfzkw/2/
As stated, <textarea maxlength="10"> will work for a small amount of cases - but not all.
It is hard to determine how to prevent the user (in firefox for example) from entering the text area, selecting the browser menu Edit and then clicking on Paste. I am really at a loss for how to prevent that. You can check the keydown event to prevent ctrl + v. You can disable the context menu to disallow the right clicking of the text area (although a malicious user can edit the front end javascript and then re-enable this feature).
In short, there is no universal way to prevent user paste in a proper fashion.
However, you could hack a solution (always my favorite when it seems there is no way to continue on something you really want). This approach I am about to suggest is dependent on how many timers you have running. If you have multiple timers for animation, google suggests you try to fold them all into one timing unit which the others derive from. If this is the case, please refactor your timers.
Implement a global timer. Implement a function which runs ever 25ms based on that timer. Cache the contents of the textarea. See if those contents have changed.
textarea
<textarea id="maintextarea"></textarea>
script
/*init*/
var globalTimer = new Date();
var cachedText = document.getElementById("maintextarea").value;
var iterationCount = 0;
function cacheText() {
cachedText = document.getElementById("maintextarea").value;
}
function upDateTimer() {
globalTimer = new Date();
var timerTimeout = setTimeout('upDateTimer()', 5);
timeBasedOperations();
}
upDateTimer();
function timeBasedOperations() {
iterationCount++;//this will allow timing to occur
//TODO: Add in other timers calls based on global timer
if (iterationCount % 5) {//every fifth iteration (hence 25ms)
checkTextArea();
}
}
function checkTextArea() {
var currentText = document.getElementById("maintextarea").value;
var textArea = document.getElementById("maintextarea");
if (currentText.length > cachedText.length) {
//TODO: Add additional logic for catching a paste or text change
textArea.value = currentText.substr(0, 10);
}
cacheText();
}
I think although this implements a timer, this is a very practical solution. It also happens to work (tested).
:)
simply use
<textarea maxlength="10"></textarea>​
No javascript needed for this. It automatically takes care of copy paste also.
Here is the updated jsFiddle.
You can't peek into the clipboard buffer from browsers, so your only option is to limit it to 10 chars like you currently do. Use the maxlength="10" attribute instead of the javascript character counting thing you got going on.
<textarea maxlength="10"></textarea>​

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.

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