jQuery .on() event ignores selector - javascript

I have a function to create a div, ID it and add content before binding it to a click event using the .on() method using a selector as the second parameter. Here is the code I am using.
$('#overlayLeft').append(createOption('Item ID'));
function createOption(name){
var element = document.createElement('div');
var noSpaceName = name.replace(" ", "_");
element.id = 'toolOverlay' + noSpaceName;
element.innerHTML = '<input type="checkbox"><label>' + name + '</label>';
$('body').on('click', $('#' + element.id),function(){
alert("Test");
});
return element;
}
However instead of binding the click event to the body using the id of the generated element as the selector, the event acts whenever a click occurs on the body of the page.
How do I get the event to occur only on clicking the element without first creating the element and then binding the event separately?

You do not need jquery object, you need selector.use:
$('body').on('click', '#' + element.id,function(){
alert("Test");
});
also you can bind the click event without delegation using:
$('#' + element.id).click(function(){
alert("Test");
});

You have a strange mix of JQuery and native JS code. Maybe this works for your.
function createOption(){
return $('<div></div>')
.attr('id', 'toolOverlay' + name.replace(" ", "_"))
.append(
$('<input></input>')
.attr('type', 'checkbox'))
.append(
$('<label></label>')
.text(name))
.click(function(){
alert('test');
});
}

Try to put just selector string:
$('body').on('click', '#' + element.id,function()

That's not a selector that you are using, it's a jQuery object.
You can solve it by using just the selector, but instead of binding a lot of delegates to the body element, you can just bind the event on the element. That means that you don't need an id on the element to target it.
$('#overlayLeft').append(createOption('Item ID'));
function createOption(name){
var element = $('<div>');
element.html('<input type="checkbox"><label>' + name + '</label>');
element.click(function(){
alert("Test");
});
return element;
}
Binding global delegates is what the live method did, and it was deprecated because that is not a good way to use delegates.

If you're going to use jQuery, may as well use it everywhere. Note that the .click event is attached to the jQuery object/element as soon as it's created:
$('#overlayLeft').append(createOption('Item ID'));
function createOption(name) {
var noSpaceName = name.replace(" ", "_");
var div = $('<div>', {'id': 'toolOverlay' + noSpaceName})
.append('<label><input type="checkbox">' + name + '</label>')
.click(function () {
alert('test');
});
return div; // returns a jQuery object now, not a DOM element,
// which is fine when using .append() as you do here
}
http://jsfiddle.net/mblase75/bdvk9ssa/

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

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

preventDefault not working on anchor

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.

How can I get to know which anchor tag got clicked?

I am creating my content dynamically, When a anchor tag is clicked navigate() function is called. How can i determine which anchor tag was clicked?
function navigate()
{
//var location=$(this).attr("id");
switch(location)
{
/*case "Configuration": $('#detailTable').empty();
$('#detailTable').append(navigateConfig);
break;*/
default: alert(location+" a tag was clicked");
}
}
$('#detailTable').empty();
$('<div width="100%">')
.attr('id','javainfoSpan')
.html('<div class="titleBlue">Configuration>'+productname+'>Java Properties</div>'+
//some other stuff
'</div>')
.appendTo('#detailTable');
Update:
My question is simple
there will be a number of a elements inside detailTable.
how can I get to know in some js function, which a element was clicked?
I see what you're doing now, you're creating the a elements on the fly. If you call javascript:navigate() then you're using standard javascript, and not jquery (jquery is required to use the $(this) selector).
Instead you should have this:
$("body").on('click', 'a', function() {
var location = $(this).attr('id');
switch(location){ /* ... */ }
});
This will catch the click event in jquery for any a element that you either create on the fly or that's already there when the page loads.
Remember, if you're using id then you need to set the id attr on the a element.
Here is a way to handle this too:
$(document).ready(function() {
var productname = "mytest";
$('#detailTable').empty();
$('<div width="100%">').attr('id', 'javainfoSpan').html('<div class="titleBlue">Configuration>' + productname + '>Java Properties</div>' + '<table id="list1" width="100%"></table>' + '<div id="gridpager"></div>' + '</div>').appendTo('#detailTable');
$(".navigate").click(function() {
var location = $(this).attr("id");
switch (location) {
case "Configuration":
$('#detailTable').empty();
$('#detailTable').append(navigateConfig);
break;
case "mytest":
alert("My test was clicked");
break;
default:
alert(location + " a tag was clicked");
}
});
});
See it live on jsfiddle
Try this:
function navigate($element) {
//var location = $element.attr("id");
switch (location) {
/*case "Configuration": $('#detailTable').empty();
$('#detailTable').append(navigateConfig);
break;*/
default: alert(location+" a tag was clicked");
}
}
$('#detailTable').empty();
$('<div width="100%">')
.attr('id','javainfoSpan')
.html('<div class="titleBlue">Configuration>'+productname+'>Java Properties</div>'+
//some other stuff
'</div>')
.appendTo('#detailTable');
// Pre jQuery 1.7...
$(".titleBlue").delegate("A", "click", function() {
navigate($(this));
}
// jQuery 1.7...
$(".titleBlue A").on("click", function() {
navigate($(this));
}
I changed the handler to use the delegate() method of jQuery (or the on() method for jQ 1.7+). Using this it makes it easier to pass the element which caused the event to your processing function, which it does as the $element variable.
You can then do with this as you need.
you have to iterate through each element of using jquery "each" function. By "this" you can get the click object.

Categories

Resources