Incremental Output - Jquery and PHP - php

I have an application that rates a large set of items and outputs a score for each one.
In my php script I'm using ob_start and ob_flush to handle the output of data for each rating. This works great if I directly load the script. But when I try to use .get via jquery, the entire content loads and then is placed into a container, instead of incrementally adding.
I'm wondering the following
Is there a way to initiate data placement before the get has completed?
Do I need to continually poll the script until the process is complete?
Is there a more efficient way to display the data instead of get?

For this kind of problems, I will have this approach:
Keep the old script that using ob_start() and ob_flush() for a user that disable javascript in their browser.
For a user that have javascript enable, load the predefined number content one at a time. To differentiate between js enable user and not, I'm thinking of 2 page. In first page you display a link to old script. Then put a jquery code in this page to intercept click on the link to old script, so click on that link will display (or create) a div, then load the content into that div.
You can use a setTimeout to call AJAX code continuously, then after a certain condition reached (Ex, empty response), you can remove the setTimeout using clearTimeout. Each AJAX request will need to have an offset param, so it will fetch content from last AJAX call. After receive response, increment the offset for the next AJAX call. You can use global variable for this.
You can use a simple global variable to prevent an AJAX request run while the last AJAX still waiting response, to prevent race condition. Example code:
//lock variable
var is_running = FALSE;
//offset start with 0
var offset = 0;
function load_content($) {
//check lock
if (! is_running) {
//lock
is_running = true;
//do AJAX
$.get(URL,
{ PARAM },
function(resp){
//put data to 'div'
//...
//if empty, then call clearTimeout
//...
//increase offset here
offset = offset + NUM_ITEM_FETCHED
//release lock
is_running = false;
});
}
}
The point you must pay attention that using AJAX call, you must determine the response manually, since ob_start and ob_flush will have no effect in this scenario.
I hope this will help you create your own code.

Jquery will receive a success status from the ajax call when the complete page has finished loading .. so whatever you do in the php will not get returned to the calling page until the whole process has finished .. (ajax is a one-send/one-receive system)
You would need to complicate your system to do what you want..
example..
your php updates an external file of progress, and your jquery polls this file in some interval and displays progress..
You would initiate the interval polling on ajax submit, and on ajax success terminate it..

I had a similar problem awhile back where I wanted a php script to send a series of emails and update the jquery page to say something like "Sending 23/50".
What I ended up doing was setting up the php script to handle one item at a time. This might also work in your case. Could you have jquery pass an item identifier of some sort to a php script that handles just that one item? Then in the callback, you could place the data for that item in the page as well as creating a new ajax request for the next item. In other words, each callback would create a new request for the next item until the entire list of items has been looped through.
What do you think?
-DLH

Related

PHP: why does my flood prevention script lag?

