jquery functions not working properly after .html reload - php

I have a page with a list of items initially loaded from a include_once('show_calendarV2.php'); line.
Next to each item is a delete icon that triggers the following jquery to delete the item from the db and then update the page.
$('.delete_schedule_item').click( function() {
var id = $(this).next('input[type=hidden]').attr('value');
alert ( id );
$.ajax({
url: 'ajax/delete_schedule_item.php',
type: 'post',
data: { id: id },
dataType: 'json', // get back status of request in JSON
success: function(data)
{
//alert( 'item deleted' );
}
// if (data.status) {
// alert('success');
// }
// else {
// alert('error');
// },
//... other parameters/callbacks ...
});
$.get('show_calendarV2.php', {},
function(data)
{
//load the calendar data
$("#calendar").html( data );
});
});
Everything works fine the first time an item is deleted.
The item is deleted.
The new page loads.
But after the page loads the delete buttons? jquery calls? no longer function.
The same page is used to create the initial display as well as the refreshed one so am not sure why the code fails.
Ideas?

Try changing
$('.delete_schedule_item').click(function() {
to
$('.delete_schedule_item').live("click", function() {
If you load a bunch of new html, the function that you ran before wouldn't apply to it anymore. And since you're loading it via Ajax, the function isn't executed again once it's done loading.
The beauty of the live() and die() functions in jquery is that they take care of this situation. Whenever something new is loaded that matches the selector, the new elements are updated automatically.

The reason that it doesn't work any more is that the event handlers are added to the DOM elements themselves. When you load new HTML via AJAX, the old elements with the event handlers attached are removed and new elements, without the handlers are substituted in their place. There are two possible solutions: first, you can reapply the handlers to the newly loaded HTML. Just re-run the code that sets up the event handler on the HTML you've loaded. The other option, which you can use in this case because the click event is handled by live, is to use live event handlers as #womp and #karim79 suggest.
Note that there are some limitations with live handlers - they don't apply to all types of events (click works) and they don't work properly with propagation (i.e., stopping propagation doesn't work). See the jQuery docs for live for more info.

Use event delegation:
$('.delete_schedule_item').live("click", function() {...
Event delegation using live will automatically re-attach event handlers to newly injected elements. When you replace a section of your web page with fresh content via ajax, any event handlers bound to 'old' elements will not automatically get re-attached to the newly injected ones, unless you use event delegation (or re-attach the event handler within your ajax method's callback).
For event delegation with live to work, you will need to be using jQuery 1.3 or greater.

Related

jquery load function for a div not working

I just want to alert 'OK' when a div with id="Box" loads. But load function is not working. Here is my code in wordpress. I have included the jquery library and other jquery is working fine.
jQuery(function(){
jQuery( '#Box' ).load(function() {
alert('ok');
});
});
It does not work with DIV elements:
See: https://api.jquery.com/load-event/
"The load event is sent to an element when it and all sub-elements
have been completely loaded. This event can be sent to any element
associated with a URL: images, scripts, frames, iframes, and the
window object."
Question:
I just want to alert 'OK' when a div with id="Box" loads. But load function is not working.
You are using .load().
Answer A : This method will not work with a div.
Answer B : This method was deprecated in jQuery 1.8. Stop using it!
This method is a shortcut for .on( "load", handler ).
The load event is sent to an element when it and all sub-elements have
been completely loaded. This event can be sent to any element
associated with a URL: images, scripts, frames, iframes, and the
window object.
https://api.jquery.com/load-event/
Possible solution:
Use the shorthand method .ajax(), .load(), .get to load content and trigger your stuff in the callback function or success handler.
.load() Load data from the server and place the returned HTML into the
matched element.
http://api.jquery.com/load/
Example 1
Specify what to load in the first parameter and act in the callback function. The content of test.html is loaded, after that it's inserted into #box and the alert is fired.
$( "#result" ).load( "ajax/test.html", function() {
alert( "Load was performed." );
});
Example 2
Ajax Example with load alert:
$.get("ajax/test.html", function(data) {
$("#box").html(data);
alert("Ok. Load.");
});
You are loading test.html the content is returned as data. It is assigned as new html content to the dom element #box. Then you fire the alert.
Example 3
The alternative is using the .ajax method and define a success handler:
function getData() {
$.ajax({
url : 'test.html',
type: 'GET',
success : alert('Ok.Loaded')
});
}

Updating the dynamic PHP in a jQuery Mobile site after updating the database

Let's say I have 2 pages in a jQuery Mobile website.
Page1 - shows data from a database using inline PHP.
Page2 - inserts new data into the database.
The problem is that page1 is not updated when going back, after page2 adds something to the database. I can get it updated by pressing F5, but how can I achieve the same update using jQuery?
I think you're showing data in Page 1 using the pageinit event. This will fire only once and won't update your data every time you add new data.
You need to use pagebeforeshow event of Page 1 to get data from database. This way, new data will be brought every time, which is what you need. Here's a syntax :
$(document).on("pagebeforeshow", "#page1", function() {
//call to server
});
If you're not using pageinit, you must be using document.ready event to get data. Well, thats the way thats done. You must not use ready with jquery mobile. DOM ready will initialize the whole document which will make the ajax page change feature of jQM pointless & useless.
It was late last night and I missed that I should just get my inline php content using Ajax.
So this is how I solved it:
Moved everything contain dynamic content using PHP in a separate file.
Add an Ajax call to the bottom of the page that loads the PHP file as follows:
$(document).on('pagebeforeshow', function(){
$.ajax({
type: "GET",
url: "includes/db/ajax_show_php_content.php",
success: function(html) {
$("#page1").html(html); //Insert PHP content
$("#page1").trigger('create'); //Apply jQuery Mobile style to it.
});
});
Thanks to #hungerpain and #anglinb for their help in figuring this out.
I'm not extremely familiar with jQuery Moblie but here's what I found:
function refreshPage()
{
jQuery.mobile.changePage(window.location.href, {
allowSamePageTransition: true,
transition: 'none',
reloadPage: true
});
}
I think the reloadPage to true should do the trick.
If that doesn't work, check out this answer: jQuery Mobile Page refresh mechanism
Hope this helps!

event handler for clicking a link to ajax call

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

JQuery onclick issue when calling a function from the parent page

I'm having a problem..
Actually I do have an issue when sending a value from a child page to the parent page.
I'm actually loading a page via JQuery and that page is getting refreshed to display new results, but one of these problems is that the function from the parent page doesn't get called from the child page.
Although this works perfect on Google Chrome, Opera and Safari, it doesn't seem to work on Firefox.
I heard Firefox doesn't manage events the same way as Safari or Google Chrome does?
I've been searching on answers for this but I couldn't find anything pretty much..
Alright, here's what I'm doing:
The child page calls another file which has all the functions that make my site work, this is what should trigger the function:
$like = "<a href='$comment_poster' id='$msgid' class='like'
onclick='parent.likecomment(this);'>Like</a>";
echo "$like";
And this is the function that gets fired from the onclick event which is located in the parent page (the function is in the parent page the onclick is in the child page):
This function is the one that receives the id from the child page to later on add the value to the database.
function likecomment(commentID)
{
event.preventDefault();
var likeid = commentID.id;
var author = ($(commentID).attr('href'));
// forming the queryString
var data = 'likeid='+ likeid + '&author=' + author;
if(likeid)
{
// ajax call
$.ajax({
type: "POST",
url: "likeprofmessage.php",
data: data,
beforeSend: function(html)
{
$(".word").html(likeid);
},
success: function(html){
$("#resultsprofcomments").fadeIn('slow');
$('#profcommentsdiv').load('showprofmessages.php?vprofile=<?php echo $row['1'];?>').fadeIn("slow");
$("#resultsprofcomments").append(html);
}
});
}
}
I've tried the Firefox console and I've received the error: event is undefined so this should be a problem on how Firefox manages events.
Again, any help is appreciated, thank you very much.
I think the following will work as long as you set the onclick handler inline in your HTML (as you did in your example):
<A href="..." onclick='parent.likecomment(event,this);'>blah</A>
<SCRIPT>
function likecomment(evt, commentID) {
evt.preventDefault();
var likeid = commentID.id;
// etc
}
</SCRIPT>
For event handlers not set inline in HTML, the standards compliant browsers (including FF) should automatically pass the event object as a parameter to your handler function. IE, up to version 8, anyway, uses a different event model and lets you reference event directly - really it is window.event but generally as with most window properties it works even if you omit window..
So if you assign your click handler on document ready (or onload) you can do this:
function yourOnloadFunction() {
document.getElementById('yourElementId').onclick = clickHandler;
}
function clickHandler(e) {
// check if event object was passed in, otherwise use window.event
if (!e) e = window.event;
// but how to get a reference to the clicked element?
// use the event object's target property, except (of course)
// in IE, which uses srcElement:
var elRef = e.srcElement ? e.srcElement : e.target;
// rest of your function here, e.g.
e.preventDefault();
}
You have managed to make a mess of your code, but try to change
onclick='parent.likecomment(this);'
to
onclick='parent.likecomment(this);return false;'
and then remove
event.preventDefault();
from your function likecomment(commentID).
Instead of using the in-line onClick, have you tried sending back a script that does something like
<Script>$('#{id}').click(function() {
var id = this.id;
likecomment(id);
return false;
})</Script>

How to initiate javascript in jQuery ajax-loaded content in IE8

I'm facing a trouble with jquery ajax under IE8. I have a form which at the base level displays a list of few items, each with buttons to edit and remove. The list, along with those two buttons, is loaded via jquery ajax call. Although it works fine on Firefox and Chrome, on IE8 it won't trigger functions behind edit or remove buttons.
So basically, on a base page, jquery works and loads the list. Within that list tho, jQuery doesn't work as it won't trigger edit or remove functions
I have a similar problem with the modal window call. IE8 is able to open the modal window (content is loaded with jquery ajax) but won't trigger any function within the content of the modal
Example of a simple call
$('#form-modal').load('/form/' + path + '?id=' + id).modal();
This works on IE8 from the base page, but doesn't when triggered within ajax-loaded content
All js scripts definitions are being loaded in the <head> of the main base page. I tried adding definition to the ajax-loaded file header, but didn't help so it must be something else
Any ideas? If you need more details, will gladly provide
Let me show you the easiest example. Each item on the list loaded with ajax has a 'remove' button.
Remove
DeleteItem definition is in external lib.js file
function deleteItem(id){
$.ajax({
type: "POST",
url: "/ajax/deleteitem.php",
data: "id=" + id,
success: function(msg){
loadItemsList();
}
});
}
This is it... That simply doesn't work on IE8... Nothing happens, not even javascript error. Same thing works no problem on Firefox and Chrome
It would be nice if you show the event handlers for those buttons, since if you're using bind(); for example, it loads when the dom is ready, and your ajax call is made. That means that the dom elements loaded through the ajax call wasn't there when bind was called to bind the buttons.
The solution to this is to use live();
$(".button").live("click", function () {
// do stuff
});
I don't know what event binder you're using, but if you're using anything other than live, you could try live and it should work.
EDIT
Read my comment first on the alert(id), if your function doesn't run at all in IE8, try doing this instead. Give the link element the id instead like this
<a id="item_10" href="#">Remove</a>
Then somewhere in your javascript
$("document").ready( function () {
$("a").live("click", deleteItem);
});
function deleteItem (event) {
event.preventDefault();
var id;
id = $(this).attr("id").replace("item_", "");
//this will now provide you with the current id
console.log(id);
your ajax-stuff here..
}
This should work in IE8, no problem. You might wanna specify the selector though for the click event by giving all the delete links some class or something.

Categories