jQuery does not recognize PHP generated child element when clicked - javascript

I am working on a website on which I have to display buttons based on database content. Clicking these buttons should then send a request to the database and reload the content of the page appropriately.
Everything is done with Ajax and jQuery by executing PHP scripts.
I can generate the buttons, but jQuery does not trigger when they are clicked.
It seems that jQuery detects a click on the div containing the buttons but not on the buttons themselves.
I was told that it may be because the jQuery script is loaded before the page is updated with the new HTML content.
This is the div container for all the choice buttons:
<div id = "choices">
<!-- Choices button will be displayed here -->
</div>
Here's the PHP code creating the HTML for the buttons:
echo " <button class = 'choice' id = \"$id\">
$content
</button> ";
This code is loaded in the previous #choices div by this jQuery code :
$.post("php_script/getChoices.php",
function(result){
$("#choices").html(result);
});
Pretty basic, and the expected (and actual) output on the webpage is :
<div id = "choices">
<button class = 'choice' id = "1">
Yes.
</button>
<button class = 'choice' id = "2">
No.
</button>
</div>
But when I write this :
$(".choice").click(function());
It never triggers, no matter how basic the function.
However, having another event to interact with the buttons is possible.
For example, the code below does hide the buttons when the #choices div is clicked.
$("#choices").click(function(){
$(".choice").hide();
});
In order to understand the problem, I wrote this jQuery script that print the content of the element that was clicked on the console.
$("*").on('click', function(event){
event.stopPropagation();
console.log('Clicked: ' + $(this).html());
});
And when I click on a button, it always returns the whole #choices div instead of just the content of the button.
As I said, I think this is because I am trying to interact with HTML elements that were added after the jQuery script was loaded (it is written in the section of my page).
Is my assumption correct and what should I do in order to trigger an action when the button themselves are clicked ?

You can always target the document to trigger dynamically created elements:
$(document).on('click', '.choice', function (e) {
e.preventDefault(); //stop default behaviour
var id = this.id; //get element ID
$(this).hide(); //hide element
});

As mentioned you can use event delegation
$(function(){
$("#choices").on("click", "button", function(){
alert("clicked");
});
});
Or manually bind the event handler when you add the new buttons
// called each time new buttons are added
function bindOnClick(){
$("#choices").off();
$("#choices").on("click", "button", function(){
alert("clicked");
});
}
$(function(){
// called once when dom is ready
bindOnClick();
});
If you don't call off you will bind the onclick event to the same element more than once.

Related

Add click event to dynamically added button to kendo window content

I have kendo window and im adding content dynamically to kendo window.
The content has a button and i wanted to attach click event to that button.
jQuery is able to find the button from the content, attach click event however click event never gets fired
JSFiddle
Html
<div id="example">
<div id="window">
</div>
</div>
JQuery
$(document).ready(function() {
// in reality this contnet will be returned from ajax call
var dynamicContent ="<div><button id='btn' type='button'>Click Me</button></div>"
var myWindow = $("#window")
var button = $(dynamicContent).find("#btn");
// show number of buttons found.
alert("found " + button.length + " button")
// attach click event to button
button.click(function(){
alert("this is test");
})
myWindow.kendoWindow({
width: "600px",
height:"200px",
title: "My Window"
}).data("kendoWindow").center().open().content(dynamicContent);
});
You need to change:
button.click(function(){
alert("this is test");
})
to
$('#window').on('click', 'button', function(){
alert("this is test");
})
As you mentioned the element is dynamically created, so it is not part of the browsers dom structure, and therefore can't be selected with jQuery. Using the above code, jQuery listens for any changes to the dom structure inside the #window element, so you can then select any dynamically created elements.

Which Click event handler is to use when changing the content dynamically in jQuery?

I have a small application in jQuery, which takes the href value of an anchor element and inserts that as a div's Id. The div is a basic popup window which is only visible if it's triggered.
The popup window on gets triggered if a anchor tag gets clicked with the same href value as the id of the popup div.
HTML Code:
Item 1
Item 2
Item 3
<div class="popup"></div>
jQuery Code:
var items = ["#item1", "#item2", "#item3"];
$.each(items, function()
{
$(document).on("click", this, function(e)
{
e.preventDefault();
var href = $(this).attr("href");
var length = href.length;
var anchor = href.substring(1, length);
var popup = $(".popup").attr("id", anchor);
});
});
Problem:
The popup window should be triggered once the client clicks on any of the anchors above. However it only gets triggered, on the second click. I guess the first one sets the Id and the second opens is, with the set value.
I have also tried to use another type of click event and it worked for the first click. The event, which have been working was:
$(this).on("click", function(e)
{
// Stuff goes here as above
});
My problem is that I cannot use this type of event handler, because I will be changing the content of the anchor href's dynamically with jQuery.
Question:
How is it possilbe to make the original code working as I expect, so the client should only click once to the anchor tag to get the popup window? Anything else I should consider as well?
$('#item1').on("click", function(e)
{
// Stuff goes here as above
});
$('#item2').on("click", function(e)
{
// Stuff goes here as above
});

Button click event based on class isn't being fired on button that is dynamically created.

