Delay AJAX from loading? - php

I am programming an online PHP-based fantasy pet simulation game. I am not very familiar with AJAX, so please keep this in mind when answering.
On pet pages, I would like users to be able to feed/water/play with their pets without needing to reload the entire page - that's why I'm using AJAX. Here's what I have so far:
Working Script
$(function() {
$(".petcareFood").click(function(event) {
event.preventDefault();
$("#petcareFood").load($(this).attr("href"));
});
});
$(function() {
$(".petcareWater").click(function(event) {
event.preventDefault();
$("#petcareWater").load($(this).attr("href"));
});
});
$(function() {
$(".petcarePlay").click(function(event) {
event.preventDefault();
$("#petcarePlay").load($(this).attr("href"));
});
});
</script>
Working HTML
<a class=\"petcareFood\" href=\"petcare.php?pet=#&action=#\">Feed Your Pet</a>
<a class=\"petcareWater\" href=\"petcare.php?pet=#&action=#\">Water Your Pet</a>
<a class=\"petcarePlay\" href=\"petcare.php?pet=#&action=#\">Play With Your Pet</a>
NOW, everything that I listed above works like a charm! This is my problem: I want those links to also update another DIV - the one which contains updated status bars showing how hungry/thirsty/unhappy their pet is. Currently, I am doing that like this:
The Almost Working Script
$(function() {
$(".petcareFood").click(function(event) {
event.preventDefault();
$('#petcareHunger').load('ajax/hunger.php?pet=#');
});
});
$(function() {
$(".petcareWater").click(function(event) {
event.preventDefault();
$('#petcareThirst').load('ajax/thirst.php?pet=#');
});
});
$(function() {
$(".petcarePlay").click(function(event) {
event.preventDefault();
$('#petcareMood').load('ajax/mood.php?pet=#');
});
});
The script above makes it so that when a user clicks one of the HTML links, it updates two DIVS (one DIV containing the message displayed when a user feeds/waters/plays with their pet, and the other containing the status bar). Now... that seems all fine well and good, BUT... if both scripts update at exactly same time, then the PHP that handles the status bar is not updated - it's still retrieving old information.
My question to all of you is: Is there any way that I can delay running the second set of script (so that it will update after the PHP makes changes to MySQL)?
I tried inserting this before "the almost working script":
setTimeout(function() {
$('#petcareMood').load('ajax/mood.php?pet=#');
}, 2000);
However, it doesn't work. Well - it does, but just once. Users need to play with their pets at least 3 times a day to achieve 100% happiness, and so delaying the second DIV only once doesn't cut it for me. When I tried adding the same script multiple times, it just stopped working all together. What can I do?!
If you'd like to see screen shots of how things are working, please just ask. I will be happy to provide them upon request.
Thank you in advance!

Instead of a hardcoded delay time, you maybe could use the callback function of the first ajax action:
//trigger first ajax
$("#petcarePlay").load($(this).attr("href"), function(){
//trigger second ajax call, when first is completed
$('#petcareHunger').load('ajax/hunger.php?pet=#');
});
see http://api.jquery.com/load/

You could use the complete parameter to specify a callback function that gets executed when the request completes. Then from within the callback, execute another request which actually updates the divs.
Example:
$(".petcareWater").click(function(event) {
event.preventDefault();
$("#petcareWater").load($(this).attr("href"), function(response, status, xhr) {
// code here to make another request for stats
}
});
Alternatively, you could have the initial URLs return some JSON data that contain the updated stats so when a person does something to/with their pet, it returns all the stats so you can immediately update the div's all with one call rather than having to make a secondary call for the data.

I'm not sure, but i think the ajax constructor is better for your purpose http://api.jquery.com/jQuery.ajax/.
There you can set that the AJAX will be synchronous(It will wait to finish the AJAX callback )
Here is a few theory about it :)
http://javascript.about.com/od/ajax/a/ajaxasyn.htm

