Event onblur not working in <input> element | JS - javascript

I'm pretty new on JS and I need to call an external function when an onblur event happens with the <input type="text" id="username">.
Here is the code:
<input type="text" id="username">
<input type="hidden" id="feedback" value="">
<script>
var elUsername = document.getElementById("username");
elUsername.onblur = PagSeguroDirectPayment.onSenderHashReady(function(response){
if(response.status == 'error') {
console.log(response.message);
return false;
}
var hash = response.senderHash; //Hash will be available here.
var elFeedback = document.getElementById("feedback");
elFeedback.setAttribute("value", hash);
});
</script>
The code shows no error but as soon as the page loads, the function is being called, sending the hash value immediately to the <input type="text" id="username">. Instead of this, I'd like that this value was only available as the onblur event had been triggered.
Thank you!

The onblur event handler expects a reference to a function which it can execute when the blur occurs. You're instead executing the function and then assigning onblur the return value of your onSenderHasRead() method.
As stated above, onblur expects a reference to a function. In order to do this, you can write your own function which performs the code you want to run when the blur occurs. Then, you can assign onblur a reference to this function:
function handleBlur() {
PagSeguroDirectPayment.onSenderHashReady(function(response) {
if (response.status == 'error') {
console.log(response.message);
return false;
}
var hash = response.senderHash; //Hash will be available here.
var elFeedback = document.getElementById("feedback");
elFeedback.setAttribute("value", hash);
});
}
elUsername.onblur = handleBlur; // a reference to the handleBlur function (note: we are not calling this function, as onblur will call it for us)
Having to create an additional function and then using it later on can disrupt the flow of your code sometimes, so you'll often see people use an anonymous function, which are function expressions that can be assigned in-line, and don't require a name (hence the anonymity):
// onblur will call this --\/ function when a blur occurs
elUsername.onblur = function() {
PagSeguroDirectPayment.onSenderHashReady(function(response) {
if (response.status == 'error') {
console.log(response.message);
return false;
}
var hash = response.senderHash; //Hash will be available here.
var elFeedback = document.getElementById("feedback");
elFeedback.setAttribute("value", hash);
});
}
These days it's often good practice to use .addEventListener() rather than modifying the element's blur event handler. This way if another library or piece of code overwrites the onblur property later on, your blur event will still be registered:
elUsername.addEventListener('blur', function() {
PagSeguroDirectPayment.onSenderHashReady(function(response) {
if (response.status == 'error') {
console.log(response.message);
return false;
}
var hash = response.senderHash; //Hash will be available here.
var elFeedback = document.getElementById("feedback");
elFeedback.setAttribute("value", hash);
});
});

Related

How to return a value from a jQuery event function to the parent function?

I have a jQuery event inside a JavaScript function. I've already read that you cannot access the inner function. However, I would like to know how to adjust my code so that the parent function returns true or false depending on the jQuery function.
function validate() {
$("#button").on('click', function(){
var input = document.forms["formular"]["text"].value;
if (input == "") {
return false;
}
});
if(onclickfunction() == true){
return true;
}
else{
return false
}
}
validate();
Or can you recommend a different approach?
Not sure what this code is supposed to do, because calling validate only creates the event listener without actually executing it. But what you can do is to prevent the default action when you need, which is how validation is usually implemented:
$("#button").on('click', function(){
var input = document.forms["formular"]["text"].value;
yourSecondFunction(input !== "");
});
function yourSecondFunction(inputIsValid) {
// Do your magic here
}

AJAX Request Running Twice on Validation

