How to restore JQuery events on removed element? - javascript

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() {......})

Related

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

multiple .on() functions not working

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.

How do I get an event listener to work on an element that is added to my html via javascript?

I'm adding some HTML to my document via javascript. I also add a button to my HTML via this javascript function. I want this button to have an event listener, but this doesn't seem to work on the element added with javascript. Is it possible to fix this?
my js:
$('#content-overview li').on('click',function(){
// Clear previous videos
$('.content-overview-row').remove();
// Insert new video
var vimeoId = $(this).data('vimeo');
var html = '<li class="content-overview-row"><div class="content-overview-video"><iframe src="http://player.vimeo.com/video/'+vimeoId+'" width="950" height="534"></iframe><a id="close-video"></a></div></li>';
// Find end of row and insert detailed view
var nextRow = $(this).nextAll('.first-in-row:first');
if(nextRow.is('li')){
nextRow.before(html);
}
else{
//last row
if($(this).hasClass('first-in-row'))
{
//first item clicked in last row
$(this).before(html);
}
else{
$(this).prevAll('.first-in-row:first').before(html);
}
}
return false;
$('#close-video').click(function() {
console.log("works");
});
});
close-video is the close button I am talking about.
You need to bind the click event to an element which exists in the DOM when the page is loaded, and delegate the dynamically added element, like so:
$(document).on('click', '#close-video', function() {
...
});
You should change document for the element closest to your #close-video so that it doesn't have to bubble right up to the document.
Also, you're returning false; before the #close-video click handler, so that code would never be executed anyway. Move it outside of your #content-overview li click handler.

Can't listen to hover (etc) events after creating divs using innerHTML

So I generate some divs using this
document.getElementById('container').innerHTML += '<div class="colorBox" id="box'+i+'"></div>';
The problem I'm running into is that catching a hover event
$(".colorBox").hover(function(){
alert("!");
});
Won't work after doing that. Any thoughts?
EDIT:
To be more clear, check this out: http://graysonearle.com/test/16_t.html
I need to be able to have hover events happen after changing innerHTML that happen dynamically and many times. So like after changing the number of columns, the hover effect needs to work.
THANKS TO CHOSEN ANSWER:
For those in the future that might want to do something similar, my code looks like this now:
$(document).ready(function(){
document.body.onmousedown = function() {
++mouseDown;
}
document.body.onmouseup = function() {
--mouseDown;
}
$(document).on("mouseenter",".colorBox",function(){
if(mouseDown){
var clicked = $(this).attr("id");
var clicked = clicked.substring('box'.length);
next_color(clicked);
}
$(this).css("border-color","#ff0");
}).on("mouseleave", ".colorBox", function() {
$(this).css("border-color","#aaa");
});
$(document).on("click",".colorBox",function(){
var clicked = $(this).attr("id");
var clicked = clicked.substring('box'.length);
next_color(clicked);
});
});
whenever we update DOM from server side code or client side code.
For EX. DIV we are updating then it will not work with events we loaded before if we load that partial data.
so for this in document ready
code like this.
if you are using jquery 1.7+
then code like
$(document).on("hover",".colorBox",function(){
alert("Hi it will load after partial div update as well");
});
$(document).delegate(".colorBox","hover",function(){
alert("Hi it will load after partial div update as well");
});
and if you are using jquery 1.6 or less then that.
then use
$(".colorBox").live("hover",function(){
alert("Hi it will load after partial div update as well");
});
http://oscarotero.com/jquery/
If this helped you please mark as answer.
First, as you're using jQuery your first code could be simplified using the below function.
$('#container').append('<div class="colorBox" id="box'+i+'"></div>');
Second I think this is because you haven't declared the hover-off function.
$(".colorBox").hover(
function(){
alert("On");
}
);
Working Fiddle
You have to call your hover code AFTER injecting your divs. Jquery doesn't automatically listen to dom changes, so if you hook all your colorBoxes in $(document).ready(){...} and then insert a new div, nothing will ever happen.
So this works fine:
$(document).ready(function(){
for(i=0; i<5; i++) {
document.getElementById('container').innerHTML += '<div class="colorBox" id="box'+i+'"></div>';
}
$(".colorBox").hover(function(){
alert("!");
});
}

How to append the div element in jquery if don't exist

I am adding the form my current list in a div box at the bottom of the table.
I am appending the div box when someone clicks on add button.
But when i click add button multiple times , then many div boxes are appended.
Is there any way that no matter how many times I click the button, only one instance gets append to div box.
This is my code
$var = $(this).parent().parent();
$var.append($('.jq_div')[0].outerHTML);
attach your listener using .one().
$("button").one('click', function(){
// Your code
});
Read more: http://api.jquery.com/one
This is under the assumption that you're using jQuery 1.7+
One simple solution would be having a boolean flag that you can toggle once your button is clicked. Additionally, there is actually a jQuery function that provides this exact functionality.
It's called one() -
Attach a handler to an event for the elements. The handler is executed
at most once per element.
So your code would look something like this -
$("#someTrigger").one('click', function(){
$var = $(this).parent().parent();
$var.append($('.jq_div')[0].outerHTML);
});
The boolean method is also very simple -
var wasClicked = false;
$("#someTrigger").on('click', function(){
if (wasClicked == false){
// append your form
wasClicked = true;
}
});
Reference -
one()

Categories