I have a table with dynamically created rows. Each row has a link button that you click on to delete that row. This is the click function here:
$(".deleteButton").on('click', function(){
console.log("Delete Hit");
var successful = deleteEntry($(this).attr('id'));
if(successful == true){
$(this).parent().parent().remove();
}else{
alert("Delete Unsuccessful.");
}
});
Some of the buttons are created with one function when the page first loads. Those work, but this other function seems to create a button with the right classes for the event to fire. It creates a link like this.
<a class="deleteButton dButton" href="#">
while the one that works right creates a link like this,
<a href='#' class='deleteButton'>
I have checked in the inspector and it says that the button has the class deleteButton, which is required to fire the event, but it seems to be ignoring it entirely. The Delete Hit never shows in the console.This has really confused me for some time, and I'd appreciate the help anyone can give.
You need to use delegated events for elements that doesn't exist on DOM when you bind event handler
$(document).on('click', '.deleteButton', function(){...}
Where document can be any .deleteButton container that exists at handler bind time.
You can delegate your events.
$(document).on('click', '.deleteButton', function(e){
//do something
});
here is a similar post where I explain the differences between bind live and "on".
How Jquery/Javascript behave on dynamic content updation?
The existing buttons get their event handlers on page load, but the new button is added to the DOM afterwards. You would have to update your JavaScript code, like this:
$(document).on('click', '.deleteButton', function(){
console.log("Delete Hit");
var successful = deleteEntry($(this).attr('id'));
if(successful == true){
$(this).parent().parent().remove();
}else{
alert("Delete Unsuccessful.");
}
});
Find more info in the jQuery docs at http://api.jquery.com/on/#direct-and-delegated-events.

Jquery appending with styling and functions

i appending buttons with some IDs and i use those IDs to make on click stuff
when it appending didn't take button() effect
and on click it don't take the function that I created it for this button id
$("button#edit-doc").each(function() {
$(this).button();
$(this).on("click", function(){
alert("clicked");
});
});
append button
$("#append").on("click", function(){
$('div#container').append("<button id='edit-doc'> Edit </button>");
});
container
<div id="container"></div>
This seems to be what you're after:
function handler() { alert('clicked'); }
$("#append").on("click", appendButton);
function appendButton(){
$('#container').append(function() {
return $("<button id='edit-doc'> Edit </button>").on("click", handler);
})
}
http://jsfiddle.net/PF8xY/
See jQuery how to bind onclick event to dynamically added HTML element for more information on this behavior.
$(document).on("click", "#selector", function(){
//Your code here.
});
Using document for your selector with .on will allow you to bind events to dynamically created elements. This is the only way I've found to do it when the DOM elements don't exist prior to execution.
I do this in a dynamically created table that is sort-able and works great.
EDIT:
Here is an example. Click the button to add a div then click the div to get it's contents.
http://jsfiddle.net/FEzcC/1/
The first code-block attaches an event listner to all buttons with class='edit-doc', use classes instead of an id since an id's name may only exist once per page. So I was saying, when your browser reaches this code an event listner is added to all available buttons in your document at that moment. It doesn't add an event listner to buttons you will be adding later onclick of some element, because it doesn't know. You will have to explicitly execute the code again for the buttons that you append. But what you don't want is to add a new event listner to the original buttons, causing two events being called.
Something like:
// Load all buttons with class=edit-doc and add event listner
$(function() {
$("button.edit-doc").button().on("click", function(){
alert("clicked");
});
});
// Append button if button with id=append is clicked
$("#append").on("click", function(){
var button = $.parseHTML("<button class='edit-doc'>Edit</button>");
$('div#container').append(button);
$(button).button().on("click", function(){
alert("clicked");
});
});
Working example:
http://jsfiddle.net/RC9Vg/

JQuery does not determine the div class which is printed from ajax

I have html elements that printed in html page using smarty engine , then printed from jquery
the html which is printed from smarty is
<div id="broadcastsXXX" class="broadcast orginal-broadcast highlightedbroadcast">
<i class="dogears"></i>
<div class="content">
...
...
</div>
</div>
and the html which is printed from jquery is the same html code which is printed comming from smarty template as shown above.
I want to remove the css class "highlightedbroadcast" when someone clicked on the div which has the class "content" as shown above
so I do the jquery code:
$(document).ready(function() {
$('.content').click(function() {
$(this).parent().removeClass("highlightedbroadcast");
var broadcastid = ($(this).parent().attr("id"));
});
});
The function is changing the clicked div parent and remove the class highlightedbroadcast.
when the user clicked on the .content div that is printed from smarty template when page loas its remove the highlightedbroadcast css class without any problem. but if the user clicked on the div .content which has been printed from ajax it will not remove the class and do nothing.
I try to add alert('hi') to the function and it also says hi when the user clicked on the .content div which is comes from smarty and do noting when the user clicked on the div which is printed from ajax.
note that the broadcastsXXX is dynamic as broadcasts123 broadcasts124 .. etc
and this is a real example http://jsfiddle.net/samshannaq/FUK5Z/2/
so is there any solution for this?
.click() will only add event handlers to the current DOM.
If you want jQuery events to also apply to any HTML that is subsequently loaded via AJAX, you need to use the .on() event handler rather than .click():
$(document).ready(function() {
$('body').on('click', '.content', function() {
$(this).parent().removeClass("highlightedbroadcast");
var broadcastid = ($(this).parent().attr("id"));
});
});
Either that, or you need to add the click events to HTML that is loaded via AJAX after every AJAX call.
I think you should use 'live', while not just 'bind' or 'click' . When document is ready, the div.content is not rendered at all ( they are rendered through ajax response. ). so change your code to
$(document).ready(function() {
$('.content').live('click',function() {
$(this).parent().removeClass("highlightedbroadcast");
var broadcastid = ($(this).parent().attr("id"));
});
});
may work.

Categories

Resources