I am doing a Validation for email input
$("#email").on("input",function()
{
email = $(this).val();
const regex_1 = /^([a-zA-Z0-9_\-\.]+)#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/;
const regex_2 = /^\w+([\.-]?\w+)*#\w+([\.-]?\w+)*(\.\w{2,10})+$/;
var re1 = new RegExp(regex_1);
var re2 = new RegExp(regex_2);
if(re1.test(email)===true && re2.test(email)===true)
{
e.preventDefault();
$.ajax({
url:"Validate.php",
method:"POST",
data:'type=check_email&email='+email,
success:function(data)
{
if(data == 'FAIL')
{
$("#email").addClass("is-invalid");
$("#email").removeClass("is-valid");
$("#email").focus();
}
else
{
$("#email").addClass("is-valid");
$("#email").removeClass("is-invalid");
}
}
});
}
else
{
$("#email").addClass("is-invalid");
$("#email").removeClass("is-valid");
$("#email").focus();
}
$("#email").removeClass("is-invalid");
$("#email").removeClass("is-valid");
});
So my issue is that when the validation through RegEx passes , the AJAX Call is made twice whereas the result from the first success:function(data) itself returns SUCCESS.
Two successive queries for the same instance will increase load on the server unnecessarily.
I personally think my bind is wrong here or that I haven't used e.preventDefault();
But I tried using input focus change keyup (individually as well as multiple binds) but nothing worked, the query still runs twice.
The concept here is that only when the RegEx test returns true then only the ajax is required to run (just once). Why is it running twice here ?
Required : The email(string) should pass both the RegEx tests
The event parameter e in the code is missing.
$("#email").on("input",function(e)
...
...
e.preventDefault();
Edit:
To prevent multiple event firing from the handler, you can return false; From JQuery docs:
Returning false from an event handler will automatically call
event.stopPropagation() and event.preventDefault().
In cases where the event is bound more than once, ensure only one handler is available by using off(). e.g.
$("#email").off('input').on("input",function(e) {
...

Run tracking code after validation but before submit

There is form. Validation function is attached to submit event and it returns true/false ($(form).submit(...)).
<form name="f" class="form">
<input type=text name=ff>
</form>
$(".form").submit(function() {
if ($("[name='ff']").val()==="") {
return false
}
return true;
})
We want to run some tracking script that must be executed in case if validation return true but without changing original validation function (We have possibility to enable/disable tracking script from interface)
var _this = this;
ga('send', 'pageview', 'la-la-la', {
'hitCallback': function() {
jQuery(_this).parents('form').first().submit();
}
})
return !window.ga;
How would I do that properly?
So far I want to unbind current submit/validation function and bind my function and inside of it execute validation logic and then run my tracking code. In such way I can easy disable/enable tracking code without interrupting original behavior of logic.
However I have issues in doing this. Please advise. I want to do something like that
var fn = $(.form).submit // get attached logic - and that's does not work
$(.form).unbind('submit') // unbind it from submit
$(.form).submit(function() { // attach my code and reuse old code inside
my code...
if (fn()===true) {
my code...
}
my code...
})
You should use the following code $(form).on("submit", function(f){
//your function here. lets say you add a counter that starts from 0 and your validation functon returns its count. then you would say
if (counter != 0){ f.preventDefault(); } //this would stop the form from submitting until a condition on your function is met
});
I've made solution using hitCallback event
jQuery(".register-form").on("valid", function(f) {
var event = "/signup";
var _this = this;
ga('send', 'pageview', event, {
'hitCallback': function() {
_this.submit();
}
})
return !(ga.hasOwnProperty('loaded') && ga.loaded === true);
})

Javascript - set focus after alert message

I'm tryng to focus on the same element when validation fail. Here's my HTML code :
<input
id="potatoes" name="potatoes" value="" type="text" class="tooltip"
onblur="Validate('potatoes')" autocomplete='off'>
and here's my javascript code :
function Validate(id) {
var errors = {
potatoes : 'enter potatoes',
hamburgers : 'enter'
};
if (document.getElementById(id).value === '') {
if (id in errors) {
alert(errors[id]);
//setTimeout(function(){document.getElementById(id).focus();}, 1);
}
}
}
I've tried to set focus using .focus() method but it doesn't work. I've read that it might depend on "onblur" in HTML, when I call my function Validate(), so i've tried to change it but nothing worked till now.
There is a problem here. This code is going in loop. When 'focus' is triggered, the function Validate is called again, showing another alert dialog.
That's a working code
HTML
<input id="potatoes" name="potatoes" value="" type="text" class="tooltip" onblur="Validate(this)" autocomplete='off'>
Javascript
var validating = false; //<-- IMPORTANT
function Validate(element) {
var id = element.id;
var errors = {
potatoes : 'enter potatoes',
hamburgers : 'enter'
};
if (document.getElementById(id).value === '') {
if (id in errors) {
if(validating == false) {
validating = true
alert(errors[id]);
setTimeout(function(){
document.getElementById(id).focus();
validating = false;
}, 1);
}
}
}
}
In the html I'm passing this, doing so I'm passing the element and in the Validate function you can access to the id just calling
var id = element.id;
For the focus problem (caused by a loop problem) as you can see I'm using a validating variable to know when is validating when is not. This let Validate function avoids to go in loop.
So:
1) Define a validating var outside the Validate function and set it to false.
2) Fire the focus and alert only if validating is false, and after that set it to true
The javascript function alert(string) is synchronous. The script is paused while the user is reacting to the alerted message. There is no need to do something special. The following snippet should work:
alert(errors[id]);
document.getElementById(id).focus();
The element got focus directly after the user has submitted the alerted message.
You can use jQuery like this:
setTimeout(function() {$('#yourInputId').focus();},1);

Two dom events that call the same function should call the function only once if happening in the same time

I have one input and one button. When I blur from the input and the input has changed, the price() function should be called. Also, when I click the button, the price() function should be called.
The problem is that when a user modifies the value of the input and clicks the button, the price() function is called twice. I don't want this to happen.
I tried the old-fashioned way, setting a variable "inPriceFunction" to true while entering and checking if it is not set before entering. This didn't worked because the two events (blur and click) are executed in the exact same time, the if and the variable set didn't had the time to occur.
How can I avoid that?
What I have tried:
<div>
<input type=text onchange="price();" />
</div>
<button onclick="price();" />test</button>
<script>
called = 0;
function price() {
if(called == true){
return;
} else {
called = true;
}
console.log("called");
called=false;
}
</script>
Underscore has you covered: http://underscorejs.org/#throttle
throttle will prevent your function being called twice within a
specified length of time.
once will prevent your function being called twice at all.
The click and change event do not happen at the same time. They happen one after another.
First, the "change" event is fired, setting called = true, then execute console.log("called"); and set called=false again.
Then, the "click" event is fired, but called == false, so it sets called = true; and then execute console.log("called"); and set called=false again.
Here's a jsfiddle that will do the job. You shouldn't use global variables, of course:
http://jsfiddle.net/SZe26/
var clicktimer = null;
function clickfunc() {
var BLOCK_TIME = 500;
function handleclick() {
console.log("Pressed!");
}
if (clicktimer) {
console.log("Skipping handling of click!");
} else {
handleclick();
clicktimer = setTimeout(function() {
clicktimer = null;
}, BLOCK_TIME);
}
}
The sim^pliest way to handle that might be to store a datetime whenver Price is called and use it to check if it has been called too recently.
if (refDate > new Date(10000 + (new Date())) { // 1 second delay?
return;
}
refDate = new Date();
It's likely that two calls to Date return the exact same date though (so no date manipulation would be required).
add a timeout, something like this
function schedludePrice() {
if(myTimeOut){
clearTimeout(myTimeOut);
}
myTimeOut = setTimeout('price()', 10);
}
this way if the function gets called twice in a short time by your blur and click event, the Price function will only be called once.

Categories