Thank you for reading.
I have an input field that sends its contents in an XMLHttpRequest to a php script. The script queries the database with the POST data from the field and returns the results.
Because the XMLHttpRequest is invoked using onkeyup, typing in a lengthy value sends several calls in a short period. To combat this I wrote some code that creates a timestamp, loads it into the session, sleeps, then rechecks the timestamp. if the timestamp has increased, it means a subsequent call was made and the script should abort. Otherwise the script executes. Here is the code.
$micro = microtime(true);
$_SESSION['micro'] = $micro;
usleep(500000); // half a second
if ($micro < floatval($_SESSION['micro']))
{
// later call has been made, abort
echo 'abort';
exit;
}
else
{
// okay to execute
}
The code appears to work as expected at first. If I add or remove a character or two from the input field the result appears quickly.
However if I type a good 12 characters as fast as I can there is a large delay, sometimes 2 or 3 seconds long.
I am working on localhost, so there is no connection issues. The query is also really small, grabbing one column containing a single word from a specific row.
I have also set XMLHttpRequest to be asynchronous, so that should also be fine.
xmlhttp.open("POST","/test/",true);
If I remove the flood prevention code, typing in the field returns results instantly - no matter how much and how quickly I type.
It's almost as if usleep() keeps stacking itself or something.
I came up with this code on my own, best I could do at my level. No idea why it isn't behaving as expected.
Help is greatly appreciated, thanks!
When you open a session using session_start(), PHP locks the session file so any subsequent requests for the same session while another request has it open will be blocked until the session closes (you were exactly right with the "stacking" you suspected was happening).
You can call session_write_close() to close the session and release the lock but this probably won't help in this situation.
What's happening is each time the key is pressed, a request gets issued and each one is backed up while the previous one finishes, once the session is released one of the other requests opens the session and sleeps, and this keeps happening until they've all finished.
Instead, I'd create a global variable in Javascript that indicates whether or not a request is in progress. If one is, then don't send another request.
Something like this:
<script>
var requesting = false;
$('#input').on('keyup', function() {
if (requesting) return ;
requesting = true;
$.ajax({
url: "/url"
}).done(function() {
requesting = false;
});
}
</script>
drew010's answer explained my problem perfectly (Thanks!). But their code example, from what I gather by how it was explained (I didn't try it), does the opposite of what I need. If the user types "hello" the h will get sent but the ello might not unless the result makes it back in time. (Sorry if this was a wrong assumption)
This was the solution I came up with myself.
<input type="text" onkeyup="textget(this.value)" />
<script>
var patience;
function ajax(query)
{
// XMLHttpRequest etc
}
function textget(input)
{
clearTimeout(patience);
patience = setTimeout(function(){ajax(input)},500);
}
</script>
when a key is pressed in the input field, it passes its current value to the textget function.
the textget function clears an existing timer if any and starts a new one.
when the timer finishes counting down, it passes the value further to the ajax function to perform the XMLHttpRequest.
because the timer is reset every time the textget function is called, if a new call is made before the timer finishes (0.5 seconds), the previous call will be lost and is replaced by the new one.
Hope this helps someone.

Jquery/Php returning processing status with Ajax POST

I'm working on a page to process Excel data.
Currently I have an index page where I once submit JSON data (filename, selected columns, worksheet,..) via $.ajax POST to a PHP page for processing (iterate every row with posted selection). But I would like to have some progress response from the processing page. Because now, it just submits and processes everything in the background without knowing if it's done or not.
Is there some kind of way to:
Redirect to the processing page, along with the JSON POST data, instead of an ajax post?
OR
Return multiple JSON responses from one PHP page (like started, stopped,..) and fetch those responses in the same $.ajax success function? Add some kind of check function like
IF last response-line == started, show image
..after a while (keep checking json response..),
IF last response-line == finished, hide image?
I couldn't use the form submit action, because I'm sending a full JSON string instead of seperate input values.
Am I overlooking something here or is this just not possible (with my way of processing)?
You need to use ajax calls to a different PHP file that gets the progress from a session. I also did this once and I did it like this:
Javascript
function getProgress(){
//console.log("progress called");
$.get( "getprogress.php", function( data ) {
//console.log(data);
var p = data.progress;
if (p!=100){
//set your progressbar here
}
}, "json");
}
And in the function where you start the job you just set a timeout
timeout = setInterval('getProgress()', 1000);
Getprogress.php
ob_start();
session_start();
session_write_close();
$output = array();
$output['progress'] = $_SESSION['progress'];
echo json_encode($output);
In your PHP file where you do the actual work, you need to set the progress like this:
session_start();
$_SESSION['progress'] = $progress;
session_write_close();
Remember to use session_write_close() because the session can only be open in one process at a time.

How to query database using javascript?

