jQuery keydown event: Value coming delayed - javascript

I have following issue:
I got an event listener on an input field. On every keydown event the value of the input field should get validated. The problem is that the value assigned to the event-target is delayed:
You have an empty input field and type down one letter:
$('form.registration').keydown(function(e) {
var $el = $(e.target);
if ($el.val() == "") {
$el.closest("div.control-group").addClass("error");
}
console.log($el.val()); // this logs ""
});
You type in the second letter
$('form.registration').keydown(function(e) {
var $el = $(e.target);
if ($el.val() == "") {
$el.closest("div.control-group").addClass("error");
}
console.log($el.val()); // this logs the first letter (for example: "a")
});
As you see the value is always delayed by one letter.
How can I fix this?

I will suggest you use keyup instead. This will prevent your program running intensively when user presses the key and holds it, the content is being processed only after user releases the key. This method is very convenient in many cases.

Related

jQuery to prevent user from inputting if regular expression is not matched by using preventdefault

Every time user enter, value is checked with regular expression, I'm trying to restrict user from entering further into input field if regexp is not matched
Using keyup event, preventdefault never fires and using keypress event, user is unable to input at all because in the begining, value in input field shows as "" (nothing)
var discountRegex = /(^100([.]0{1,2})?)$|(^\d{1,2}([.]\d{1,2})?)$/
$("#" + (idOfElement)).on("keyup",function (e) {
var val=this.value
var k = e.keyCode
if(k==46 ||(k > 48 && k <97)){
console.log(k)
return discountRegex.test(val);
}
});
in the above code idOfElement is the id i get on whichever field i focus.
Please refer sample code. If input key is invalid input will not accept it. Also please find fiddle for same in comment.
<input type="text">
$(document).ready(function(){
$("input").bind('keypress', function(e) {
var str = e.keyCode;
if (/(^100([.]0{1,2})?)$|(^\d{1,2}([.]\d{1,2})?)$/.test(str)) {
alert('Invalid')
e.preventDefault();
} else {
alert('Valid');
}
});
});
You can check if the regex is matched and if not you can remove the last char like the example below
I updated the code with keydown example
Example

Delegating change event on input field

I'm trying to fire a function whenever the value of an input field changes. The input field is in a lightbox so I have to delegate the event:
var validateDonation = function(elem) {
var msg,
value = elem.value;
if (value == '') { msg = 'Please enter an amount'; }
else if(parseInt(value, 10) < 1) { msg = 'Please enter an amount greater than 1'; }
else if(parseInt(value, 10) > 100) { msg = 'Please enter an amount less than 100'; }
else { msg = ''; }
if(msg != '') {
console.log(msg);
}
}
and
$('body').delegate('#donation_amount', 'change', function(event) {
validateDonation(this);
});
If I use keyup instead of change the console log works just fine. But not on change. Why?
https://msdn.microsoft.com/en-us/library/ms536912(v=vs.85).aspx
onchange: This event is fired when the contents are committed and not while the value is changing. For example, on a text box, this event is not fired while the user is typing, but rather when the user commits the change by leaving the text box that has focus. In addition, this event is executed before the code specified by onblur when the control is also losing the focus.
If you want the change to be instantly updated then you would want to use the oninput event
oninput: The DOM input event is fired synchronously when the value of an <input> or <textarea> element is changed. Additionally, it fires on contenteditable editors when its contents are changed.
For IE less than IE9 i believe you need to use the onpropertychange event as well as oninput to accommodate modern browsers.
Here is a fiddle to show you the event fires immediately
http://jsfiddle.net/SeanWessell/9jfkcapp/
Try this...
$('body').delegate('#donation_amount', 'input propertychange', function (event) {
validateDonation(this);
});

Fix double call and get before value

I am learning JQuery by example. Please check this fiddle: http://jsfiddle.net/4tjof34d/2/
I have two problems:
1 : showText() gets called twice when a person hits enter and thus console.log(this.id+ " " +this.value); gets called twice, What do I add so that it only gets called once?
2: I get the id and value of the textbox, but I also want to know what was the old id and value so that I can do a comparison test. How do I do that?
eg:
var oldValue = ? // How do I do this?
var newValue = this.value;
Then I can do something like:
if(newValue != oldValue)
{
// Do .ajax() - update DB
}
for your first issue showText is called twice ie,on blur and on enter
change your blur function as follows
$('.input').blur(showText).keyup(function (e) {
if(e.which === 13) {
this.blur();
}
});
for second issue i will go with a global variable as flag
http://jsfiddle.net/x1ez7Lek/6/

Multiple event listener in Javascript

