I have the contents of a php file loaded via Ajax that contains HTML and JavaScript. I have a button:
<button class="search_button">Search</button>
And I have a script underneath that will update the documents hash from a jQuery function
<script type="text/javascript">
$(".search_button").click(function() {
var searchTerm = $('#search_box').val();
document.location.hash="searchTerm";
return false;
});
</script>
This code works when I run the php file separately, but when loading this page from an Ajax call, the function no longer runs. In firebug the script is not present so I am assuming I cannot load a script in using this method. I tried also putting the JavaScript snippet instead a header for the whole website, but this failed also.
I was also thinking perhaps the function has to be declared when there is a search_button class already present, but it was structured in this way when I previously had them in one file (that was retrieved via Ajax) to no avail so I'm confused as to the problem.
You can include it globally with a live event:
$(".search_button").live('click', function() {
var searchTerm = $('#search_box').val();
document.location.hash="searchTerm";
return false;
});
jQuery will automatically evaluate script blocks, you cannot see the function in the HTML because it has been stripped out. However it should have already run. The problem is most likely timing. You could do something like
setTimeout(function(){
$(".search_button").click(function() {
var searchTerm = $('#search_box').val();
document.location.hash="searchTerm";
return false;
});
}, 500);
So that when the script is loaded it waits to be executed (hopefully giving jquery time to update the DOM with the new element).
As of jQuery 1.7, the .live() method is deprecated. Use .on() to attach event handlers. Users of older versions of jQuery should use .delegate() in preference to .live().
This method provides a means to attach delegated event handlers to the document element of a page, which simplifies the use of event handlers when content is dynamically added to a page. See the discussion of direct versus delegated events in the .on() method for more information.
Rewriting the .live() method in terms of its successors is straightforward; these are templates for equivalent calls for all three event attachment methods:
$(selector).live(events, data, handler); // jQuery 1.3+
$(document).delegate(selector, events, data, handler); // jQuery 1.4.3+
$(document).on(events, selector, data, handler); // jQuery 1.7+
Example usage of .on() to bind click event
$(document).on("click", "#post a", function(){
alert("1");
})
Try to add the script inside a function
function name(){
$(".search_button").click(function() {
var searchTerm = $('#search_box').val();
document.location.hash="searchTerm";
return false;
});
}
and call this function just after the end of the ajax call.
$(document).ready(function() {
name();
});
Related
This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 8 years ago.
Suppose I have some jQuery code that attaches an event handler to all elements with class .myclass.
For example:
$(function(){
$(".myclass").click( function() {
// do something
});
});
And my HTML might be as follows:
<a class="myclass" href="#">test1</a>
<a class="myclass" href="#">test2</a>
<a class="myclass" href="#">test3</a>
That works with no problem.
However, consider if the .myclass elements were written to the page at some future time.
For example:
<a id="anchor1" href="#">create link dynamically</a>
<script type="text/javascript">
$(function(){
$("#anchor1").click( function() {
$("#anchor1").append('<a class="myclass" href="#">test4</a>');
});
});
</script>
In this case, the test4 link is created when a user clicks on a#anchor1.
The test4 link does not have the click() handler associated with it, even though it has class="myclass".
Basically, I would like to write the click() handler once and have it apply to both content present at page load, and content brought in later via AJAX / DHTML. Any idea how I can fix this?
I am adding a new answer to reflect changes in later jQuery releases. The .live() method is deprecated as of jQuery 1.7.
From http://api.jquery.com/live/
As of jQuery 1.7, the .live() method is deprecated. Use .on() to attach event handlers. Users of older versions of jQuery should use .delegate() in preference to .live().
For jQuery 1.7+ you can attach an event handler to a parent element using .on(), and pass the a selector combined with 'myclass' as an argument.
See http://api.jquery.com/on/
So instead of...
$(".myclass").click( function() {
// do something
});
You can write...
$('body').on('click', 'a.myclass', function() {
// do something
});
This will work for all a tags with 'myclass' in the body, whether already present or dynamically added later.
The body tag is used here as the example had no closer static surrounding tag, but any parent tag that exists when the .on method call occurs will work. For instance a ul tag for a list which will have dynamic elements added would look like this:
$('ul').on('click', 'li', function() {
alert( $(this).text() );
});
As long as the ul tag exists this will work (no li elements need exist yet).
Sometimes doing this (the top-voted answer) is not always enough:
$('body').on('click', 'a.myclass', function() {
// do something
});
This can be an issue because of the order event handlers are fired. If you find yourself doing this, but it is causing issues because of the order in which it is handled.. You can always wrap that into a function, that when called "refreshes" the listener.
For example:
function RefreshSomeEventListener() {
// Remove handler from existing elements
$("#wrapper .specific-selector").off();
// Re-add event handler for all matching elements
$("#wrapper .specific-selector").on("click", function() {
// Handle event.
}
}
Because it is a function, whenever I set up my listener this way, I typically call it on document ready:
$(document).ready(function() {
// Other ready commands / code
// Call our function to setup initial listening
RefreshSomeEventListener();
});
Then, whenever you add some dynamically added element, call that method again:
function SomeMethodThatAddsElement() {
// Some code / AJAX / whatever.. Adding element dynamically
// Refresh our listener, so the new element is taken into account
RefreshSomeEventListener();
}
Hopefully this helps!
Regards,
After jQuery 1.7 the preferred methods are .on() and .off()
Sean's answer shows an example.
Now Deprecated:
Use the jQuery functions .live() and .die(). Available in
jQuery 1.3.x
From the docs:
To display each paragraph's text in an
alert box whenever it is clicked:
$("p").live("click", function(){
alert( $(this).text() );
});
Also, the livequery plugin does this and has support for more events.
If you're adding a pile of anchors to the DOM, look into event delegation instead.
Here's a simple example:
$('#somecontainer').click(function(e) {
var $target = $(e.target);
if ($target.hasClass("myclass")) {
// do something
}
});
You can bind a single click event to a page for all elements, no matter if they are already on that page or if they will arrive at some future time, like that:
$(document).bind('click', function (e) {
var target = $(e.target);
if (target.is('.myclass')) {
e.preventDefault(); // if you want to cancel the event flow
// do something
} else if (target.is('.myotherclass')) {
e.preventDefault();
// do something else
}
});
Been using it for a while. Works like a charm.
In jQuery 1.7 and later, it is recommended to use .on() in place of bind or any other event delegation method, but .bind() still works.
Binds a handler to an event (like click) for all current - and future - matched element. Can also bind custom events.
link text
$(function(){
$(".myclass").live("click", function() {
// do something
});
});
If your on jQuery 1.3+ then use .live()
Binds a handler to an event (like
click) for all current - and future -
matched element. Can also bind custom
events.
You want to use the live() function. See the docs.
For example:
$("#anchor1").live("click", function() {
$("#anchor1").append('<a class="myclass" href="#">test4</a>');
});
This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 7 years ago.
I've got a few functions in JQuery that stop working after I perform an Ajax request (to a PHP file) to add elements to the DOM.
This is the ajax function:
function paginacion(pagina){
$.ajax({
method: "GET",
url: "paginacion.php",
data: {pag: pagina}
})
.done(function(msg) {
$(".bt_container").remove();
$(".contenido").append(msg);
});
}
Here I call it:
$(".button").on("click", function(){
var pag = parseInt($(this).attr("data-pag"));
pag++;
paginacion(pag);
});
When I click the button, it works correctly the first time. But the elements I retrieve, should work with another function, and they don't, while the previous elements do work without any problem. Also, the old button gets removed and another one gets added at the end of the file, being retrieved by the same function as above. That button doesn't work either.
I'm sure that I'm having some problem with JQuery, making it to not work with these new DOM element's I'm retrieving. What can I do to make it work?
Use event delegation:
Event delegation allows us to attach a single event listener, to a parent element, that will fire for all descendants matching a selector, whether those descendants exist now or are added in the future.
$(document).on('click', '.button', function () {
var pag = parseInt($(this).data("pag"));
// ^^^^
pag++;
paginacion(pag);
});
Also, use data() to get data attribute value.
http://api.jquery.com/data/
Refer: http://learn.jquery.com/events/event-delegation/
It is loaded dynamically! Use .on for Event Delegation.
$("body").on('click', '.button', function () {
var pag = parseInt($(this).attr("data-pag"));
pag++;
paginacion(pag);
});
You need to use .on() for bindig events for dynamically generated elements
$(document).on('click', '.button', function () {
var pag = parseInt($(this).attr("data-pag"));
pag++;
paginacion(pag);
});
You are looking for Event delegation. You dynamically added and replace the dom elements use event delegation.
$(".contenido").on("click", ".button", function(){
//------^ Immediate parent or document
// Your code
});
Am currently using a Jquery load function to load php content into Div. But when I use my php e-mail form it turns all white an the index page is lost(the main layout I mean). Is there anyway I can use Jquery to load Insch.php back into the div even when it needs to be executed?
<form id="contactform" method="POST" action="insch.php"> <--- this is my Form
$('.menut').click(function () {
var phpFile = $(this).attr('id') + '.php';
/* alert(phpFile)*/
$.get(phpFile, function (data) {
$('#box1').html(data);
});
return false;
}); <---- my Jquery load function(on index)
I see you add returning data directly into $("#box1"). If your php file returns Html you should set dataType:'html' in the ajax request.
Sorry, your question is kinda hard to understand. I'm kinda guessing, but it sounds like you're asking how to submit the form without the page refreshing. If so, you could do something like this:
$('.menut').click(function() {
var phpFile = $(this).attr('id') +'.php';
$('#box1').load(phpFile, function() { // <-- this is your ready function
// once the form has been added to the page,
// add the 'submit' event listener
$('#contactForm').submit(function(e) {
// prevent the form from submitting regularly (causing a page refresh)
e.preventDefault();
// get the data from the form
var data = $(this).serialize();
// submit the form via AJAX and put the response in #box1
$('#box1').load($(this).attr('action'), data);
});
});
});
UPDATE:
Your ready function is the function you create in your AJAX call to be executed when the content is done loading (when the content is ready). It may also be called a callback function, complete function, or a success function.
Take a look at the comment I added on the fourth line of code above. I have pointed out what I'm referring to as your ready function.
In your question, you used this:
$.get(phpFile, function (data) {
$('#box1').html(data);
});
Which is equivalent to:
$('#box1').load(phpFile);
This loads the response (your form) from phpFile into #box1. The function (data) { ... } is your ready function. That is where you should bind the submit event to the form.
If you switch to the load() method as I am suggesting, then you would just pass a new function (which will be your ready function) as the second parameter to the load() method, which is the solution I've given in my original answer.
I'm trying to add a link to delete a row from a mysql database using jquery and ajax. The data is currently displayed in a table. For some reason, the Click event isn't triggering.
Here's my AJAX call:
<script>
$(document).ready(function() {
/* load table with page load*/
$("#sort tbody").load("inc/index_table.php");
/* row deletion */
$(".deletelink").click(function(){
var id = $(this).attr("id");
$.ajax({
beforeSend: function (request) {
var answer = confirm("Are you SURE you want to delete this?/nThis action is NOT reversible.")
if (answer){ return(true); }
else { return(false); }
},
type: "POST",
url: location.href,
data: "delete="+id,
error: function() {
console.log("Theres an error with AJAX deletion");
},
success: function(){ //a.td.tr.remove just that row rather than the whole table
$this.parent().parent().remove();
console.log("Deleted.");
}
});
});
});
</script>
And the relevant HTML:
this is part of a while loop that prints a table from my database:
<td><a class="deletelink" id="'.$row["id"].'"><img src="images/delete.png" alt="Delete"></a></td>';
My code specifies <a class="deletelink"> but it's not registering with $(".deletelink").click(function(){ });
Does anyone see what could be wrong here or have an alternate method to suggest?
Looks like you are loading the elements dynamically. You can only bind to elements which currently exist in the DOM. To bind to elements which you are about to add, you must attach the event to a static element, the closer it is to the dynamic content, the better.
Try using on() with a delegate.
$("#sort tbody").load("inc/index_table.php");
/* row deletion */
$("#sort tbody").on("click", ".deletelink", function(){
//...rest of code the same
});
on() was added in jQuery 1.7. If you are using a previous version, but higher than 1.4.2 you can use delegate() instead.
$("#sort tbody").load("inc/index_table.php");
$("#sort tbody").delegate(".deletelink", "click", function(){
//...rest of code the same
});
If #sort or tbody of $("#sort tbody") is also dynamic then $("document").on("click", "#sort tbody .deletelink", function(){...}) would work as well, though anything closer than document is better off course.
Edit
I'm just looking at your code again, the delegate binding should work, however, using load()'s success callback should work with your existing code too.
The callback is executed ones load has successfully completed. I'm not 100% certain but I'm assuming that when success is called that the elements already have been loaded into the DOM and as such the normal bindings should work.
If that doesn't work the dynamic bindings mentioned above should.
$("#sort tbody").load("inc/index_table.php", function(){
/* row deletion */
$(".deletelink").click(function(){
// .. your code as before.
});
});
to make sure the table is fully loaded, try to declare the click function, in the callback of .load() like,
$("#sort tbody").load("inc/index_table.php", function() {
/* row deletion */
$(".deletelink").click(function(){ ....
});
});
Try using .on() to bind the events to the elements
$(".deletelink").on('click',function(e){
e.preventDefault();
Also make sure to add preventDefault to stop the default functioning of the link
The problem is that your delete link appears after the table loads. So when page was loaded and DOM tree was built, it wasn't there. So you can't attach a click to it.
You can try live(). This can be used as
$(".deletelink").live('click',function(){
// ajax call handling code here
});
This function attaches event after the element has been introduced in the DOM. However, this function is a bit greedy as it keeps on scanning entire DOM tree on any DOM change. So use with caution
I made a jquery code like :
$('button').click(function(event) {
});
In it; I put $.post and sent data to a php file and return table rows. In every rows, there is an 'add' button.
Then I made another jquery code for these buttons like :
$('.row_button').click(function(event) {
});
Again, I put $.post and tried to send data about that row and wanted to fetch information via ajax request. But it didn't work. Nothing happend. I looked code and there is no error.
Isn't it possible to use ajax within another ajax? Or is there another way? Thank you.
That is because those newly injected elements don't know about the click event binding you already have.
Solution : use jquery on function.
Change
$('.row_button').click(function(event) {
});
to
$(document).on("click",".row_button'",function(event) {
});
jQuery on works for current and future elements (newly injected elements via ajax/dynamically adding new elements using javascript) . It is available from jQuery 1.7+ version. If you are using an earlier version of jQuery, consider using jquery live
(As of jQuery 1.7, the .live() method is deprecated)
Try to use this instead second code:
$('.row_button').live('click',function(event) {
...
});
Jquery .live attach an event handler for all elements which match the current selector, now and in the future.
Edit
.live is now deprected so use .on insted:
$(document).on("click",".row_button'",function(event) {
});
From Jquery documentation:
$(selector).live(events, data, handler); // jQuery 1.3+
$(document).delegate(selector, events, data, handler); // jQuery 1.4.3+
$(document).on(events, selector, data, handler); // jQuery 1.7+