Instead of setTimeout, use setInterval. When it's no longer needed, you can kill it using clearInterval.
setInterval will execute a given function every n milliseconds.

Related

How to pass variable to php script from Jquery $(document).ready function

I am building a chat. I have this Jquery working code which calls logs.php every second and refreshes the chat.
$(document).ready(
function(e) {
$.ajaxSetup({cache:false});
setInterval(function() {
$('#chatlogs').load('logs.php');
updateScroll();
}, 1000);
}
);
As you can see, also updateScroll, a JS function on my page, gets called. Updatescroll creates a variable, which I would like to pass on to logs.php, is there any way to do this? In other words, updatescroll basically checks everysecond if the user has scrolled up to the top of the chat. If so, I am gonna tell logs.php to load -say - another 10 messages. But in order to do this, I have to have something that from updatescroll passes on to the Jquery function and thus onto logs.php. You get it? Thanks
First, when it comes to ajax, I would recommend using a window.setTimeout, intervals can get tricky when you are running things asynchronously (if one call hangs you can end up with multiple calls to the same script).
so something more like:
(function($){
var update_messages = function(){
var count = updateScroll();
$('#chatlogs').load('logs.php?count='+count, function(){
window.setTimeout(update_messages, 1000);
});
}
$(document).ready(function(){
$.ajaxSetup({cache:false});
update_messages();
});
})(jQuery);
Then in your PHP script the "count" would be available via $_GET['count'].
EDIT: you can see an anonymous function is being sent as a second argument to load, this will be called AFTER the AJAX call is complete, so we can make sure only 1 of these is running at a time

JQuery autocomplete not working until after page refresh and/or a random event

