Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
jne
12,613 Pointsjquery selection after a search result
Hi! I made a little program that searches my database for books and displays it to the page. The search result is great but I have a click event bound to the class of each book-element that is displayed using jquery. At default all books are displayed and the click event works great on the books that are displayed. But when i make a search and I try to click a book that i searched, nothing happens. The html is excactly like the books that are displayed at default and contains of course the class book that the jquery targets.
My search is made using a ajax request and a php program returns the html.(Same for both default books and the searched books).
Anyone experienced the same and have a answer? Thanks
So to be clear the problem is that I can't click any book that the php program returns from a search.
jquery to select the book element and displays a settings box
var $settings = $(".books");
/*var $settings = $("search-results").find(".books");*/
$settings.click(function()
{
var $id = $(this).children().last().data("id");
//Make ajax request here with use of id!!
var $insert = "Data to be displayed but is not necessary to be displayed(Plain html to be displayed after click event). ";
$($insert).insertAfter( $(this) );
$(this).next().children().last().attr("value", $id);
/*$(this).next().click(function()
{
$(this).remove();
});*/
});
ajax request. Works but I can't use click events on the elements returned from php script below
$("#search").keyup( function()
{
var $search = $(this).val();
if($search == ""){
if(window.XMLHttpRequest)
{
xmlhttp1 = new XMLHttpRequest();
}
else
{
xmlhttp1 = new AtiveXObject("Microsoft.XMLHTTP");
}
xmlhttp1.onreadystatechange = function()
{
if(xmlhttp1.readyState == 4 && xmlhttp1.status == 200){
document.getElementById("search-results").innerHTML = xmlhttp1.responseText;
}
}
xmlhttp1.open("GET","./inc/get_content.php?v=all",true);
xmlhttp1.send();
}
else
{
if(window.XMLHttpRequest)
{
xmlhttp = new XMLHttpRequest();
}
else
{
xmlhttp = new AtiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function()
{
if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
document.getElementById("search-results").innerHTML = xmlhttp.responseText;
}
}
xmlhttp.open("GET","./inc/get_content.php?q="+$search,true);
xmlhttp.send();
}
});
php code to return searched elements. The html is equal to the default view all books only sql that are different
function get_search_result($data)
{
require_once('connect.php');
$query = "SELECT * FROM book WHERE tittel LIKE " . "'%" . $data . "%'";
$result = mysql_query($query);
if(!$result) die("Kunne ikke lese database..: " . mysql_error());
$rows = mysql_num_rows($result);
while($row = mysql_fetch_row($result))
{
echo '<ul class="books" id="book">';
echo "<li><h4>" . $row[1] . "</h4>" . " (". $row[5] . ")" . "</li>";
echo "<li>" . $row[2] . "</li>";
echo "<li>" . $row[3] . "</li>";
echo "<br/>";
echo "<li>" . $row[4] . "</li>";
echo "<li data-id='". $row[0] . "' class='hidden'>" . "</li>";
echo "</ul>";
}
}
To compare this is the php code that for the default view of books
function get_all_books_info(){
require_once('connect.php');
$query = "SELECT * FROM book";
$result = mysql_query($query);
if(!$result) die("Kunne ikke lese database..: " . mysql_error());
$rows = mysql_num_rows($result);
while($row = mysql_fetch_row($result)){
echo '<ul class="books" id="book">';
echo "<li><h4>" . $row[1] . "</h4>" . " (". $row[5] . ")" . "</li>";
echo "<li>" . $row[2] . "</li>";
echo "<li>" . $row[3] . "</li>";
echo "<br/>";
echo "<li>" . $row[4] . "</li>";
echo "<li data-id='". $row[0] . "' class='hidden'>" . "</li>";
echo "</ul>";
}
As said the search and displaying of data works great, but I can't use any click event on the retuned data from search result
The returned html is displayed in here
<div id="search-results">
<?php
echo get_all_books_info();
?>
</div>
Robert Richey
Courses Plus Student 16,352 PointsIt's pretty hard to speculate without seeing any code.
jne
12,613 PointsAdded code!
2 Answers
Robert Richey
Courses Plus Student 16,352 PointsOne more shot in the dark is to try jQuery's .on() event handler.
// change this line
$settings.click(function()
// to this
$("body").on("click", ".books", function()
As far as the reason goes, it has to do with event delegation - a topic I don't fully understand, but can be read in more detail from the jQuery API. Here is a relevant snippet from the same link above regarding the .on() event handler
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. This element could be the container element of a view in a Model-View-Controller design, for example, or document if the event handler wants to monitor all bubbling events in the document. The document element is available in the head of the document before loading any other HTML, so it is safe to attach events there without waiting for the document to be ready.
Glad it worked for you!
Robert Richey
Courses Plus Student 16,352 PointsHi Joakim,
Thanks for posting the code. While this helps, there is a lot of code here and the posted code is not benefiting from syntax highlighting. Please consider using markdown with an appropriate language specified.
I believe the problem may be because you're caching the DOM here
var $settings = $(".books");
At this point, the DOM has loaded and you're saving the elements matched with the class 'books' into $settings, well before any click events. After the database retrieves new books, the DOM gets modified, but the new nodes are not part of what has been saved in $settings.
The way around this is to perform a fresh selector query on each click, rather than using a cached value from a variable.
// change this line
$settings.click(function()
// to this
$(".books").click(function()
I'm interested in knowing if this works for you.
jne
12,613 PointsI believe that is the problem to, but I have no idea how to solve it. I changed the click function but that didn't work.
Robert Richey
Courses Plus Student 16,352 PointsOne more shot in the dark is to try jQuery's .on() event handler.
// change this line
$settings.click(function()
// to this
$("body").on("click", ".books", function()
jne
12,613 PointsThank you thank you thank you!!! Spent hours on this!! Works perfectly and it was so simple...yet hard though
Post it as an answer and I'll give you a best answer!
Do you know the reason why that works and not .click?
mikes02
Courses Plus Student 16,968 Pointsmikes02
Courses Plus Student 16,968 PointsCan you post your code?