preventDefault not working on anchor - javascript

I'm trying to log the click on an anchor that's being generated asynchronously.
The asynchronous call - which works perfectly fine - looks like this:
$("#txt_search").keyup(function() {
var search = $("#txt_search").val();
if (search.length > 0)
{
$.ajax({
type: "post",
url: "<?php echo site_url ('members/searchmember') ;?>",
data:'search=' + search,
success: function(msg){
$('#search_results').html("");
var obj = JSON.parse(msg);
if (obj.length > 0)
{
try
{
var items=[];
$.each(obj, function(i,val){
items.push($('<li class="search_result" />').html(
'<img src="<?php echo base_url(); ?>' + val.userImage + ' " /><a class="user_name" href="" rel="' + val.userId + '">'
+ val.userFirstName + ' ' + val.userLastName
+ ' (' + val.userEmail + ')</a>'
)
);
});
$('#search_results').append.apply($('#search_results'), items);
}
catch(e)
{
alert(e);
}
}
else
{
$('#search_results').html($('<li/>').text('This user does not have an account yet'));
}
},
error: function(){
alert('The connection is lost');
}
});
}
});
The anchor I want to get to is <a class="user_name" href="" rel="' + val.userId + '">' + val.userFirstName + ' ' + val.userLastName + ' (' + val.userEmail + ')</a>'
I detect the click on these anchors with this function:
// click op search results
$("a.user_name").on('click', function(e) {
e.preventDefault();
});
The problem seems to be that the preventDefault is not doing anything... I've looked at most of the questions involving this problem on Stackoverflow and checked jQuery's own documentation on the topic, but I can't seem to find what's wrong. I've tried adding a async: false statement to the AJAX-call, because perhaps the asynchronous call might be the problem, but that didn't fix it.

Event does not bind with dynamically added element unless you delegate it to parent element or document using on(). You have to use different form of on for event delegation.
$(document).on('click', 'a.user_name', function(e) {
e.preventDefault();
});
delegated events
Event handlers are bound only to the currently selected elements; they
must exist on the page at the time your code makes the call to .on().
To ensure the elements are present and can be selected, perform event
binding inside a document ready handler for elements that are in the
HTML markup on the page. If new HTML is being injected into the page,
select the elements and attach event handlers after the new HTML is
placed into the page. Or, use delegated events to attach an event
handler, as described next.
Delegated events have the advantage that they can process events from
descendant elements that are added to the document at a later time. By
picking an element that is guaranteed to be present at the time the
delegated event handler is attached, you can use delegated events to avoid the need to
frequently attach and remove event handlers, Reference

The .on() syntax you showed will only bind handlers to elements that match the selector at that moment - not to elements added in the future. Try this instead:
$("#search_results").on("click", "a.user_name", function(e) {
e.preventDefault();
});
This binds a handler to the parent element, and then when a click occurs jQuery only calls your callback function if the actual target element matches the selector in .on()'s second parameter at the time of the click. So it works for dynamically added elements (as long as the parent exists at the time the above runs).

This should work for you -
$('.search_result').on('click', 'a.user_name', function(){
// your code here
// code
return false;
});

try this
$("a.user_name").on('click', function(e) {
return false;
});
or
$(document).on('click', 'a.user_name', function(e) {
e.preventDefault();
});
Difference between .on() functions calls

May be your a href linked with other listeners too. Check with event.preventDefault
event.stopImmediatePropagation();
together.
You can check this site for more info
https://codeplanet.io/preventdefault-vs-stoppropagation-vs-stopimmediatepropagation/

I had this problem too, and it turned out my selector was wrong.

Related

How can I submit a Form with <a> that Was Created Appending Stuff

This is what I currently have:
var popupContent = ''
function createMessage(msg,pl) {
return [
"<p>" + msg + "</p>",
"<form action='" + pl + "' method='post' accept-charset='utf-8'>",
"<ul class='cd-buttons no_margin'>",
"<li><a class='submit'>Yes</a></li>",
"<li><a class='popup-close'>No</a></li>",
"</ul>",
"</form>",
"<a class='cd-popup-close popup-close img-replace'>Close</a>"
].join('');
}
//Accept Employement Request
$('.popup1').on('click', function() {
employeeName = $(this).siblings('.js-employee-name').text();
var message = "Are you sure you want to hire <b>" + employeeName + "</b>?"
var postLink = "/hire-employee"
createMessage();
$(".cd-popup-container").append( createMessage(message, postLink) );
});
$('.submit').click(function(){
$('form').submit();
});
But this doesn't seem to work.
So how can I submit this the form created by the createMessage function when the with that class submit is clicked?
Thank you very much. Let me know if I wasn;t clear enough.
I would recommend you to use <button> instead of anchor and use the default behavior of the button.
Use
<button class='submit'>Yes</button>
However, Solution for your immediate problem.
Currently what you are using is called a "direct" binding which will only attach to element that exist on the page at the time your code makes the event binding call.
Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time.
As you are creating elements dynamically.
You need to use Event Delegation. You have to use .on() using delegated-events approach.
General Syntax
$(staticParentElement).on(event, selector, eventHandler);
Example
$(".cd-popup-container").on('click', '.submit', function(event){
$('form').submit();
event.preventDefault(); //Cancel default behaviour of anchor
});

