Function gets called twice for each click - javascript

The $(".actionsAdListnTo").click function is getting fired twice.
I tried various solutions posted in StackOverflow but nothing worked.
What is the reason of twice firing any pointers please.
How to avoid this?
$(".actionsAdListnTo").click(function (e) {
$('#actionsAdListnTo').slideToggle();
});
$(".ddlAddListinTo li").click(function () {
var urlstring = "../ActionTypes";
var ddlselectedVal = $(this).attr('id');
var $form = $("#frmPostToEmailReports");
var selectedListinsCount = selected_Listings.length;
var SelectedMlsnums = selected_Listings.join();
if (ddlselectedVal != "None" && ddlselectedVal != "select") {
//*********** To Cart Functionality
if (ddlselectedVal == 'Tocart') {
if (selectedListinsCount > 500) {
if ($('#errmesg').length == 0) {
$('.messageCenter').append('<span id="errmesg" class ="errmesg"> <span class="messageIcon"></span><span>The maximum number of listings you may select To Add to cart is 500.</span></span>');
return false;
}
} else {
$.post(urlstring,
function (data) {
$(window.open(urlstring, '_blank', 'width=750, height=400')).load(function (e) {
var $formCopy = $("#frmPostToEmailReports").clone();
$($formCopy).append('<input id="SelectedMlsnums" name="SelectedMlsnums" type="hidden" value="' + SelectedMlsnums + '">');
// Here "this" will be the popup window. insert a form element into the popup window.
$(this.document).find("#divfrmInfo").html($formCopy);
e.preventDefault();
});
});
}
}
}
});
HTML :
<div class="actionsAdListnTo">
<span> Add Listing To</span>
<ul id="actionsAdListnTo" class="ddlAddListinTo" style="display: block;">
<li id="Tocart">To CART</li>
<li id="Toportal">To Portal</li>
<li id="SaveListings">Save Listing</li>
</ul>
</div>