Another question by a newbie. I have a php variable that queries the database for a value. It is stored in the variable $publish and its value will change (in the database) when a user clicks on a hyperlink.
if ($publish == '') {
Link to publish.html
} else {
Link to edit.html
}
What is happening in the background is i am querying a database table for some data that i stored in the $publish variable. If the $publish is empty, it will add a link for publish.html in a popup. The popup will process a form and will add the data to the database and which means that the $publish is no more empty. What i would like to achieve is that as soon as the form is processed in the popup and a data has been added to the database, the link should change to edit.html. This can happen when the page will re-query the database but it should happen without page refresh.
How can it be donw using javascript, jquery or ajax?? Please assist.
Javascript by itself cannot be used to deal with database. That is done using php (Or the server side language of your choice). Ajax is used to send a request to your php script using javascript which will in turn communicate with the db. And it doesn't require a page refresh.
So what you are trying to do can be easily achieved using ajax. Since you mentioned jquery, you can check out the $.ajax or $.post methods in jquery which make the process even more simple.
You need to process the form using ajax. The ajax request is sent to a php script which will make the necessary changes in the database and send the new link (link to edit.html) in the response. Upon getting the response, just replace the current anchor element with the new one ..
for eg..
$.post(url, formdataobject , function (resp) {
$("a.youra").text('edit').attr('href', resp);
});
url - where the php script is located
formdataobject - a javascript object that will have the form data as key value pairs
the third parameter is an anonymous function also known as callback function since it will be invoked only when the response is received from the server. This is because ajax requests are asynchronous.
Inside the callback function, jquery is used to change the text inside the anchor element to edit and the href attribute is changed to value that came in the response.
$.post means we are using the post method. so the parameters can be accessed as elements of $_POST array in php.
After updating the db, you can simply echo out the new link and it will be received in the response.
Also, there are other formats in which you can get the response for eg. xml, json.
I'll try to leave the technical jargon aside and give a more generic response since I think you might be confused with client-side and server-side scripting.
Think of javascript as a language that can only instruct your WEB BROWSER how to act. Javascript executes after the server has already finished processing your web page.
PHP on the other hand runs on your web server and has the ability to communicate with your database. If you want to get information from your database using javascript, you'll need to have javascript ask PHP to query the database through an AJAX call to a PHP script.
For example, you could have javascript call a script like:
http://www.myserver.com/ajax_function.php?do=queryTheDatabase
In summary: Javascript can't connect to the database but it can ask PHP to do so. I hope that helps.
Let me try, you want to change the link in a page from a pop-up that handles a form processing. Try to give your link a container:
<div id="publish_link">Publish</div>
As for the form submission use Ajax to submit data to the server to do an update and get a response back to change the link to edit or something:
$.post("submit.php", { some_field: "some_value"}, function(response) {
if(response.isPublished)
$('#publish_link', window.opener.document).html('Edit');
});
Basically your publish link is contained in a div with an ID publish_link so you change its content later after data processing without reloading the page. In the pop-up where you would do the form processing it is done using jQuery Ajax POST method to submit the data. Your script then accepts that data, update the database and if successful returns a response. jQuery POST function receives that response and there's a check there if isPublished is true, get the pop-up's opener window (your main window) and update the link to Edit. Just an idea, may not be the best out there.
It cannot be made with javascript, jquery or ajax. only server side script can query a database. with ajax request you can get the script output. ajax requests can be sent either with pure javascript or jquery.
Well, i think i understand your quaestion, but you have to get a starting point, try to understand this:
try to understand what are client variables and server variables.
javascript does not comunicate with database.
you can use javascript to retrieve data to a specific "Object variable".
Using ajax methods of jquery you can post that data do other page, that will execute the
proper actions
you can ;)
at first you must create php file to query database and return something like true or flase and then with file url check the function and get answer
function find_published(folder_id) {
var aj_url = "{{server_path}}/ajax/url"
var list;
$.getJSON(aj_url+"?callback=?&",
function(data) {
//here is your data... true false ... do every thing you want
}
);
};
this app for node.js does mysql queries https://github.com/felixge/node-mysql
You need to use AJAX for this, like .post() or .get() or JSON.