Jquery .replaceWith not working proper

i have a jquery code that is preventing a link to go to that link but executing it. The problem i have is that after it executs the script and script is returning data i want to replace it with a new one but with the same class. The replace is doing inside the dom but next time i press that link is not prevening going to that link but the class is the same, here is my code:
<script>
$(".recomanda").click(function(e){
e.preventDefault();
var test=$(this);
var href = $(this).attr('href');
$.getJSON(href, function(data) {
if(data.recom==1)
{
$(test).replaceWith('<a class="recomanda" href="app/recomanda_produs.php?id=' + data.id + '&recom=' + data.recom + '">Recomandat</a> ');
}
if(data.recom==0)
{
$(test).replaceWith('<a class="recomanda" href="app/recomanda_produs.php?id=' + data.id + '&recom=' + data.recom + '">Recomanda</a> ');
}
});
});
</script>
html
<a class="recomanda" href="app/recomanda_produs.php?id='.$row['ID_Produs'].'&recom=0">Recomanda</a>
yeah, I ran into that problem too before, it's because when you attach click to recomanda on ready(), but when ajax load, everything in ready() won't fire again, that why you need to attach the event to non-dynamic elements, and let it find it's child selector.
$('body').on('click', '.recomanda', function() {});
When you call a replaceWith actually you are removing elements that are bound to onclick handler:
.replaceWith()
Description: Replace each element in the set of matched elements with
the provided new content and return the set of elements that was
removed.
The main idea is that you handler must be bound to the same element (that is not removed when clicking).
So instead of using replaceWith method use method that modify existing element like this:
test.attr('href', blablabla);
And this is not a problem, but second time you don't need to use $ with test variable.
You need to delegate the event to a parent so that it can be applied to specific children wether they exist now or in the future.
See: http://learn.jquery.com/events/event-delegation/
$("body").on("click", ".recomanda", function(e){
e.preventDefault();
var test=$(this);
var href = $(this).attr('href');
$.getJSON(href, function(data) {
if(data.recom==1){
$(test).replaceWith('<a class="recomanda" href="app/recomanda_produs.php?id=' + data.id + '&recom=' + data.recom + '">Recomanda"+((data.recom==1)?"t":"")+"</a> ');
}
if(data.recom==0){
$(test).replaceWith('<a class="recomanda" href="app/recomanda_produs.php?id=' + data.id + '&recom=' + data.recom + '">Recomanda</a> ');
}
});
});

Why is click event handler for a submit button in a colorbox defined in a jQuery prototype method not invoked

I have added a function to jQuery prototype as below. What I want to do is when this method is invoked, generate an html form based on the arguments passed to the method and show it in a colorbox.
(function($) {
$.fn.myFunction = function(data){
var form = $('<form name="people"></form>');
var index;
for (index = 0; index < data.length; index++) {
var match = data[index];
$('<input type="radio" name="person">' + match['name'] + ' [' + match['uri'] + ']<br> ')
.attr("value", match['uri'])
.appendTo(form);
}
$('<input type="button" id="a_button" value="Add"/><br>')
.appendTo(form);
var list = $('<div>').append(form).html();
$('#a_button').click(
function(){
console.log('message from event handler');
}
);
$.colorbox({ innerWidth:420, innerHeight:315, html: list });
};
})(jQuery);
As you can see, form has a button called Add using which I hope to make an ajax request. But unfortunately click event handler attached to this button doesn't seem to be invoked.
Does anyone have any idea about what's wrong here? myFunction is actually invoked by a drupal ajax command in case if that's helpful.
You are appending the form to the DOM after attaching the event handler.
$('#a_button') searches the DOM at that specific point in time, but the form is not added to the DOM until after your call to colorbox with list as a parameter.
Try a permanent delegated event handler instead (or simply add the click handler after the colorbox line).
e.g.
$(document).on("click", "#a_button", function(){
console.log('message from event handler');
});
or
$.colorbox({ innerWidth:420, innerHeight:315, html: list });
$('#a_button').click(
function(){
console.log('message from event handler');
}
);

jQuery not working on a jQuery generated HTML tag