Apologies for the title.
I have a page using two scripts, both acting upon the same form.
This is an autosave script (as there is a lot of typing on the form, I don't want users to lose data).
<script rel="text/javascript">
$(function () {
$.post("autosave.php", "json");
setInterval(function () {
$.post("autosave.php", $("form").serialize());
}, 2000);
});
</script>
Which works well. autosave.php is nothing more than a simple db query updating the various fields from the POST data its getting from the form.
I am also using an autocomplete script for the email field in my form.
<script rel="text/javascript">
$(function() {
var availableTags = <?php include('view-job-q-em-search.php'); ?>;
$("#sendy_to").autocomplete({
source: availableTags,
autoFocus:true
});
});
</script>
This also works well, the PHP script in this again is just a simple db query returning a json array.
However, they don't work well together, well they do, to a fashion.
Interestingly if I type even so much as a single character into one of the text boxes on the form, then refresh, the autocomplete starts working, but it wont when the page loads for the first time. It is like it is stuck waiting for the autosave to perform its first action before the autocompete kicks in.
I am versed enough in Jquery to make these things work, but not good enough yet to spot the anomaly's, so any help or ideas to make this work would be great.
I'm also using generic external scripts jquery.min, jquery,ui which are loaded at the start of the page in the <head>
By the looks of it (and without running too many tests), you're running your code in a synchronous way. What I mean is that this statement:
var availableTags = <?php include('view-job-q-em-search.php'); ?>;
is preventing the execution of the rest of the code since your server is parsing a PHP script.
Instead of including a script for your availableTags, use AJAX to request the tags
available, for example:
var availableTags;
$.get( "tags/getAvailable", function( data ) {
availableTags = data;
$("#sendy_to").autocomplete({
source: availableTags,
autoFocus:true
});
});
that should solve the issue. Could you elaborate on the contents of view-job-q-em-search.php?
OK, it was a combination of two things. Firstly, you were completly right, the call needed to be synchronous.
The biggest problem ...
Because I was autosaving every two seconds, as soon as I opened the form I was saving a blank row. The query for the autocomplete was then trying to populate a json array with a blank entry and it didnt like it.
The workaround was to just add ...
$dname_list = array();
while($row = mysqli_fetch_array($result))
{
if(!empty($row['sent_to'])){
$dname_list[] = $row['sent_to'];
}
}
echo json_encode($dname_list);
... the !empty clause into the query so that it didnt try and add empty rows to the json array.

AJAX/PHP – callback after finished loading data

(Not sure if I missed an already similar answered question…)
On click of a button, I'm loading various images from a database via PHP/MySQL and appending it to the body (the actual images are of course not stored in the database, the correct selection of the images is based on a posted variable).
My goal is to display a loading indicator after pressing the button and hiding the indicator after all the image data has completely loaded and displayed. This may be an easy to solve callback issue but I'm just getting started with AJAX. :)
The following is the code I currently managed to come up with. I'm guessing the load() function is not really the right one here?
Thanks for your help!
$("#somebutton").click(function(){
alert("fetching…");
$.post('loadmore.php', {
somevariable: somevariable
},
function(data){
$("body").append(data);
$(window).load(function(){
alert("finished loading…");
});
});
});
The function you have with the finished loading... alert is a success callback, so it gets executed once the AJAX call has finished. This means you don't need to use $(window).load.
Also, you can use the html method on an element to change its contents and display a message.
Something like this would work fine:
$("#somebutton").click(function(){
$('#divID').html('Loading...');
$.post('loadmore.php', {
somevariable: somevariable
},
function(data){
$("body").append(data);
$('#divID').html('');
});
});
Read the docs http://api.jquery.com/jQuery.ajax/
Use the success callback to append the body and then the complete and error callbacks to clear things up correctly.
$("#somebutton").click(function(){
alert("fetching…");
$.post('loadmore.php', {
somevariable: somevariable
})
.success(function(data){$("body").append(data)})
.error(function(){alert("oh dear")})
.complete(function(){alert("finished loading…")});
});
Remember to always have a fallback for removing the loader - nothing worse than just having a loader and no way to remove it from the page and continue using the application / web site.
I managed to solve my problem by reading and tweaking the code in the following article.
The function load() with the equation containing the self-explanatory variables [imagesLoaded >= imageCount] did the trick.
Know when images are done loading in AJAX response

JQuery Additional Questions Fade Effect

$(document).ready(function(){
setInterval(function(){
$('.bopa').load('accounts.php');
},30000);
});
Hi guys! Me again. So I got back to this stuff and I realized that this is JQuery. It maybe possible for me to put a fade effect somewhere there. I just don't konw where. Is it actually possible if so please tell me where. The accounts php actualy contains something like
$command=mysql_query("SELECT * FROM pages order by rand() limit 1");
now it works every 3 seconds the content changes. I am trying it on text first so that it'd be easier. Later on I'm planning to do it on pictures.
You can add a callback function to the AJAX request you're making:
$('.bopa').load('accounts.php');
Could change to:
//start by fading-out the element(s)
$('.bopa').fadeOut(250, function () {
//continue by loading the new content now that the element(s) has/have faded-out
$(this).load('accounts.php', function () {
//now that the new content has loaded, fade the element(s) back in
$(this).fadeIn(250);
});
});
This also takes advantage of the callback functions for the jQuery animation functions used (.fadeIn()/.fadeOut()).

Jquery(ajax) PHP search results not displaying in search_results div under form

For a website I'm making for school, I'm trying my hand at using Jquery extensively for the first time, and even though I managed quite a bit so far, I'm stuck at two (most likely related) problems.
I'm aware that the upcoming case is somewhat long, but I feel it's necessary to submit all relevant code for everyone reading this to get a good image of what is happening.
Basically, the website is one index.html file, with the CSS thrown in, a few buttons, and one div with the ID content. I use this code to make this work:
<script type="text/javascript">
if ($('#content').innerHTML == " "){
$(document).ready(function(){
$('#content').load('main_text.html');
});
}
</script>
<script type="text/javascript">
function loadContent(elementSelector, sourceURL) {
$(""+elementSelector+"").load(""+sourceURL+"");
}
</script>
Then there is one content page, named search.html, which only contains a form that submits a search string to a search.php page (through ajax) that should then place the search results immediately back into a div called search_results in that same search.html file. The jquery that I use for this:
<script type='text/javascript'>
$(document).ready(function(){
$("#search_results").slideUp();
$("#search_button").click(function(e){
e.preventDefault();
ajax_search();
});
$("#search_term").keyup(function(e){
e.preventDefault();
ajax_search();
});
});
function ajax_search(){
$("#search_results").show();
var search_val=$("#search_term").val();
$.post("Functions/search.php", {search_term : search_val}, function(data){
if (data.length>0){
$("#search_results").html(data);
}
})
}
</script>
The issue that I'm having is as followed:
Before I had the first line of code: if ($('#content').innerHTML == " "){; implemented, I would open the site, main_text.html would nicely be loaded in, I could navigate to other subpages fine. But typing in something in the form field in search.html did not display any results (just typing should already trigger the function). When I hit the search button on this form, instead of seeing query results, the main_text.html file load again in the #content div. This made me assume that perhaps, somehow, that the code:
$(document).ready(function(){
$('#content').load('main_text.html');
});
was being called again unwanted. Hency why I implemented that check for whether innerHTML existed.
However, now, when I first load the page, the #content div does not load any initial content at all. (The section on the webpage just becomes black, like my page background) I have to click any button to get some content loaded again in my main content div. Also, when I now go back to the search.html, the typing anything to get results, like previously, still does not work. If I now hit the search button, I get the initial result again of what I'd see when I just opened the page: a blacked out #content div.
So somehow, the biggest issue is in the fact that the jquery to get results from my PHP do not seem to work. My problem with the content.innerhtml check might well be obsolete if the issue with the searchresults not displaying in the #search_result div on the search.html is fixed.
Anyone have any idea's what I could do to fix this. Or otherwise, what other approaches I could take for the kind of website I'm making. Since I'm trying to learn jquery here, better approaches are always appreciated, I'd rather learn myself doing this the right way and all. :)
Thanks for your time.
Few things to note here:
<script type="text/javascript">
if ($('#content').innerHTML == " "){
$(document).ready(function(){
$('#content').load('main_text.html');
});
}
</script>
<script type="text/javascript">
function loadContent(elementSelector, sourceURL) {
$(""+elementSelector+"").load(""+sourceURL+"");
}
</script>
In the above, you are testing to see if there is a space in the innerHTML of the element with an id of content.
jQuery uses .html() or .text() to make comparisons against the data being held within a container, so if you want to maintain using jQuery principles, change this line. Going along the same thought process, you are preparing an IF statement on an element before the document is actually ready and loaded.
You should move the document.ready function to the outside of the if statement. This will allow you to ensure that the element is available at DOM, and you can indeed perform checks against this element.
<script type="text/javascript">
$(document).ready(function(){
if ($('#content').html("")){
$('#content').load('main_text.html');
}
});
</script>
Also, while being readily provided and fully functional, I would recommend starting off using $.ajax instead of $.get / $.post. I have personal preferences as to why I think this, but I won't go into that, it's just that, personal.
$.ajax({
url: "Functions/search.php",
type: 'POST',
data: "search_term="+search_val,
success: function(data){
if (data.length>0){
$("#search_results").html(data);
}
});
Lastly, you should be using the GET method and NOT the POST method. Based on REST/SOAP practices, you are retrieving data from the server, and not posting data to the server. It's best practice to follow those two simple ideas. This isn't because web servers will have a difficult time interpreting the data; but, instead, it's to prepare you for working on larger scale application deployment, or future team-environments. This way everyone on the team has an expectation as to what method will be used for what purpose.
Anyway, long story short, you also leave semicolons off of the end of your closing }) brackets. While this is not an issue, nor will it cause flaws in your development, coding is all about uniformity. You've used the closing ; everywhere else, so try and maintain that same uniform design.
Best of luck.

Categories