How to stop an event for raising - javascript

I have two fields, one textbox and one div element.
I have an onblur event for textbox, and an onclick event for div element.
When I click the div element the textbox's onblur event occurs and not the onclick event of div element. How to suppress the onblur event when I click on the div element?

try to use a semafore.
if the click event is triggered set the semafore to true and check the value in the blur event call. if true - do not perform the action.
after successfully performing the click event reset the semafore to false.

I'm not sure what you are trying to do and is it right way or not.
But this will solve your problem by using flag named "f":
<head>
<script type="text/javascript">
var f = 0;
function f1() {
if (f == 0)
alert('blur');
}
function f2() {
alert('click');
}
function f3() {
f = 1;
}
function f4() {
f = 0;
}
</script>
</head>
<body>
<input type="text" onblur="f1();" />
<div onclick="f2();" onmouseover="f3();" onmouseout="f4();">
Click Me!
</div>
</body>
Good luck!

Related

Can you stop the jQuery focusout from firing when losing focus?

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());
});

Prevent onclick from firing

I was working around with form submissions in html. Please take a look at below code
<form id="form1">
<button id="btn1" onclick="clicked();">Submit</button>
</form>
<script>
$("#btn1").click(function (event) {
alert("event triggered");
if(some_condition == true){
// stop firing onclick method but it always submits the form
event.stopImmediatePropogation(); // not working
event.preventDefault(); // not working
event.stopPropogation(); // not working it's for bubbled events
}
});
function clicked(){ alert("clicked me"); }
</script>
I want to stop clicked() function from firing which is attached to inline onclick attribute. I would like to run my jquery click function and if something goes wrong, I dont want to trigger onclick but it always runs clicked() function. Could any one help me. Any help is greatly appreciated.
The order in which an onxyz handler is called relative to dynamically-attached handlers varies from browser to browser, so your handler may well not run before the original does.
To deal with that, you save and remove the onclick handler:
var btn = $("#btn1");
var clickHandler = btn[0].onclick;
btn[0].onclick = false;
Then, in your handler, if you want that function to be called, you call it:
clickhandler.call(this, event);
Example:
// Get the button
var btn = $("#btn1");
// Save and remove the onclick handler
var clickHandler = btn[0].onclick;
btn[0].onclick = false;
// Hook up your handler
$("#btn1").click(function(event) {
alert("event triggered");
if (!confirm("Allow it?")) {
// Disallowed, don't call it
alert("stopped it");
} else {
// Allowed, call it
clickHandler.call(this, event);
}
});
// The onclick handler
function clicked() {
alert("clicked me");
}
<form id="form1" onsubmit="return false">
<button id="btn1" onclick="clicked();">Submit</button>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Try event.stopPropagation()
api docs
if condition is true then remove the 'onclick' attribute
if (some_condition == true) {
$("#btn1").removeAttr('onclick').click(function(event) {
alert("event triggered");
//do something
});
}
function clicked() {
alert("clicked me");
}
I am sharing a quick workaround without knowing why you cannot add logic to stop adding "onclick="clicked();" code which you are saying getting automatically added.
I recommend you hide button with id as "btn1". Add style display:none. You donot need on ready function for this but simply add style attribute to the button btn1 or if that is also not possible directly then use jQuery to do that post document ready.
Read :
How to change css display none or block property using Jquery?
Then add a new button to the form using jQuery with id as "btn2" and add register the btn2 click event as well. DO this after form load.
<form id="form1">
<div id="newbut">
<button id="btn1" onclick="clicked();">Submit</button>
</div>
</form>
jQuery("#newbut").html('<button id="btn2">Submit</button>');
$(document).on('click', '#btn2', function(){
// Your Code
});
Refer below url to how to register click event for new button:
Adding click event for a button created dynamically using jQuery
jquery - Click event not working for dynamically created button
Can't you do the condition check and the clicked() logic in one function? i.e
<script>
function clicked() {
if(some_condition == true){
return;
}
alert("clicked me");
}
</script>

Javascript click event firing twice, even with stopPropagation