I generated multiple li in a string to have a dynamic display of a user list (connected or not).
At the end of the list, I added a li that's the button to disconnect.
Problem is, if I add it in my original code by default, without generating it, the Ajax function works fine.
If I generate it, it doesn't even apply the preventDefault().
Why is that, and how to fix this issue ?
function displayUsers() {
$.ajax({
url: 'getUsers.php',
dataType: 'json'
}).done(function (aUsers) {
if (aUsers != null) {
var sUserList = '';
$.each(aUsers, function (key, oUser) {
sUserList += '<li><span class="glyphicon glyphicon-ok" style="color: springgreen;"></span>' + oUser.nickname + '</li>';
});
sUserList += '<li class="divider"></li>';
sUserList += '<li class="disconnect"><span class="glyphicon glyphicon-off"></span>Sign Out</li>';
$('ul.dropdown-menu').html(sUserList);
} else {
var sNoConnectionMessage = '<li><span class="glyphicon glyphicon-remove-sign" style="color: crimson;"></span>Aucune connexion en cours.</li>';
sNoConnectionMessage += '<li class="divider"></li>';
sNoConnectionMessage += '<li class="disconnect"><span class="glyphicon glyphicon-off"></span>Sign Out</li>';
$('ul.dropdown-menu').html(sNoConnectionMessage);
}
});
}
setInterval(displayUsers, 1000);
$('li.disconnect a').on('click', function (event) {
event.preventDefault();
$.ajax({
url: 'logoff.php'
}).done(function () {
$('div.LoginChat').removeClass('hide');
$('div.WriteMessage').addClass('hide');
})
});
Please guide me the correct way to achieve my objective.
Event handlers are attached to elements, not to selectors.
When you do this:
$('li.disconnect a').on('click', function (event) {
jQuery will identify matching elements for 'li.disconnect a' once, and only once, at the time this line of code executes. Any matching elements added to the DOM afterward will not have been identified. In order to do that, you need to attach the click handler to a common parent element (which doesn't change during the life of the DOM) and use the overload of .on() which filters events from child elements. Something like this:
$(document).on('click', 'li.disconnect a', function (event) {
This will attach the handler to the document element (though any common parent element will work) instead of the identified elements. As events "bubble up" through the DOM they will eventually reach that parent element. The second selector in the .on() function then filters those child elements to respond only to click events which originated from an identified element.
I've written more on the subject here.
Use Event Delegation and delegate the click handler to something that doesn't get regenerated, such as the document:
$(document).on('click', 'li.disconnect a' function (event) {
...
});
The issue is if you don't delegate to something higher, the event handler is lost when you destroy the element.

mouseover function of jquery not working on dynamically created div

I am trying to add a mouseover function to dynamically created elements using jquery
$('#schools').append(
'<div class="mediumListIconTextItem" onclick="javascript:showSchoolReport(\'' + $.trim(this.id) + '\',\'' + $.trim(this.companyID) + '\',\'' + $.trim(this.companyCode) + '\',\'' + $.trim(this.companyName) + '\');" style="padding-left: 30px;margin: 5px;">' + '<div class="icon-newspaper mediumListIconTextItem-Image"></div>' + '<div class="mediumListIconTextItem-Detail">' + '<h6 id="header" style="max-width:100px; overflow:hidden;">' + this.name + ' - ' + this.companyName + '</h6></div></div>');
code for mouseover effect
$(document).ready(function (e) {
$(".mediumListIconTextItem").mouseover(function () {
alert($(this.name));
});
});
$(".mediumListIconTextItem").on("mouseover", function () {
alert('mouseover works!!!!!!!!!');
});
});
none of the above function for mouseover works. whats wrong with my code. suggest a solution
This is the case called event delegation. In here you can't bind the direct event to a dynamically created elem. try this as below:
$(document).on("mouseover", ".mediumListIconTextItem", function() {
alert('mouseover works!!!!!!!!!');
});
You're almost there, you have to use on but in a different form. You're using direct event but you need to use delegated events
$('#schools').on("mouseover", ".mediumListIconTextItem", function() { .. }
For more details check section Direct and delegated events
Use on() for dynamically added elements like,
$(document).on("mouseover", ".mediumListIconTextItem", function() {
alert('mouseover works!!!!!!!!!');
});
Use .on()
As elements are added dynamically you can not bind events directly to them .So you have to use Event Delegation.
$(document).on("mouseover", ".mediumListIconTextItem", function() { .code here. }
better use
$("#schools").on("mouseover", ".mediumListIconTextItem", function() { .code here. }
Syntax
$( elements ).on( events, selector, data, handler );
Use event delegation :
$('#schools').on('mouseover', '.mediumListIconTextItem', function(){ ... })
For a clear and short explanation of how event delegation works, see this question :
Direct vs. Delegated - jQuery .on()

Categories

Resources