multiple .on() functions not working - javascript

So basically I want to after clicking button add div with contacts and after clicking any of contacts alert info. Its just to simulate Loading of contacts from xmpp server and after loading opening new tab for chat.
HTML:<button>append</button>
JQuery:
$("button").on("click", function(){
$("body").append("<div id='kontakty'><ul><li id='test3-imserver-soc'><div class='roster-kontakt offline'><div class='roster-meno'>test3</div><div class='roster-jid'>test3#imserver.soc</div></div></li><li id='test-imserver-soc'><div class='roster-kontakt offline'><div class='roster-meno'>test</div><div class='roster-jid'>test#imserver.soc</div></div></li></ul></div>");
});
so far everything works fine and contacts are appended to body, but when i try to execute:
$("#kontakty").on("click", ".roster-kontakt", function(){
var jid = $(this).find(".roster-jid").text();
var meno = $(this).find(".roster-meno").text();
alert(meno + "\n" + jid);
});
its not working, but if I try to execute 2nd function on contacts I want to append used as body of site (without appending) its working fine. Any idea why this happens?

Change your second event to use body and not the id.
id="kontakty" doesn't exist yet when the event is created and therefore doesn't fire. Attach higher in the DOM to avoid this problem.
$("body").on("click", ".roster-kontakt", function(){
var jid = $(this).find(".roster-jid").text();
var meno = $(this).find(".roster-meno").text();
alert(meno + "\n" + jid);
});
The second problem that you have is that when you click the "button" that the first event is bound to, you'll create the same batch of HTML with duplicate ID's. ID's have to be unique, so you'll need to use classes instead.
$("button").on("click", function(){
$("body").append("<div class='kontakty'><ul><li class='test3-imserver-soc'><div class='roster-kontakt offline'><div class='roster-meno'>test3</div><div class='roster-jid'>test3#imserver.soc</div></div></li><li class='test-imserver-soc'><div class='roster-kontakt offline'><div class='roster-meno'>test</div><div class='roster-jid'>test#imserver.soc</div></div></li></ul></div>");
});
Updated <div id='kontakty'> to <div class='kontakty'>
Updated <li id='test3-imserver-soc'> to <li class='test3-imserver-soc'>
Updated <li id='test-imserver-soc'> to <li class='test-imserver-soc'>
With the delegated event listener bound to the body, that code won't have to change.

Related

How to restore JQuery events on removed element?