How to add multiple event listeners in the same initialization?
For example:
<input type="text" id="text">
<button id="button_click">Search</button>
JavaScript:
var myElement = document.getElementById('button_click');
myElement.addEventListener('click', myFunc());
This is working correctly however I would like to have another event listener for this input filed in the same call if that is possible, so when user clicks enter or presses the button it triggers the same event listener.
Just one note. User needs to be focused on the input field to trigger an "enter" event.
Just bind your function to 2 listeners, each one of the wished element:
document.getElementById('button_click').addEventListener('click', myFunc);
document.getElementById('text').addEventListener('keyup', keyupFunc);
where the new function test if the user pressed enter and then execute the other function :
function keyupFunc(evt) {
if(evt.keyCode === 13) // keycode for return
myFunc();
}
Working jsFiddle : http://jsfiddle.net/cG7HW/
Try this:
function addMultipleEvents(elements, events){
var tokens = events.split(" ");
if(tokens.length == elements.length){
for(var i = 0; i< tokens.length; i++){
elements[i].addEventListener(tokens[i], (e.which == 13 || e.which == 48)?myFunc:); //not myFunc()
}
}
}
var textObj = document.getElementById("textId");
var btnObj = document.getElementById("btnId");
addMultipleEvents([textObj,btnObj], 'click keyup');
UPDATE:
function addMultipleEvents(elements, events) {
var tokens = events.split(" ");
if (tokens.length == elements.length) {
for (var i = 0; i < tokens.length; i++) {
elements[i].addEventListener(tokens[i], myFunc); //not myFunc()
}
}
}
var textObj = document.getElementById("textId");
var btnObj = document.getElementById("btnId");
addMultipleEvents([btnObj, textObj], 'click keyup');
function myFunc(e) {
if (e.which == 13 || e.which == 1) {
alert("hello");
}
}
Working Fiddle
I think the best way to do this is by using for loops.
const events = ["click", "mouseover"]
for (i in events) {
document.getElementById("button_click").addEventListener(events[i], () => myFunc())
}
The code above loops through every events inside an array and adds it to the button.
Yeah this is a good question and can apply to other scenarios. You have a form and a user will have input text field, a radio box, a select option. So now you want the submit button to go from disabled to enabled. You decide to add an event listener to check if fieldA and fieldB and fieldC is first to enable submit button.
If you use event listener on Keyup", and all your fields are valid, the submit button will become enabled only if the last field is a text field because the event will only be triggered when you let go the key. This means it will not trigger if the radio box or select option is selected with your mouse. We must not rely in the order the fields are filled for the logic to work. Again, If you use "click", it sucks, because user will have to click somewhere on page in order for the event listener to fire and run the logic. So i think we'll need an event lister on mouseup, keyup and change for this example below. I assume you made all your validations and variables for the form fields already. We need a function with parameters of multiple events names as a string, the element we want to target (document, or button or form), and a custom function that contains our logic.
// Create function that takes parameters of multiple event listeners, an element to target, and a function to execute logic
function enableTheSubmitButton(element, eventNamesString, customFunction) {
eventNamesString.split(' ').forEach(e => element.addEventListener(e, listener, false));
}
// Call the above function and loop through the three event names inside the string, then invoke each event name to your customFunction, you can add more events or change the event names maybe mousedown, keyup etc.
enableSubmitButton(document, 'keyup mouseup change', function(){
// The logic inside your customFunction
if (isNameValid && isLocationValid && isProjectValid){
publishButton.disabled = false;
} else {
publishButton.disabled = true;
// Do more stuff like: "Hey your fields are not valid."
}
});
// The isNameValid isLocationValid, isProjectValid are coming from your previous validation Javascript for perhaps a select field, radio buttons, and text fields. I am adding it as an example, they have to be equal to true.
// The publishButton is a variable to target the form submit button of which you want enabled or disabled based one weather the form fields are valid or not.
// For example: const publishButton = document.getElementById("publish");

Question on tabbing to next NON-READONLY field

On blur of field1, field2 is set to READONLY but the cursor on my page then defaults to field2 and the cursor is located at the END of the value and when the user clicks the backspace button the value can be erased. I would like the ability to have the cursor move to the next NON-READONLY or ENABLED field on the page. Is that do-able with jQuery?
Any help/direction would be appreciated.
Here is my code:
$(function() {
$("#ARTransferForm\\:fromAccountAmt").blur(function() {
var origAccountAmount = $("#ARTransferForm\\:fromAccountAmt").val();
var fromAccountAmount = $("#ARTransferForm\\:fromAccountAmt").val();
// Call validation "r2" function
var modFromAccountAmount = r2(fromAccountAmount);
//alert("modFromAccountAmount = " + modFromAccountAmount);
fromAccountAmount = $("#ARTransferForm\\:fromAccountAmt").val(modFromAccountAmount).val();
//alert ("modified fromAccountAmount = " + fromAccountAmount);
if (modFromAccountAmount != "N.aN") {
var firstChar = fromAccountAmount.charAt(0);
var fromAcctAmtLen = $("#ARTransferForm\\:fromAccountAmt").val().length;
if (firstChar == "-") {
var revFromAcctAmt = fromAccountAmount.substring(1, fromAcctAmtLen);
$("#ARTransferForm\\:toAccountAmt").val(revFromAcctAmt);
$("#ARTransferForm\\:toAccountAmt").attr("readonly", "readonly");
} else {
$("#ARTransferForm\\:toAccountAmt").val("-"+fromAccountAmount);
$("#ARTransferForm\\:toAccountAmt").attr("readonly", "readonly");
}
} else {
$("#ARTransferForm\\:fromAccountAmt").val(origAccountAmount);
$("#ARTransferForm\\:fromAccountAmt").select();
alert("Invalid From Amount Format. Use ##.## (NO commas or $ sign)");
}
});
});
Have you tried modifying tabindexes onblur, before RETURN TRUE, to control where the cursor goes? It's kind of a hack, but there you go.
Also, you could use a delegated event (perhaps on the form) to intercept and return false on any keypress events that would modify the value of any readonly input. Something like:
$('#ARTransferForm *[readonly]').live("keypress", function(event) {
// compare keycode to blacklist: backspace, perhaps delete too?
if(bKeyIsBlacklisted) {
event.preventDefault();
return false;
}
});
(Note: that is pretty pseudocodeonous. You'll want to double-check the syntax for sizzle's attribute selectors, as well as jquery's event delegation signature. And be real careful about how wide you cast your "no keys" net: try to avoid disallowing Copy and other operations performed with keyboard shortcuts. You will need to check for a modifier key to distinguish between the user trying to type "c" and Ctrl+C.
Which browser(s) are you testing this in?

Categories