I have a set of items like this:
<label for="Cadenza-1" class="cars">
<input type="checkbox" value="1" alt="Cadenza" id="Cadenza-1" name="vehicles[]">
<img src="img/bill_murray_173x173.jpg">
<span>Cadenza</span>
</label>
there's about 13 of them. I want to add a class to the label when clicked. However, the click event fires twice. right now I'm debugging the click event then I'll add the class:
var cars = document.getElementsByClassName('cars');
for(var c = 0;c < cars.length; c++){
cars[c].addEventListener("click", function(e){
selectVehicle(cars[c],e);
},false);
}
function selectVehicle(el,e) {
console.log(e);
e.stopPropagation();
}
The console.log fires twice.
Try adding preventDefault after your stopPropogation:
function selectVehicle(el,e) {
console.log(e);
e.stopPropagation();
e.preventDefault();
}
I believe it is best to place console.log(e) after the stopPropogation & preventDefault though. You will also then need to implement functionality to set the checkbox to checked since this would prevent that from happening.
When the <span> or the <img> receives a "click" event, that'll bubble up the DOM to the <label> element, and your event handler will be called. The <label> then triggers another "click" event on the <input> element, and that also bubbles up to the <label>.
You can check in the handler to see whether the <input> was clicked:
function selectVehicle(el,e) {
if (e.target.tagName !== "INPUT") return;
// do stuff
}
Alternatively, you could just add the "click" handler only to the <input> itself.
Now you're also going to notice that your code isn't working because you've hit a common problem with binding event handlers inside loops. The problem is that the variable c will have as its value the length of the cars list by the time the event handlers actually run. There are a few ways of dealing with that; one is to loop with forEach() instead of a for loop:
[].forEach.call(cars, function(car) {
car.addEventListener("click", function(e){
selectVehicle(car,e);
}, false);
});
You are adding the event listener to the label, you should add the event listener to the checkbox because the label behavior copy the same of the input assigned in for.
Please note that if you click just in the checkbox the callbacks works fine, this is because the event on the label is raised by the checkbox.
The right way to do that is to add the event listener only for the checkbox or adding prevent default in the setlectVehicle callback.
You are not required to preventDefault or stopPropagation, but just to add listner on the input element.
cars[c].children[0].addEventListener("click", function(e) {
Try this. It is working as expected.
Additionally, you are not required to use Id's with label's for if the label element encloses the required input/other elements
var cars = document.getElementsByClassName('cars');
for (var c = 0; c < cars.length; c++) {
cars[c].children[0].addEventListener("click", function(e) {
selectVehicle(cars[c], e);
}, false);
}
function selectVehicle(el, e) {
console.log(e);
}
<label class="cars">
<input type="checkbox" value="1" alt="Cadenza" name="vehicles[]">
<img src="img/bill_murray_173x173.jpg">
<span>Cadenza</span>
</label>
<label class="cars">
<input type="checkbox" value="1" alt="Cadenza" name="vehicles[]">
<img src="img/bill_murray_173x173.jpg">
<span>Cadenza 2</span>
</label>

javascript event handlers list

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.

How to stop onclick event in div from propagating to the document?

I want to stop propagation of this div's onclick event to the document? When the user click on the "div", both alerts appear: 1) the div's alert and 2) the document's alert. I want to suppress the document alert.
I know how to do it using addEventListener, but is there another way to to do it? The problem below is that I don't know how to get ahold of the event -- I tried "event = element.onclick", shown below, but that doesn't work. How do I get the event?
<head>
<script>
function showMenu(element) {
alert("div clicked");
event = element.onclick; // HOW TO GET HOLD OF THE EVENT?
// Don't propogate the event to the document
if (event.stopPropagation) {
event.stopPropagation(); // W3C model
} else {
event.cancelBubble = true; // IE model
}
}
document.onclick = function() {
alert('document clicked');
};
</script>
</head>
<body>
<div id="foodmenu" onclick="showMenu(this);">Click inside this div</div>
or click outside the div.
</body>
Change your function definition to include the event:
function showMenu(event, element) {
alert("div clicked");
// Don't propogate the event to the document
if (event.stopPropagation) {
event.stopPropagation(); // W3C model
} else {
event.cancelBubble = true; // IE model
}
}
Then change the call to pass in the event:
div id="fooddmenu" onclick="showMenu(event, this);">Click inside this div</div>
Try EventListeners:
html:
<div id="fooddmenu">Click inside this div</div>or click outside the div.​​​​​​​​​​
js:
function showMenu(e) {
alert("div clicked");
}
document.onclick = function() {
alert('document clicked');
};
window.onload = function(){
document.getElementById("fooddmenu").addEventListener("click", function(e){
showMenu(this);
e.stopPropagation();
});
};
Add the onclick to the body element.
Douglas,
It does stop the event from getting bubbled up.
Check this out http://jsbin.com/ahoyi/edit
here, if you comment the alert statement, it will show 2 alerts on clicking the smaller box else only one.
Hope this helps.
well, that's a jquery code.
$("#id") same as document.getElementById("id")
.click function is same as addEvent("click", function() { ... } );
so basically both the functions there are click handlers for Parent and Child DIVs.
Observe the output by commenting / uncommenting the "return false;" statement.
Hope that helps.
By the way, sorry for that "$" confusion.
$("div").click(function(){
...
...
...
return false; //this will stop the further propagation of the event
});
Add Pointer-events: none to the particular element will help to stop pointer events.
event.StopPropagation() will help us to avoid child propagating

Categories

Resources