With this PHP I add the following HTML. I use PHP because I retrieve information from the database, but it's irrelevant in this question.
<?php
echo "
<div id='user_bio_container'>
<p id='user_bio'>My bio<i id='user_bio_edit' class='fas fa-edit'></i></p>
</div>
";
?>
This is the script I have. When the user clicks the bio paragraph, it stores the inside of the paragraph in a variable, then empties the container and adds a form. If the form is cancelled I want to remove the form and add the previous HTML I had in the paragraph. The problem is that when I try to do so the new paragraph does not respond to events (mouseover, click...).
$('#user_bio_edit').css("display", "none");
$(document).ready(function(){
$("#user_bio").on('mouseover', function(){
$('#user_bio_edit').css("display", "inline");
});
$("#user_bio").on('mouseleave', function(){
$('#user_bio_edit').css("display", "none");
});
$("#user_bio").on('click', function(){
var actualbio = $("#user_bio_container").html();
$('#user_bio_container').empty();
var user_bio_form =
"<form id='change_user_bio'>" +
"<span id='cancel_user_bio'>Cancel</span>"
"</form>";
$("#user_bio_container").append(user_bio_form);
//Button decision control
$("#cancel_user_bio").on('click', function(){
$("#user_bio_container").empty();
$("#user_bio_container").append(actualbio);
$('#user_bio_edit').css("display", "none");
});
});
});
I have tried using hide() and show(), but after two cancelled forms it stops working and I keep adding forms to the HTML that are not shown. I also tried moving the button decision control code outside the click event, but it does not work either.
This is a scope issue. actualbio is not available outside $("#user_bio").on('click', function(){..}
Change this
var actualbio = $("#user_bio_container").html();
to
actualbio = $("#user_bio_container").html();
and use
var actualbio = '';
just below
$(document).ready(function(){
this way the variable actualbio is available in all events handlers inside $(document).ready
Regarding the events not working issue
You need to attach events like this since #user_bio is removed from dom along with all attached events when you cleared the html.
$("#user_bio_container").on('mouseover', "#user_bio", function() {......})

Adding Jquery click handler to dynamically-loaded content

My Rails app loads links to a page dynamically. I want to append an onClick action to those links.
The links are appended to the page properly, but the JS for the page is not being applied to those newly added elements.
I've tried rendering new JS tags to the dynamically-added content. I've also tried including this block of code, which should target any link with .select-link added to the #links div.
$("#links").on("click", ".select-link", function() {
my code here...
})
That code works when the links are not dynamically loaded. However, I cannot seem to apply ANY onClick handler to them when dynamically loaded, even in the console.
What could possibly cause this issue?
For more context, the problem I'm trying to solve is here: AJAX-loaded JS not rendering
You should bind your event to document like this
$(document).on("click", "#links .select-link", function() {
my code here...
});
Try following code:
$(document).on("click", "#links .select-link", function() {
/*my code here...*/
})
or
$("#links .select-link").live("click", function() {
/*my code here...*/
})
The thing is, the code which you have in the question does work for dynamically inserted content.
The following snippet has one <div class="select-link"> which is part of the HTML and inserts two <div class="select-link"> elements via JavaScript.
jQuery is used to add two separate click handlers. The first handler is added prior to any of the dynamic content being added to the DOM. The second handler is added after the second <div class="select-link"> is added, but before the third one is inserted. Both handlers are called for all three <div class="select-link">. This demonstrates that the code you have provided in the question does work for dynamically inserted content. That means something else is going on.
$("#links").on("click", ".select-link"
,logEvent.bind(null,'#links on .select-link','jQuery'));
function logEvent(text,type,e){
var curTarget = (e.currentTarget.id)?e.currentTarget.id:e.currentTarget.nodeName;
var target = (e.target.id)?e.target.id:e.target.nodeName;
console.log(text + ' ::' + type + ' ::curTarget=' + curTarget
+ ' ::target=' + target);
}
function appendLink(id,text) {
document.querySelector('#links').insertAdjacentHTML('beforeend'
,'<div class="select-link" id="' + id + '" style="color:blue;">'
+ text + '</div>');
}
appendLink('sel-pre-ready','Selected Link 2 (added prior to document ready)');
$(document).ready(function(){
$("#links").on("click", ".select-link"
,logEvent.bind(null,'#links on .select-link','jQuery at doc ready'));
appendLink('sel-post-ready','Selected Link 3 (added after document ready)');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Not Link</div>
<div id="links">Links
<div id="not-sel">Not Selected Link</div>
<div class="select-link" id="sel-html" style="color:blue;">Selected Link 1 (HTML)</div>
</div><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
Without more information, spending a lot of time speculating on what might be causing the problem is just wasting time.
One possibility of what is happening is that another event handler is being fired for these events and stopping propagation. One way to (mostly) check for that is to add an event handler to the window on the capture phase (i.e. not using jQuery). You could do so with the following:
//The following will catch the event prior to almost all possible
// interference by other event handlers.
window.addEventListener('click',function(e){
if(!$(e.target).is("#links .select-link")){
return; //Not one of the elements we are interested in
}//else
//e.stopPropagation();
logEvent('on window','Capture',e);
},true);

jQuery: create a div alert you when its is clicked,

I can't put a title to it. It's inception :)...
I have add div, when it is clicked, it creates alert div. When alert div is clicked it alert me.
that is an example.
$("#add").click(function(){
$("#add").after("<div class='alert'>Alert</div>");
});
$(".alert").click(function(){
alert("Here I am");
});
I noticed if I placed a div in the html template as <div class="alert">Alert</div> the alert will work. But if I added the div through the jQuery/JS it will not work.
what is the point of that?
to add more inputs and remove it in case he/she added too much, I noticed it didn't work and I wanted to know why:
this is the actual code:
$(document).ready(function(){
var i = $("#new_field_count").val();
//add new field
$("#addnew_field").click(function(){
i++;
$("#new_field").before("<div class='fivepadding'><input name='part1_" + i + "' type='text' placeholder='<?=lang('addform_p1')?>'> = <input name='part2_" + i + "' type='text' placeholder='<?=lang('addform_p2')?>'> <span class='remove clickable'><?=lang('addform_field_remove')?></span> </div>");
$("#new_field_count").val(i);
});
// remove the field
$(".remove").click(function(){
i--;
$(this).parent('div').remove();
$("#new_field_count").val(i);
});
});
For dynamically created content, use on.
$("#wrapper-div").on("click", ".alert", function(){
alert("Here I am");
};
Additionally, it's worth mentioning that it is adviced to use on instead of clickfor monitoring for example classes.
Rather than adding an event handler to every class element separately, the click event will bubble to the parent. According to the jQuery docs, it is a good idea to attach the handler to the closest relevant parent element (rather than the document).
Your document.ready block is interpreted once the DOM has finished loading. At that point in time, anything not in your DOM cannot have proper event binding. Here you can use delegation to make sure your bindings are going as planned. Since your 'body' will be loaded, you can target your .alert div for clicks as follows:
$("body").on("click", ".alert", function(){
alert("Here I am");
};

.click() function being ignored

I'm generating list items that go in an unordered list. I then want to listen for a click on any of these list items. I'm aware I haven't posted the full code, but I'm hoping it isn't necessary for me to. Are elements that are appended like this completely ignored by my jQuery click function? I've tried just about everything and can't find out why! All I want to see is my "lol" alert! :(
$.each(entries, function(i, v) {
s += '<li';
if (favouriteItem(v.title)) s += ' data-theme="e"';
s += '>' + v.title + '</li>';
});
$("#linksList").append(s);
$("#linksList").listview("refresh");
$("li").click(function() {
alert("lol");
selectedEntry = $(this).data("entryid");
});
Although the items do visually appear the source code stays like this:
<div data-role="content">
<ul data-role="listview" id="linksList" data-divider-theme="b" data-inset="false"></ul>
</div>
Suggesting that there are no li elements there. Yet they do show visually? Someone please save me before I jump into a pool of lava.
Change:
$("li").click(function() {
alert("lol");
selectedEntry = $(this).data("entryid");
});
to
$('#linksList').on('click', 'li',function() {
alert("lol");
selectedEntry = $(this).data("entryid");
});
When you add elements dynamically to the document, you need to use .on()'s delegated event syntax.
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.
Use delegation:
$("#linksList").on('click',"li",function() {
alert("lol");
selectedEntry = $(this).data("entryid");
});

JavaScript disconnect after jQuery replaceWith()

In the application that I'm currently creating, I am doing several AJAX calls to the server and replacing parts of my page with partial views. Everything seems to be working right except for my buttons which are "replaced" using the jQuery replaceWith() function.
In my actual code, I'm replacing a whole <div> not just a button, but the code found here will help illustrated my issue.
When the button is clicked, the JavaScript is called and thusly, that button is then updated. However, try to click on that button again, the same JavaScript will NOT be called or executed. There is some disconnect here that I'm missing. (In my mind, every time that the button with a class of "updateButton" is clicked, the javascript should be executed.) Please help me out.
Thanks
Event delegation.
$(document).on('click','.updateButton',function (e) {
e.preventDefault();
var now = new Date().getTime();
var newButton = "<span class='btn btn-info updateButton'>Update Button " + now + "</span>"
$(this).replaceWith(newButton);
});
Demo: http://jsfiddle.net/D2RLR/896/
Instead of binding the event to the button which will be removed (thus losing the event binding), bind it to an element that doesn't get removed but is an ancestor of that button.
Instead of binding the event handler on the document (as in Kevin B's answer), just re-bind it to the new button you've created to replace the old button with. This is a more efficient method of event handling because the event doesn't need to bubble all the way up the DOM tree to the document before the event fires.
http://jsfiddle.net/D2RLR/900/
var replaceBtn = function(domBtn,e) {
e.preventDefault();
var now = new Date().getTime();
var newButton = $("<span class='btn btn-info updateButton'>Update Button " + now + "</span>");
newButton.on('click',function(event) {
replaceBtn(this,event);
});
$(domBtn).replaceWith(newButton);
}
$('.updateButton').click(function(event) {
replaceBtn(this,event)
});

Categories