I am inserting the HTML response from an AJAX call into my page, but then when I try to access those elements after they have been created, it fails..
This is how i retrieve and insert the HTML:
$.ajax({url: 'output.aspx',
data: 'id=5',
type: 'get',
datatype: 'html',
success: function(outData) {$('#my_container').html(outData);}
})
The outcome HTML, which is inserted into the <div> (id = my_container) looks like:
<div id="my_container">
<ul>
<li id="578" class="notselected">milk</li>
<li id="579" class="notselected">ice cream</li>
<li id="580" class="selected">chewing gum</li>
</ul>
</div>
...and afterwards, when I try to access any of the <li> elements using queries like:
$('#my_container li:first') or
$('#my_container ul:first-child') or similar, nothing gets selected.
I am using the Listen plugin to detect any click events on the <li>elements and it works... But i couldn't figure out how to detect if the div is populated with the output HTML and accordingly change one of the <li>'s class for example...
$(document).ready does not work either...
Imagine I need to change the css style of the second <li>.. what is the solution to this?
How are you checking to see whether your AJAX call has completed? Because it's asynchronous, the elements will not, of course, be available to the code which executes immediately after your $.ajax(…) call.
Try manipulating those elements from within the success function or in other code which is called from there — at that point, you will know that the content is available.
Are you sure your actual request is successful? If nothing is selected, the most probably reason is that nothing was actually inserted into #my_container in the first place.
First, try the following code (in place of the original AJAX call you showed):
var html = $.ajax({url: 'output.aspx',
data: 'id=5',
type: 'get',
datatype: 'html',
async: false
}).responseText;
$('#my_container').html(html);
If that works, your li:first selector is just being called before the AJAX request finishes. If that doesn't work, try the following code:
$.ajax({url: 'output.aspx',
data: 'id=5',
type: 'get',
datatype: 'html',
success: function(outData) { $('#my_container').html(outData); },
error: function(errorMsg) { alert('Error occured: ' + errorMsg); }
});
That will cause an error message to pop up if the request fails. If an error message pops up with an error message, the request is not returning.
it's looks like you are trying to access to those elements before their was created because your current ajax call is asynchronous, try to put the option:
"async=false"
to your ajax and it should be work.
Related
In my HTML page , I have the following div:
<div id="notification"></div>
An ajax call add some attribute to that div after receiving successful response.This is what the ajax success does:
$("form").on("submit", function (e) {
e.preventDefault();
$.ajax({
dataType: 'json',
type: "POST",
url: "/dummy/url",
data: {Redacted},
success: function (data) {
$('#notification').attr({'data-status': data['status'], 'data-message': data['message']});
$('#notification').click();
$('#notification').removeAttr("data-status data-message");
}
});
});
The problem is the attributes of #notification does not go away after using removeAttr. I mean it removes the attributes from the page, but remains as cached. Thats why I am getting same data-message on every click though the server returns different data-message.
For example:
In my first ajax call, server returned:
{"status":"success","message":"Invitation sent"}
In this case the #notification triggers and shows me data-message="Invitation Sent". But in my second call server returned:
{"status":"danger","message":"Invitation sending failed"}
But #notification shows data-message="Invitation Sent" again.
Any suggestion for me on this? How can I remove the cached data? Or is there any alternative of what I am doing up there?
Instead of using attribute, use data(). If you had already used data() to read the attribute it is going to be cached as a property of the element.
success: function (data) {
var elementData = {
status: data['status'],
message: data['message']
}
$('#notification').data(elementData);
$('#notification').click();
// not sure why it needs to be removed here
// if it does use `removeData()
}
just working on a small blogging system and using multiple ajax calls for updating information without page reloads.
However, after one ajax call the others dont work and instead the form goes to the php page itself.
The ajax calls all follow a similar pattern of:
$(document).ready(function(){
$('.addpost').one("submit",function(e){
$.ajax({
type: "POST",
url: "process/addnewpost.php",
data: $targetForm.serialize(),
dataType: "json",
success: function(response){
if (response.databaseSuccess) {
$("#container").load("#container");
} else {
$ckEditor.after('<div class="error">Something went wrong!</div>');
}
}
});
});
});
On my page, these scripts are loaded like so:
<script src="http://buildsanctuary.com/js/addcomment.js"></script>
I had the same issue with some button events, but got around the issue using .on() however sometimes this doesnt even work so my solution was to put the even in the ajax success response.
Cant find any answers around about how to bind / delegate a whole script?
You use $('.addpost').one("submit",function(e){ to bind the submit event to do your ajax therefore it will ony execute one time, use on instead.
$('.addpost').on("submit",function(e){
I have a javascript function.
I'm making a AJAX call, and in that recieved content there is a link that I want to call the javascript function with.
MyJavascriptFunction(bla){
alert (bla);
}
Result from ajax = "Click
Do I have to do anything special with the result from AJAX to get this to work or should it just work.
I have tried it like this but with no success with clicking the link.
The AJAX call:
function doSearch() {
var form = $('form');
$.ajax({
url: "doSearch.php",
type: "GET",
data: form.serialize(),
success: function(result){
document.getElementById("result").innerHTML=result;
}
});
}
In the php I'm printing out
Click
First of all, try it. But yes you have to do something with the AJAX result. It has to be put somewhere in the DOM or the user won't be able to click on it.
Plus, make sure that the javascript function is a top level. I would suggest you use event handlers instead though.
Change your <a> tag to:
Click
You are mixing jQuery and DOM. that is not pretty
try this - assuming you do not have more than one link in the html
success: function(result){
$("#result").html(result).find("a").on("click",function() {
MyJavascriptFunction(bla);
return false;
};
}
I want to use John Resig's pretty date for replacing my ugly time stamps with some nice-to-read time specification.
So I thought about using the following unobtrusive html markup:
<span data-type="prettyDate">25.04.2012 10:16:37</span>
Acording to that I use following Javascript/jQuery to prettify the date:
$(function() {
$('[data-type="prettyDate"]').prettyDate();
}
My problem is that I don't know how to deal with markup that is loaded using ajax because that would not be caught since it does not yet exist when the DOM ready event fires. Reacting to events on "ajaxed" elements is pretty easy using the on handler. But this is not an event.
You have to call .prettyDate() after each Ajax response is added to the DOM. A simple way to do that is to set a global complete handler with ajaxComplete.
You can use jQuery to target dynamic content before it's actually been inserted into the document, something like:
success: function(html) {
var $html = $(html);
$html.find('[data-type="prettyDate"]').prettyDate();
$(somewhere in document).append($html);
}
What you want to do to get the best performance out of this is have a function which get called on the data as it gets returned from the ajax callback. That way you can prettify your date before adding them to the DOM.
You don't want to call pretty date on element in the DOM every time as you will process date already done too.
So, something like this.
$.ajax({
url:'someurl',
success: function(data) {
var $content = $(data).find('[data-type="prettyDate"]').prettyDate();
$('#mycontainer').append($content);
}
});
or have an helper function which you call
function prettify(data) {
return $(data).find('[data-type="prettyDate"]').prettyDate();
}
or even better hook into the ajax call so that it is done for all html content
There have been a number of cases where I needed certain code to execute after every AJAX call. I'm not sure if it's considered the "correct" solution but I simply decided to create my own wrapper method and use that whenever I needed to make an AJAX request. It typically looks something like this:
AJAXLoadData: function (url, data, successCallBack) {
$.ajax({
type: "GET",
data: data,
url: url,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
// Code I want to execute with every AJAX call
// goes here.
// Then trigger the callback function.
if (successCallBack) successCallBack(msg);
},
error: function (msg) {
alert("Server error.");
}
});
}
In my case this made it particularly convenient to create a javascript caching system for static HTML files.
You could incorporate this code into your ajax success callback function. When the ajax is done and you update your page, also run the code to prettify the dates.
This is one of the things .on() is for. (In the olden days, .live() would have been used.)
I am using the ThreeDots jQuery pulgin and it works great. I am having trouble using it on an ajax success event.
$.ajax({
type: "POST",
url: 'url',
success: function(value) {
$("#content").append(value);
$(".ellipsis").ThreeDots({max_rows:3});
}
});
I load some new data and append the new data to a div (this works great). When I call the ThreeDots function from inside the success event it takes about 1 minute to work and the browser is not responsive during this time. There are .ellipsis spans returned in the new data.
Is there a better way to be doing this? Is there something fundamentally wrong with my approach?
Update
#Nick, Thanks for your answer. I used this and I went one step further. The above still reruns on every ellipsis in content not just the newly returned ellipsis results.
I now do this:
$(value).appendTo("#content").find('.ellipsis' + document.getElementById('hidPage').value).ThreeDots({max_rows:3});
$("#hidPage").val(($("#hidPage").val()-0) + 1);
You can run the .ThreeDots() plugin only on the .ellipsis elements in the returned response, instead of re-running it on all of them, like this:
$.ajax({
type: "POST",
url: 'url',
success: function(value) {
$(value).appendTo("#content").find('.ellipsis').ThreeDots({max_rows:3});
}
});
You can't chain it the reverse way because .ThreeDots() isn't chainable (it returns a custom object), but the above version should work fine.