I am trying to prioritize click event in case two events click and change are fired.
I have a global function similar to "ValidateOnChange" and "ValidateOnClick" to validate input of text box on change and on click event.
Enter some text, it shows up error message. Then try to input correct value and click the Submit button, the error vanishes and this makes user to click the button twice. Here I am trying to fix this double click.
Here is mock up code:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
</head>
<body>
<div>Enter any string:</div>
<div><input type="text" id="txtInput" ></input></div>
<div id="divError" style="color: red; display: none;">Please enter 0</div>
<input type="button" value="Submit" id="btnSubmit" ></input>
<script type="text/javascript">
var mouseevent_var = null;
function ValidateOnChange(e) {
var input = $('#txtInput').val();
if (input == '0') {
$('#divError').hide();
} else {
$('#divError').show();
}
}
function ValidateOnClick(e){
alert("Hurray!!! You got it right!");
}
$('#txtInput').mousedown(function (e) {
mouseevent_var = e;
});
jQuery(document).ready(function(){
$('#btnSubmit').click(function(e){
ValidateOnClick(e);
});
$('#txtInput').change(function(e){
ValidateOnChange(e);
});
//User don't want error when they are typing in.
//$('#txtInput').keyup(function() {
//$('#txtInput').trigger("change");
//});
});
</script>
</body>
</html>
The keyup event seemed to be solution but users don't want the error to popup when they are typing in.
Is there any way to list all the triggered events so that I could filter "mousedown" and "mouseup" events for submit button? Or is there any alternative way to prioritize click event ?
There can be many alternatives depending on the situations. I have made few minor changes to avoid the double click issue (comments amended). Basically we need to bind the mousedown event on the button object. There we will set a temporary flag variable to true. In the same time if input's change event gets fired then you can skip the checking if the temporary flag variable is true. Reason behind the double click for triggering the button's click event is better explained here: How to get jQuery click event after append in change event handler
Your updated js code below:
var mouseevent_var = false;
function ValidateOnChange(e) {
// Skip validation if the change event is fired due to user's click on submit button
if(mouseevent_var){ return false; }
var input = $('#txtInput').val();
if (input == 0) {
$('#divError').hide();
} else {
$('#divError').show();
}
}
function ValidateOnClick(e){
mouseevent_var = false; // Reset mouseevent_var to false
alert("Hurray!!! You got it right!");
}
$('#btnSubmit').mousedown(function (e) {
mouseevent_var = true;
});
jQuery(document).ready(function(){
$('#btnSubmit').click(function(e){
ValidateOnClick(e);
});
$('#txtInput').change(function(e){
ValidateOnChange(e);
});
//User don't want error when they are typing in.
//$('#txtInput').keyup(function() {
//$('#txtInput').trigger("change");
//});
});
The above code is just a fix as per your need. But there are other better alternatives too. Ideally you should not have two different validation functions for validating same fields on different events. You must think of managing it with a single function.
Related
I have a textbox and a button. The functionality is that whenever textbox is empty, button is disabled and if not empty then button is enabled. I am doing this using following jQuery code:
$('#user_field').keyup(function(){
if($(this).val().length !=0){
$('#btn_disabled').removeAttr('disabled');
$('#btn_disabled').attr('class', 'upload_button_active');
}
else{
$('#btn_disabled').attr('disabled',true);
$('#btn_disabled').attr('class','upload_button_inactive');
}
})
However, when I am trying to paste input using mouse, the button is not enabling. I have tried binding other mouse events like mousemove, but for that to work we have to move the mouse after pasting. I want to avoid that. Suggest something else.
You should use 'input'
$("#tbx").on('input',function(){
var tbxVal=$(this).val();
if(tbxVal.length===0){
$("#btn").prop("disabled",true);
}else{
$("#btn").prop("disabled",false);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="tbx">
<button id="btn" disabled>Button</button>
You can use the paste event and retrieve the value of the input inside a setTimeout
$('#user_field').on('paste input', function() {
setTimeout(() => {
if ($(this).val().length !== 0) {
$('#btn_disabled').removeAttr('disabled');
$('#btn_disabled').attr('class', 'upload_button_active');
} else {
$('#btn_disabled').attr('disabled', true);
$('#btn_disabled').attr('class', 'upload_button_inactive');
}
}, 1000)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type='text' id='user_field'>
<button id='btn_disabled' disabled='disabled'>Click</button>
Just Call the function on change.
It will take your input event from mouse as well.
$("#textBox").change(function(
var val=$(this).val();
if(val.length===0){
$("#btn").prop("disabled",true);
}else{
$("#btn").prop("disabled",false);
}
});
I'm trying to get the option that when a user presses the Return key, the search button is triggered.
Currently it can only be pressed on the search button, but sometimes users have the tendency to press the return key after the search entry.
$(document).ready(function() {
$('#search-button').keydown(function(event){
if (event.keyCode==13) {
Trackster.searchTracksByTitle($("#search-input").val());
}
});
$("#search-button").click(function(){
Trackster.searchTracksByTitle($("#search-input").val());
});
});
does anyone know what i did wrong here? i still cant use press return to trigger the search.
If you have a search input and a search button, an ideal practice is to get them wrapped by a form tag.
<form id="search-form">
<input type="text" id="search-input" ...>
<button type="submit" id="search-button" ...>Search</button>
</form>
Notice that the type is set to submit. It makes the button act as a submit button for the form. Now you will have to listen to the submit event of the form. The return key binding comes for free. Plus, you don't have to listen to the keydown and click events separately.
$(document).ready(function() {
$('#search-form').submit(function(event) {
event.preventDefault();
Trackster.searchTracksByTitle($("#search-input").val());
})
});
You will see that the search works when:
User types something in textbox and hits the return key
User types something in textbox and clicks on the submit button
I believe this solves your issue.
You have attached the keydown event on the search-button but in my opinion it has be attached on the search-input
$(document).ready(function() {
$('#search-input').keydown(function(event) {
if (event.keyCode === 13) {
Trackster.searchTracksByTitle($(this).val());
}
});
$("#search-button").click(function() {
Trackster.searchTracksByTitle($("#search-input").val());
});
});
This should work:
$(document).ready(function() {
var $btn = $('#search-button');
var $inElement = $btn.prev('input');
$inElement.keydown(function(event){
if (event.keyCode==13) {
Trackster.searchTracksByTitle($("#search-input").val());
}
});
$btn.click(function(){
Trackster.searchTracksByTitle($("#search-input").val());
});
});
I've got an input box that I want to have save its value when it loses focus.
Pretty straightforward stuff and I'm able to get that done via jQuery's focusout event.
The problem however, is that I want to NOT fire the focusout event when the user clicks on an "X" icon next to the input box (example shown below)
So when the user tabs out of this input box, or clicks outside of the box or they click the green checkbox it should fire the focusout event... but if they click the red "X", it should NOT fire the focusout.
Is this possible to do with JavaScript / jQuery?
EDIT:
Some of you have recommended using event.relatedTarget, but it seems like that's returning null. I'll include my code in question for clarity:
// This is the cancel button with the red X
$("body").on("click", "span[id*='Cancel']", function(e)
{
showLabel($(this));
});
// this is the code to trigger the blur / focusout event
// trouble is that the "e.relatedTarget" is null
$("body").on("focusout", "input, textarea", function (e) {
if($(e.relatedTarget).is("span[id*='Cancel']")){
return false;
}
$(this).siblings("span[id*='OK']").trigger("click");
return false;
});
Here's a screen grab of me debugging this in JS (you'll see that the $(e.relatedTarget) selector returns nothing):
You can cancel de event returning the focus to previous element.
$('#inputText').focusout(function(event) {
setTimeout(function(){
if (document.activeElement.id == "btnCancel") {
$(event.target).focus();
return false;
}
},1);
});
This jsFiddle shows how to do it: https://jsfiddle.net/mpervh3t/
Hope it helps
You must use relatedTarget like this :
$(document).ready(function(){
$(".btn").on("focusout",function(e){
if($(e.relatedTarget).hasClass("red")) {
alert("You clicked on X button");
}
else {
alert("Fire Focus out")
}
})
})
Final code :
<!DOCTYPE html>
<html>
<head>
<style>
.gr {
color: green;
}
.red {
color: red;
}
</style>
</head>
<body>
<input type="text" class="btn"><button class="gr">Ok</button><button class="red">X</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
$(document).ready(function(){
$(".btn").on("focusout",function(e){
if($(e.relatedTarget).hasClass("red")) {
alert("You clicked on X button");
}
else {
alert("Fire Focus out")
}
})
})
</script>
</body>
</html>
As per my comment:
"I have had to do a similar type of thing with a blur event. Basically what I had to do was call a setTimeout on the blur to execute my function to save the data, and then on the click event of the X, cancel the timeout. That way, unless the X is clicked, the save function will fire. The delay can be pretty negligable, too."
I found the relevant code
var sliderTimeout = null;
$(".slider-trigger").on("blur", function () {
sliderTimeout = setTimeout(function () {
$(".slider").hide();
}, 100);
});
$(".ui-slider-handle").on("focus", function () {
clearTimeout(sliderTimeout);
});
Here is the full demo of the code in action. It does much more than demonstrate this, but if you examine the behavior of focusing/blur on the "margin" input, you will see that if you blur the margin input, the slider hides, but if you click on the slider, it cancels the hide and stays shown. It's the exact same concept, just a slightly different application.
Here, I did the thing.
https://jsfiddle.net/kowmLf2a/1/
In the blur event I target the related target. See if that related target is the item that I don't want to blur with. If it is then return false.
Code for reference:
$('#input').blur(function(event){
if($(event.relatedTarget).is('#bt2')){
return false;
}
alert($(this).val());
});
How could I tell if the focusout event occured due to an enter press = form submit or just because of clicking away? The event data which goes to the console is of type "focusout" and has no relevant information
$(".clientrow[clientid="+clientid+"] td."+fieldname+"").bind("focusout", function(event){
console.log(event);
setTimeout(function() {
if (!event.delegateTarget.contains(document.activeElement)) {
$(".clientrow[clientid="+clientid+"] td."+fieldname+"").html(
$(".clientrow[clientid="+clientid+"] td."+fieldname+" input[type=text]").val()
);
}
}, 0);
});
Edit: As Oriol pointed in the comments, this will not work in Mozilla. If you are looking only for webkit browsers, you can try this approach. But as a generic solution, try binding an event on submit button and consecutively set a flag which identifies the element. Based on the element, you can detect whether it's an actual blur or not.
You can look out for relatedTarget property in the event.
Demo: http://jsfiddle.net/GCu2D/782/
JS:
$(document).ready(function () {
$("input").on("blur", function (e) {
console.log(e);
if (e.relatedTarget) {
console.log("Because of button");
} else {
console.log("Just a blur")
}
});
});
HTML:
<form>
<input type="text" />
<button type="button">Submit</button>
</form>
You'll have to replace the focusout with blur event. When the blur is due to a click on a button, the relatedTarget property will have button as value but in other cases it will be null.
In the case that a button is clicked multiple times on a page - Is there a way to figure out using javascript/jquery that a postback is already in progress and cancels the new attempt to submit the page?
Thanks
You can avoid users from double clicking by disabling whatever form elements can cause a form submit.
Checkout http://greatwebguy.com/programming/dom/prevent-double-submit-with-jquery/ for an example.
You can disable the button on first click, so that you could not click it when the post is in progress, and re enable it when the post-back has finished.
<script type="text/javascript" language="JavaScript">
var submitted = false;
function SubmitTheForm() {
if(submitted == true) { return; }
document.myform.submit();
document.myform.mybutton.value = 'Thank You!';
document.myform.mybutton.disabled = true;
submitted = true;
}
</script>
<form method="post" action="#">
<input type="submit" onclick=return SubmitTheForm()>
</form>
you could always just disable the button in the onclick handler.
$('input[type="submit"]').click(function(e) {
e.preventDefault();
var self = this;
$(self).attr('disabled', 'disabled');
$.post('url',$(self).closest('form').serialize(), function() {
$(self).removeAttr('disabled'); // re-enable after request complete.
});
});
You could have your click event set a variable in your click handler to true and only allow the handler to proceed when the value is false. Of course you will have to set it to false again when your callback finishes.
if (!processInProgress) {
processInProgress = 1
// start the process
}