The click on li bubbles to its parents, one of them being <div class="actionsAdListnTo">, so the parent's click handler is also called. Try to stop propagation of the click on li:
$(".ddlAddListinTo li").click(function (e) {
e.stopPropagation();
...

In this case it looks it would be more correct to target the link only for the toggle and not the outer div. Be as specific with your selectors as possibe, similar to this:
$(".actionsAdListnTo a#select").click(function (e) {
$('#actionsAdListnTo').slideToggle();
});
If you want to be more specific without an id using the structure, you could do it simlar to:
$(".actionsAdListnTo > span:first > a").click(function (e) {
$('#actionsAdListnTo').slideToggle();
});
Anyway, the way your HTML is structured there is no need to have the toggle triggered by the div as only the link should react to it.
DEMO - Getting more specific with the selector

What I see here is that you are defining two events in the same place, the second one on a child.
$(".actionsAdListnTo").click( function(e){
...
});
$(".ddlAddListinTo li").click(function () {
...
})
Maybe you can use e.sTopPropagation() in the second one, or e.preventDefault()

Related

Override inline click event in jQuery

I have links in a navigation that look similar to this
<a id="navform" href="#" tabindex="-1" onclick="mojarra.ab(this,event,'action','#form','content');return false" class="active"><span>Policy</span></a>
I am checking for form changes and trying to disable the onclick event for the links when there are changes and enable them if once the user saves the form.
$(':input').on('change', function() {
formChanged = true;
});
$('nav a').on('click', function(e){
if(formChanged){
e.preventDefault();
$(this)[0].onclick = null;
}
});
I have tried preventDefault and nulling the event according to some answers I found on here, but no luck. Could someone please tell me how to fix this?
UPDATE:
Thanks to all your answers, I got some ideas and figured how to fix it:
if($('.policy-form')){
$(':input').on('change', function() {
formChanged = true;
$('nav a').each(function(){
var handler = $(this).attr('onclick');
$(this).removeAttr('onclick');
$(this).on('click',function(){
if(formChanged){
invokeDialog("warning");
formChanged = false;
$(this).attr('onclick', handler);
}
});
});
});
Plain JavaScript one-liner
Use
document.getElementById('navform').onclick = null;
This is because only the last onclick defined will run and here we override it with null.
Note that it would be way better if you would just avoid onclick in your HTML, or if you would at least modify mojarra.ab() appropriately, so that it performs any actual actions only when you desire.
Demo:
document.getElementById('one').onclick = null;
<a id="one" href="#" onclick="alert(true)">Doesn't alerts</a>
<br/>
<a id="two" href="#" onclick="alert(true)">Does alerts</a>
EDIT
Vide comment, here is an example of toggling old onclick on and off:
var button = document.getElementById('button');
var oldOnclick = button.onclick;
document.getElementById('toggle').addEventListener('click', function() {
button.onclick = button.onclick !== null ? null : oldOnclick;
})
<input id="button" type="button" onclick="alert('Test')" value="Alert"/>
<br/>
<br/>
<input id="toggle" type="button" value="Toggle above button"/>
$('nav a').on('click', function(e){
$(this).removeAttr('onclick'); // add this line to remove inline onclick
if(formChanged){
e.preventDefault();
$(this)[0].onclick = null;
}
});
You can use the .off() method:
$('nav a').off('click');
One good practive is to add an namespace to your events.
$('nav a').on('click.somenamespacehere', function(e){
});
...
$('nav a').off('click.somenamespacehere');
In this case, you can specify later which events you want to remove (with the off method)
You can't do it that way because the on('click' event and the inline one are two different events and there's no way to tell which would happen first. But, you could replace the inline handlers with your own handler like so
on('click', function(e) {
if (formChanged) {
mojarra.ab(...);
}
});
With an inline click function there are many possibilities to control the logical flow or order of executing the functions attached to the same event.
One possibility is to change the inline code so that you can define a first function and based of the result of this you may decide if execute or not the next function.
My snippet:
// assuming the inline onclick function is like:
function mojarra_ab(_this, event, _action, _form, _content) {
$('<p>Executed function: mojarra_ab</p>').appendTo('body');
}
function myNewClick() {
$('<p>Executed function: myNewClick</p>').appendTo('body');
if ($('#yesNo option:selected').val() == 'true') {
return true; // return true to execute the mojarra_ab function
}
return false; // return false if you don't need to execute the mojarra_ab function
}
$(function () {
$('nav a').attr('onclick', function(index, attr) {
return 'if (myNewClick() == true) {' + attr + '}';
});
});
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
Choose if to run myNewClick and then mojarra_ab: <select id="yesNo">
<option value="true" selected>True</option>
<option value="false">False</option>
</select>
<nav>
<a id="navform" href="#" tabindex="-1" onclick="mojarra_ab(this,event,'action','#form','content');return false"
class="active"><span>Policy</span></a>
</nav>

How to keep active class when changing pages

I am trying to add an active class to nav item, depending what page your on. I am using this script:
<script type="text/javascript">
$(document).ready(function () {
$("#side-bar a").click(function () {
var id = $(this);
$(id).siblings().find(".active").removeClass("active");
$(id).addClass("active");
localStorage.setItem("selectedolditem", id);
});
var selectedolditem = localStorage.getItem('selectedolditem');
if (selectedolditem !== null) {
$(selectedolditem).siblings().find(".active").removeClass("active");
$(selectedolditem).addClass("active");
}
});
</script>
See full jsfiddle here: https://jsfiddle.net/ebo7hLo9/
It adds the active class, but it loads a new page, it disappears. What am I doing wrong?
https://jsfiddle.net/ebo7hLo9/10/ - here's a fiddle!
$(document).ready(function () {
$("#side-bar a").click(function () {
var id = $(this);
$(".active").removeClass("active");
$(id).addClass("active");
localStorage.setItem("selectedolditem", $(id).text());
});
var selectedolditem = localStorage.getItem('selectedolditem');
if (selectedolditem !== null) {
$("a:contains('" + selectedolditem + "')").addClass("active");
}
});
Your code was having issues remembering what element to grab. I think it's due to the web storage API's unfamiliarity with objects. Instead I got the text from the element that was selected, stored it in localStorage and on page load matched it with the correct element. Also there was part of your code that was dealing with finding the class "active" within the siblings() of the selected element and removing it. That complex of code is largely unnecessary. I replaced it with the class selector $(".active")
I didn't change this in the code, but I'd advise against using localStorage in favor of sessionStorage so that the storage will clear itself on tab/browser close.
For more info take a look at this previous stackoverflow post: Storing Objects in HTML5 localStorage
Here is a possible solution: https://jsfiddle.net/6yyLpma1/
$("#side-bar a").click(function () {
var id = $(this);
$('#side-bar').find(".active").removeClass("active");
$(id).addClass("active");
localStorage.setItem("selectedolditem", id);
});
Instead of $(id).siblings() use $('#side-bar'). Use the same logic in other location.
Using data elements and a delegate function: https://jsfiddle.net/ebo7hLo9/12/
HTML
<span id="delegateAnchor">
<div id="side-bar">
<ul>
<li>Home</li>
<li>Who we are</li>
<li>Services</li>
<li>What to expect</li>
<li>Representative clients</li>
<li>Success stories</li>
<li>Current litigation</li>
<li>What if you could not be a doctor?</li>
</ul>
</div>
</span>
Javascript
$(document).ready(function () {
$('#delegateAnchor').on('click', '#side-bar a', function() {
var $this = $(this);
var linkId = $this.data('desc');
$this.closest('ul').find('a').removeClass("active");
$this.addClass("active");
localStorage.setItem("menuSelection", linkId);
});
var selectedLinkId = localStorage.getItem("menuSelection");
if (selectedLinkId !== null) {
$('#side-bar a[data-desc="'+ selectedLinkId +'"]').trigger("click");
}
});

Disable <a href> in runtime using Javascript

Using Bootstrap
<ul class="nav nav-pills nav-stacked col-sm-2 hidden" id="menu">
<li role="presentation" id="LiNewsFeed">News Feed</li>
<li role="presentation" id="LiStatusUpdate">Update Status</li>
<li role="presentation" id="LiWriteWall">Post On Wall</li>
<li role="presentation" id="LiNotifications">Notifications</li>
<li role="presentation" id="LiLogOut">Logout</li>
</ul>
In Javascript, I am disabling some of the <li> like the following:
$('#LiNewsFeed').addClass('disabled');
The Item in the List actually LOOKS disabled, when when I click on it, it actually calls the javascript function, therefore, what I need is to disable the <a href> not just the <li>
I tried adding this after $(document).ready:
$(".nav li.disabled a").click(function () {
return false;
});
But it's not really doing anything.
What I need is to disable the <a href> directly after disabling <li> in my Js code, and not to depend on a click event...
Seems like there is no way to disable an <a href>, so I need a way around it
Any help would be appreciated.
use below code. check working example JSFIDDLE
$(".nav li.disabled a").each(function(){
$(this).attr('href','javascript:void(0);');
});
As you are disabling LI in javascript (runtime), you should use .on to bind events on disabled links:
$(".nav").on('click', 'li.disabled a', function () {
return false;
});
I would check on every link click if the parent has the disabled class.
$('.nav li a').click(function () {
if($(this).parent('li').hasClass('disabled')) {
return false;
}
return true;
});
EDIT, following more info from OP I would suggest the following:
$('.nav li a').each(function() {
var $this = $(this);
// store reference of 'href' attr in case link is re-enabled
$this.data('href', $this.attr('href'));
if ($this.parent('li').hasClass('disabled')) {
// remove href attribute disabling click
$this.removeAttr('href');
} else {
// restore href
$this.attr('href', this.data('href'));
}
});
This code should be run after you add/remove the disabled class on li elements.
EDIT 2 - Rather than you calling functions from the href of <a> links, you could do something like the following:
var events = {
'#LiNewsFeed': 'GetNewsFeed',
'#LiStatusUpdate': 'StatusUpdate'
'#LiWriteWall': 'WriteOnWall',
'#LiNotifications': 'GetNotifications',
'#LiLogOut': 'LogOut'
};
for (var selector in events) {
if (events.hasOwnProperty(selector)) {
try {
$(selector).click(function () {
// assuming function is global
if (typeof window[events[selector]] === 'function') {
// call function
window[events[selector]]();
}
// this is needed if the a element still has a href attr
return false;
});
} catch (e) {
console.log('Invalid Selector');
}
}
}
This way you can control the calling of the function, and check whether it should be called without altering the element, perhaps stick an
if (!$(this).parent('li').hasClass('disabled')) {
...
}
around the function call.
can you convert the a into span?
(code not tested)
$(".nav li.disabled a").replaceWith(function() { return "<span>" + this.innerHTML + "</span>"; });

Toggle one anchor link at time with Jquery

Would like to toggle my active class, so when I click on one link on the page, only one link is active with the class at a time, through out my page as I click on any of the links. Could someone help me come up with a feasible solution adding to my code?
JavaScript
//Global definition
var activeState = $(".category-tree-with-article .article-list > li > a");
activeState.on('click', function (e) {
e.preventDefault;
// For class changes
activeState.toggleClass('active');
});
CSS
.active {
font-family:'MaxPro'
}
remove the class on all the other links and add the class on the clicked one
var activeState = $(".category-tree-with-article .article-list > li > a");
activeState.on('click', function (e) {
e.preventDefault;
activeState.removeClass('active');
$(this).addClass('active');
});
If you only want to do the current one then change -
activeState.toggleClass('active');
to this -
activeState.removeClass('active');
$(this).toggleClass('active'); // can still turn on and off on this element
Don't use toggle in this case
var links = $('.selector-to-your-links');
links.on('click', function(e) {
var link = $(this);
link.addClass('active');
links.not(link).removeClass('active');
return false; // I like this better than e.preventDefault() as it also does e.stopPropagation()
});

how can i add an attribute onClick oto my links generated automatically?

I would like to add an attribute onClick to my links generated automatically with jquery.
I select the parent div and then search if it has a link child, then add the attribute onClick.
It works on localhost but not on server
there is my code :
$('div.holder_notify_drop_data,li.holder_notify_drop_data').each(function () {
if ($(this).children('a').hasClass('holder_notify_drop_link')) {
$(this).on('click', function (e) {
var url = $(this).children('a').attr('href');
$(this).children('a').attr('onClick', "openFrame('" + url + "','yes')");
e.preventDefault();
});
};)
};
How can i do this ?
Make sure you include jQuery:
<script src="http://code.jquery.com/jquery-latest.js"></script>
IMPORTANT: Also put your code inside a document-ready function and I would suggest you to use jQuery click() function instead of the way you have done, but that's okay:
$(document).ready(function () {
$('div.holder_notify_drop_data,li.holder_notify_drop_data').each(function(){
if ($(this).children('a').hasClass('holder_notify_drop_link')){
$(this).on('click',function(e) {
var url = $(this).children('a').attr('href');
$(this).children('a').attr('onClick',"openFrame('"+url+"','yes')");
e.preventDefault();
});
};
)};
});
Here's a working example http://jsfiddle.net/g248G/.
HTML:
<div class="holder_notify_drop_data">
<a class="holder_notify_drop_link"
href="http://stackoverflow.com">Stackoverflow.com</a>
</div>
<ul>
<li class="holder_notify_drop_data">
<a class="holder_notify_drop_link"
href="http://google.com">Google.com</a>
</li>
</ul>
Javascript:
function openFrame(URL, option) {
window.open(URL);
}
$(document).ready(function() {
$('div.holder_notify_drop_data,li.holder_notify_drop_data').each(function() {
$(this).children('a').each(function() {
var $link = $(this);
if ($link.hasClass('holder_notify_drop_link')) {
var URL = $link.attr('href');
$link.on('click', function(event) {
event.preventDefault();
openFrame(URL, 'yes');
});
}
});
});
});
Why not use jQuery.on() for that?
This will bind click function to all current and future elements of a in holder_notify_drop_data container.
$('.holder_notify_drop_data').on('click', 'a', function (ev) {
ev.preventDefault();
openFrame($(this).prop('href'), 'yes');
});

Categories