Calculating ajax call time before getting the response

I have finished a facebook app that uses php and ajax to get statisicts about friends and find best match. The app is using tabs and is working fine, however sometimes when I click on one tab to send ajax request and loading icon shows I do not get any response back and the loading icon keeps showing. Is there a way that I can count how many seconds an ajax call is taking so I redirect the user to an altertanive html page after x number of seconds?
To achieve what you'd like to obtain, you could call (after X seconds, using setTimeout()) a function that checks if the ajax response has been loaded.
For example:
var responseLoaded = false;
function checkIt(){
if(!responseLoaded)
window.location = "%http://alternative-page%";
}
setTimeout(checkIt,10000) //after 10 seconds
responseLoaded could be a global variable that can be set to true at the end of the ajax response.
Or, alternatively, you could check if some DOM element or JS var is present (i.e. created by AJAX call) at that time (when the function has been called through setTimeout)
Then, You could use
Date.getTime()
To obtain the current timestamp. You can compare the timestamp at the beginning with the one at the end of the ajax response to see the total time it takes. (just if you want to check the average ajax loading time)
Another option would be to set the timeout parameter of the of the xmlhttprequest object. In jQuery it's the timeout option in the options object.
$.ajax ({
timeout: 1000,
success: successCallback,
error: function (req, error, errorStatus) {
if (error == 'timeout') {
//send them to other page....
}
}
});
You would probably want to put in some more error handlers though... also, since the xmlhttpobject2 has on timeout function callback, this process might be more streamlined now...
Don't quote me exactly on the syntax either. I'm writing this on my phone from memory....

Displaying POST Data with jQuery?

I'm using a flash webcam to take a picture. It works great and spits back a URL via POST.
I'm coding in PHP and would like to display this POST data once it is recieved, the problem is that I dont re-load the page.
I've looked around and I'm not sure to dynamically load this array of data.
Where should I be looking? jQuery?
Ah, Figured it out. The Flash thing I have has a built in callback function, so I just have to append the data from there!
jQuery is not able to read any sort of request data other than that which appears in the URL (GET). You will need to use PHP (or some other server-side language) to handle the response created by the FLash application.
Due to the fact that you're using Flash for the process you are at somewhat of a disadvantage because unless the Flash application has some sort of JavaScript "PhotoUploaded" event notification, your page won't be notified that Flash has just submitted a picture to your server which needs to be retrieved and inserted. If you can modify the Flash application to make an external JavaScript event then you can proceed as Frankie has described in his answer; otherwise, if modifying the Flash application is not an option, then another solution would be to have your page send a request to the server every so often (5-10 seconds or so maybe), to check if there is a photo for it to display yet.
The simplest way to setup polling with your server in this fashion would be to make sure that each photo upload from Flash has a unique, pre-determined identifier that your page knows at initial load. You would then simply ping your server every few seconds with an AJAX request and pass it that unique identifier in order to find the right image should one exist.
Basic example:
function GetPhoto() {
$.get('/getphoto.php?ID=1541XJ55A6', function(response) {
if(response.ImageUrl !== "") {
$(".profile-image").attr("src", response.ImageUrl);
if(getPhotoTimer !== undefined) {
clearInterval(getPhotoTimer);
}
}
});
}
$(document).ready(function() {
var getPhotoTimer = setInterval("GetPhoto()", 10000); // every 10 seconds
});
Flash calls javascript each time it spits back the URL.
Javascript contacts server (php) and gets content
Javascript injects content onto page
Like this (flex code):
// attach a function to the completeHandler
private function completeHandler(evt:Event):void {
javascriptComplete();
}
// declare the function that will call the javascript function
private function javascriptComplete():void {
var javascriptFunction:String = "galeryUploadComplete("+Application.application.parameters.opt+")";
ExternalInterface.call(javascriptFunction);
}

Categories