So I am using something like this $('#msgs').load("<?php echo $_SERVER['REQUEST_URI']; ?> #msgs"); to reload a div which contains a table that allows for dynamic sorting by the user.
The problem I am facing is, not just the table run by tablesorter, but any other time I reload a div this way, any jquery functions that would normally operate in the div no longer function. Is there any way around this with out pushing the data?
$(function () {
$("#backups")
.tablesorter({
widgets: ['zebra'],
sortList: [
[1, 1],
[2, 1],
],
headers: {
6: {
sorter: false
},
}
})
.tablesorterPager({
container: $("#pager")
});
$('#create').click(function(e) {
$.ajax({
type: "GET",
url: '?process=create',
data: '',
success: function(data) {
$('#backups')
.load("<?php echo $_SERVER['REQUEST_URI']; ?> #backups");
}
});
e.preventDefault();
});
});
For example if I click the event #create, the div #backups reloads under which circumstances the tablesorter code for backups ceases to work.
UPDATE:
I created a fiddle that shows the issue. If you click the button, then the sorting abilities of the table no longer works. I'm a learn by example type person, and I'm not sure what to do with the below answers. Could someone perhaps show me using my fiddle how to fix it?
http://jsfiddle.net/1mfgfd2n/7/show/
The basic concept behind live events in jQuery is simple. Lets say you have HTML,
<div class="container"></div>
Now through AJAX or whatever means you prefer, you load a button inside this div.
$.get("url", function(data) {
$('.container').html('<button class="submit-something">Submit</button>');
});
If you have added the event handler on $(document).ready,
$(document).ready(function() {
$('.submit-something').click(clickHandler);
});
But when the document is ready, there is no button. This applies for any of the 'jQuery stuff' you want to do with the updated content. Unless, you have the element you are accessing via selector exists, jQuery can't do anything.
A possible generic solution (for events, there's live or on) is to add the 'jQuery stuff' inside the AJAX callback.
$.get("url", function(data) {
$('.container').html('<button class="submit-something">Submit</button>');
$('.submit-something').click(clickHandler);
});
You can always check at any point of time, whether the element exists or not by simply adding a console log.
console.log($('.submit-something').length);
Hope this answers your question regarding any jQuery operation you want to perform.
UPDATE:
load event is a special case that cannot be tested in this way. However, it is intuitive that the content inside the element where I called load event is cleared. So any event or tablesorter associated with it, no longer applies. Once the content is loaded, you need to associate the event or tablesorter again to the inner elements. This is same as getting a response from AJAX and rebinding the event.
Related
some info
I'm working on a webpage that can load data on multiple layouts, so user can choose which one is best. It can be loaded in a list or a cards like interface, and the data is loaded using ajax.
In this page I also have a notifier for new messages that the user received. The ajax function is new, and when page was loaded by the php scripts, the js script (that add a badge with the number of unread messages to a link on a menu item) was working ok.
I'm using HTML5, PHP, jQuery and a mySQL DB.
jQuery is imported onto the HTML using
<script src="https://code.jquery.com/jquery.js"> </script>
So it's a recent version.
the problem
Now, when I load the data onto the page using ajax, the js script won't work anymore. I had the same issue with another js script and I managed to solve it by using the delegate event binder.
But my unread messages updater runs on a time interval, using
<body onload="setInterval('unread()', 1000)">
the unread() js is quite simple:
function unread() {
$(document).ready(function(){
$('#menu_item').load('ajax_countNewMsgs.php');
});
}
it calls a php script which grabs the unread msgs count from the DB and echo into a element that jQuery will point. Hope I'm being clear.
The problem is that I cannot figure out how I would call a timed event using delegate. Without much hope I've tried
$(document).on('ready()','#menu_item', function () {
$(this).load('ajax_countNewMsgs.php');
});
That didn't work.
I read many posts about js stop working after changes in the DOM, but, again, I couldn't figure out a way to solve that, nor found a similar question.
Any help or tips would be highly appreciated.
EDITED to change second php script's name
2nd EDIT - trying to make things clearer
I tried the way #carter suggested
$(document).ready(function(){
function unread(){
$.ajax({
url: 'ajax_countNewMsgs.php',
type: 'GET',
dataType: 'html',
success: function(response){
$('#menu_item').html(response);
},
error: function(response){
//no error handling at this time
}
});
}
setInterval(unread(), 1000);
});
the ajax_countNewMsgs.php script connects to the DB, fetch the unread messages, and echoes the number of unread messages.
If I try to apply the ajax reponse to another element, say, the <body> the results are as expected: at each 1 sec , the body html is changed. So the function is working.
As I said, none of my JS changes the #menu_item. Actuallly this element is part of another php scritp (menu.php) which is imported to the top of the page.
the page structure is this way:
<html>
<head>
some tags here
</head>
<body>
<?php include (php/menu.html); ?>this will include menu with the #menu_item element here
<div id='wrapper'>
<div id='data'>
here goes the data displayed in two ways (card and list like). Itens outside div wrapper are not being changed.
</div>
</div>
</body>
</html>
Even though the elemente is not being rewritten js cannot find it to update it's value.
It's not the full code, but I think you can see what is being done.
$(document).on('ready()','#menu_item', function () {
is an invalid event listener. If you wanted to be made aware of when the DOM is ready you should do this:
$(document).ready(function () {
However I don't think that is actually what you want. Your function unread will fire repeatedly but it attaches an event listener everytime. Instead if you want to make an ajax call every so many seconds after initial page load, you should do something like this (dataType property could be html, json, etc. pick your poison):
$(document).ready(function(){
function makeCall(){
$.ajax({
url: 'ajax_countNewMsgs.php',
type: 'GET',
dataType: 'html',
success: function(response){
//handle your response
},
error: function(response){
//handle your error
}
});
}
setInterval(makeCall, 1000);
});
remove that on your unread function:
$(document).ready(function(){
WHY?
The Document is already "ready" and this document state will only fired 1x - After that the "ready state" will never ever called. Use follwing syntax:
jQuery(function($){
I have a weird problem.
I'm currently working on loading posts using PHP, AJAX and MySQL. The code structure itself looks like this:
My code structure
--- main.js ---
$(window).load(function(){
initAjax();
});
--- ajax.js ---
function initAjax(){
// Toggles a navigation
$(document).on('click', '.btn.open', function(){
... toggles a window ...
});
// Add new posts
$(document).on('click', '.btn.refresh', function(){
$.ajax({
... ajax stuff ...,
success: function(html){
// Show new posts
$('.post_container').prepend(html);
}
});
});
}
So what is the problem?
When I append new posts they'll show up, but I am not able to click .btn.open anymore - Shouldn't 'on()' fix this? When I go to the Google Chrome console.
Does somebody know a potential way to solve the problem?
Edit:
The appended posts are the same as the default loaded posts!
'.btn.open' exists (div with class="btn open")
I am using jQuery v2.0.3 (so .on should work!, .live and .delegate were replaced by .on!)
Removed an error message that was created by a corrupted Chrome extention = No change.
Created a .gif showing the problem in action: http://d.pr/i/cJB3
FIXED! #cmorrissey found a small solution by replacing $(document) with $('body')
BUT
This fix doesn't seem to be a perfect solution since $(document) normally has to work! Since I want clean code, I am totally going to try out #Potherca's Short, Self Contained, Correct, Example method and probably I'll find the solution this way. Thanks
You need to use 'body' or document.body instead of document.
$('body').on('click', '.btn.refresh', function(){
$.ajax({
... ajax stuff ...,
success: function(html){
// Show new posts
$('.post_container').prepend(html);
}
});
});
Reason: The addition of content to the body doesn't bubble up to the document level (http://bugs.jquery.com/ticket/11621), it looks like you can also use window
Im currently struggling with an AJAX related problem on a website.
The goal is as follows:
There is a "simple" HTML page containing some links and content.
If you click on a link I want to open the file that gets includes with the link (from href) within a new div overlayed to the page. The content from the page is of course loaded with AJAX into the new div (the overlayed one).
Within this new overlayed div I want to add some JS code which in general already works.
The problem anyway is that the DOM elements within the page loaded per AJAX cannot be accessed in a way that is comfortable to work with, in my specific case.
I got following piece of code so far:
$$('.add-exercise').addEvent('click', function(e) {
var request_exercise_add = new Request.HTML({
'method' : 'post',
'url' : e.target.get('href'),
onSuccess : function(responseTree, responseElements, responseHTML, responseJavaScript) {
// i know i can access responseElements here..
}
});
request_exercise_add.send('s=true');
return false;
});
I know I can access the elements returned within responseElements but the logic on the included website is somehow quite complex and therefore it should be
possible to add the JS within the HTML code in the dynamically loaded page.
Notice that the JS also cannot be added to the head section because it would not know the elements that are loaded after the dom-ready event.
have you tried iframe ?
or the website that you are trying to add does not have PPP cookie and AllowContentInIframe .. ?
If you want to add the script inside the ajax request you need evalScripts: true and you should remove the quotes around the request options.
$$('.add-exercise').addEvent('click', function (e) {
var request_exercise_add = new Request.HTML({
method: 'post',
url: e.target.get('href'),
evalScripts: true,
onSuccess: function (responseTree, responseElements, responseHTML, responseJavaScript) {
// i know i can access responseElements here..
}
});
request_exercise_add.send('s=true');
return false;
});
I don't know what is the content of the response but you might also want to use Mootools's .set() instead of innerHTML to append new elements (if you are not doing that yet). Maybe worth to check Dimitar's answer here about that.
Imagine a normal page calling javscript in head. The trouble is some of the content isnt loaded untill i click on a link. Subsequently when this link loads the content it wont work. This is because i guess the javascript has already been run and therefor doesnt attach itself to those elements called later on. There is only standard html being called.
So for example this is the code which calls my external html.
$.get('content.inc.php', {id:id}, function(data){
$('#feature').children().fadeTo('fast', 0).parent().slideUp('slow', function(){
$(this).html(data).slideDown('slow');
});
});
If the html i was calling for example and H1 tag was already in the page the cufon would work. However because i am loading the content via the above method H1 tags will not be changed with my chosen font.This is only an example. The same will apply for any javascript.
I was wonering whether there is a way around this without calling the the javascript as well the html when its received from the above function
If you want to attach events to elements on the page that are dynamically created take a look at the "live" keyword.
$('H1').live("click", function() { alert('it works!'); });
Hope this is what you were looking for.
Does Cufon.refresh() do what you want?
As you said Cufon was just an example, I'd also suggest a more general:
$.get(url, options, function(html, status) {
var dom = $(html);
// call your function to manipulate the new elements and attach
// event handlers etc:
enhance(dom);
// insert DOM into page and animate:
dom.hide();
$target_element.append(dom); // <-- append/prepend/replace whatever.
dom.show(); // <-- replace with custom animation
});
You can attach event handlers to the data that you get via the get() inside of the callback function. For example
$.get('content.inc.php', {id:id}, function(data){
$('#feature').children().fadeTo('fast', 0).parent().slideUp('slow', function(){
$(this).html(data).find('a').click(function(e) {
// specify an event handler for <a> elements in returned data
}).end().slideDown('slow');
});
});
live() may also be an option for you, depending on what events you want to bind to (since live() uses event delegation, not all events are supported).
Andy try this. It will call the Cufon code after each AJAX request is complete and before the html is actually added to the page.
$.get('content.inc.php', {id:id}, function(data){
$('#feature').children().fadeTo('fast', 0).parent().slideUp('slow', function(){
$(this).html(data);
Cufon.replace('h1');
$(this).slideDown('slow');
});
});
JavaScript is not executed because of a security reason OR beccause jQuery is just setting this element's innerHTML to some text (which is not interpreted as a JavScript) if it's contained. So the security is the beside effect.
How to solve it?
try to find all SCRIPT tags in Your response and execute them as fallows:
var scripts = myelement.getElementsByTagName("SCRIPT");
var i = 0;
for (i = 0; i < scripts.length; i++)
eval(scripts[i].innerHTML);
I have lots of jquery functions in my script but a particular one is not working, this is my function
$('#delete').click(function() {
var id = $(this).val();
$.ajax({
type: 'post',
url: 'update.php',
data: 'action=delete&id=' + id ,
success: function(response) {
$('#response').fadeOut('500').empty().fadeIn('500').append(response);
$(this).parent('tr').slideUp('500').empty();
}
});
});
a similar function like this is working
<!-- WORKING FUNCTION -->
$('#UpdateAll').click(function() {
$.ajax({
type: 'post',
url: 'update.php',
data: 'action=updateAll',
success: function(response) {
$('#response').fadeOut('500').empty().fadeIn('500').append(response);
$('#table').slideUp('1000').load('data.php #table', function() {
$(this).hide().appendTo('#divContainer').slideDown('1000');
});
}
});
});
I checked with firebug, the console doesnt show any errors, i checked html source the values are loading correct, i checked my php file 5times it is correct can't figure out the problem. Please Help.
I struggled with the EXACT SAME PROBLEM for 6hr straight! the solution was to use jquery 'live'.
And that is it.
$('#submit').live('click',function(){
...code...
});
With the first one, I'd put a quick and nasty alert() within the click anonymous function, to ensure that it is being fired. Eliminate reasons why it may not be working. Also, try using Live HTTP headers or Firebug's console to see if the AJAX request is being sent.
If the click is not being fired, see if you have the selector correct. I often do this (quite nasty)
var testSelector = 'p:first ul li:last';
$(testSelector).css( { border: '1px solid red' } );
It won't always be visible, but if you see style="border: 1px solid red"` in the generated markup, you know your selector is on the ball.
Perhaps you have another click that is overwriting it? Try using
$('#delete').bind('click', function() {
// do it
});
I just had the same problem with a quick example I was working on. The solution was to put the click inside $(document).ready. I was trying to use my element before it was actually ready to be used.
It's basic JavaScript to wait until the DOM is ready before you try to use an element, but... for whatever reason I forgot to do that, so maybe the same happened to you.
$(document).on('click', '#selector', function(){
// do something
});
jQuery 1.7+ has depreciated .live() and now uses .on() instead :)
I don't know if this applies in your context, but if you have parts of the page that are getting loaded by AJAX then you'll need to bind the click handlers after that content is loaded, meaning a $(document).ready isn't going to work. I've run into this problem a number of times, where certain events will fire fine until parts of the page are reloaded, then all the sudden the events seem to stop firing.
Just use your .click with $(document).ready(function(){ ... }); because you are trying to apply the click event on a non-existent element.
1) just before the last }); you should add return false;
2) Are you sure that #delete exists? Also, are you sure is UNIQUE?
This is a long shot, but it's good to be aware of.
http://code.google.com/p/fbug/issues/detail?id=1948
May not be an issue if you're not on Firefox 3.5.
Instead of id=delete i changed it to class=delete in html and in js ('.delete') and it is working fine now but when again tried with id it doesnt work.
Thank You all for Help, i dont have any problem whether it is id or class just the function works now.
There is few things you can do:
like Elmo Gallen and Shooz Eh suggested, put your code in $(document).ready(function(){...});
code your $('#delete').click(function(){...}); event handling AFTER your <button> tag,
use $('#submit').live('click',function(){...}); like Parikshit Tiwari suggested.
Everyone of these should work ok.
EDIT: oops, didn't see that this was asked '09 :D
I think you must use .on() function for dynamically code run in jQuery like this:
$(document).on("click","#delete",function(){ });