I post data to a page and make some checks that take 5-6 seconds. I would like to insert a waiting page to improve the user experience.
My code is like this:
....functions that take time
echo $twig->render('template.html.twig',[ variables ....]);
Because PHP calls the twig template at the end after processing the data I cannot use a javascript solution.
I tried rendering a waiting template first, then process the data and store the output in a session variable then after that send a location header to the results page but I found PHP does not echo the waiting template untill it finishes the whole script even if i call it in the beginning.
echo $twig->render('waiting.html.twig',[ variables ....]);
....functions that take time
store output as session variable.
send location header to another page that renders the template from the session variable
How can I achieve a waiting page?
You could always store the data temporarily and load a dummy "loading page" for the user. And right when the dummy page loads you send an ajax request that recovers your data and processes it. When the ajax call returns you could do your redirection or whatever it is you want to do when the process is done.
When I say "store the data temporarily" I mean in a database or a file, etc.
The solution I ended up doing was the following:
Call the page by Ajax and display a waiting page.
function submit_form(file_method) {
var spinner = $('#loader');
spinner.show(); //show waiting div
var request = $.ajax({
url: "upload.php",
cache: false,
contentType: false,
processData: false,
async: true,
data: form_data,
type: 'POST',
success: function (res, status) {
if (status == 'success') {
window.location.href = 'results.php';
} },
error: function (jqXHR, textStatus,res) {
spinner.hide();
alert('Error encountered: '+textStatus+'-'+jqXHR.responseText);
} })
};
In the php page, store the output as an array in a session variable.
....functions that take time
$_SESSION['result'] = [RESULTS .......]
After the ajax call is completed successfully the user is redirected to a new page. The new page uses the session variable to call the template.
echo $twig->render('waiting.html.twig',$_SESSION['result'] );
unset($_SESSION['result']);
Simplest solution is to add 'waiting page' inside first page but hide it. When user presses button browser will send request, but will still wait for response showing old page. Here you can show it using JS.
In short - user presses button, you show template (which was already there but hidden) and then browser just waits for response with your template in front.
But best way would be to use AJAX like Patriot suggested.
Related
I've read all the articles but cant seem to get my ajax response into a PHP variable. Please can you advice. I want to assign rowid to a PHP variable.
$(document).on('click', '#updateid', function() {
var vallab = $('#idval').val();
var rowid;
$.ajax({
url:'a.php',
type: 'POST',
async: false,
data: {labid: vallab},
success: function(data){
// console.log(data);
rowid = data;
}
});
console.log(rowid);
return rowid;
});
my a.php code is below
<?php
# Fetch the variable if it's set.
$lab_id = (isset($_POST["labid"])) ? $_POST["labid"] : null;
echo $lab_id;
?>
I am getting the response back with the id, and want to use it on that page
I want to pass rowid into a PHP function so I need to get the value of rowid.
Please can you advice?
I cant seem to get my ajax response into a PHP variable
Well, the AJAX response came FROM a PHP file, right? So why don't you do whatever you need to do with the response right in that PHP file?
$.ajax({
url:'THIS IS YOUR PHP FILE',
type: 'POST',
data: {THIS IS THE DATA YOU SEND TO PHP},
success: function(data){
console.log(data); //THIS IS THE RESPONSE YOU GET BACK
}
});
You can't use it. Javascript is a scripting language which run in browser when the dom is loaded and elements are visible.
PHP is a serverside language and run on server before the page is loaded.
You need to understand the lifecycle of your application. Your php code executes once, it runs the full script from top to bottom when the page loads. At the point the script starts if can only access the post that came with the request (e.g if you clicked submit on a form then the 'action' of the form receives the post). Any number of things can happen in your script, but once it's finished the php is gone, and so is the post (in basic terms). So you no longer have any access to the php which created this page.
Ajax allows you to update a section of your page - it sends a request to your sever and runs some php code - you must understand that this is a new and separate request, so the new post submission only exists in the lifecycle of this new execution and is in now way linked to the page that has already finished loading. Now you could ask Ajax to call your original script, but that wouldn't affect your page at all because the page does not reload. What you would get is a strange looking response which you (probably) couldn't do anything useful with.
Ajax allows small specific changes to the page, so when you get your response (which I assume you get in a format you want since you don't ask about it and you have a console.log) you then need to do something with jQuery/javascript. Instead of returning rowid write a javascript function like :
function printRowId(rowid) {
$('#your html div id here').text('Row id is ' + rowid);
}
and then call it in your response:
$.ajax({
url:'a.php',
type: 'POST',
async: false,
data: {labid: vallab},
success: function(data){
// console.log(data);
rowid = data;
}
});
printRowId(rowid);
return rowid;
You can use Ajax to update your data, update your database and then reflect the changes on the current page, but you cannot use it to pass directly to the php that has already finished executing
I am doing a program in PHP (MVC) in which I need to delete a row from the database when I click on a link on the View side. So, when I click on the link, the following ajax function it is called.
var deleteCar = function(id)
{
$.ajax({
type: "POST",
url: "http://localhost/project/car/deleteCar/" + id,
success: function(response){
}
});
}
but I do not want to send any data so it is the reason why I put it as above.
Then, in the Controller side I have the following method:
public function deleteCar($id)
{
//Here I call the function to delete the Car that I send by id. It works fine.
header('Location: http://localhost/project/car');
}
If I call directly the method deleteCar on the link without Ajax the header works properly but in the same moment I use Ajax to call it, I have to refresh the page to see the content that I have modified, I mean, that the Car have been deleted.
The code works fine, just I do not want to refresh the page after AJAX function had finished.
Thanks in advance!
I am guessing the use case is to allow the app to work when the user does not have JS enabled - so they just click the links and get a non-AJAX experience. In this case you probably want to redirect ONLY if the page was requested via GET, not POST. something like
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
header('Location: http://localhost/project/car');
}
is likely what you are looking for.
You will then have to actually remove the element representing the car from the DOM in your success handler, with something like:
var deleteCar = function(id)
{
$.ajax({
type: "POST",
url: "http://localhost/project/car/deleteCar/" + id,
success: function(response){
$('#car-row-' + id).remove();
}
});
}
(that won't be it exactly, it depends how the HTML of your page is setup how exactly you will do this).
I believe the key thing to understand here is - when your PHP function has completed it has removed the car from the database, but the browser still has the same HTML it got from the page originally. Just sending an AJAX request won't change that. If you want the HTML in the browser to change to reflect the new state of the database, you will NEED to do one of two things:
Refresh the page, so the entire thing is rebuilt by PHP based on the current database state
Use javascript to change the HTML in the browser, to reflect the changes you have made to the database state.
It is wrong on so many levels but it's difficult to put in words. It's subtle.
Long story short - think about jquery.ajax as of another virtual tab of you browser.
When you make ajax-request to the server - you create new virtual tab.
You php header could affect this virtual tab and redirect it where that header defined.
But it will redirect that virtual tab, not your current tab - if that makes sense.
What are your options? On success - make redirect with pure javascript.
success: function(response){
location.href = "http://localhost/project/car";
}
This would be the basic way to solve your problem.
I am creating a web application and have the following problem.
In my application the user is working within a single page, they draw on a canvas. There is a single button called "Save". This takes the users ID and whatever they have created in the canvas and sends it to a database. This all works fine. The save function resemebles this:
$.ajax({
url: "/database/write.php",
type: "POST",
data: {
docName: name,
docData: document_Data,
docMode: "new"
},
success: function(html) {
alert("Successfully Saved NEW document");
set_Mode();
},
});
The above AJAX request does send the three values to the PHP script which then successfully creates a new document in the database, what i need to do now is change the application mode from saving a new document to editing the previously saved document. This means that when a user saves again, they will write to the same row, overwriting the previous version of the document.
When i send the data to the write.php it does write the data to the DB and the queries the database for that inserted document and retrieves its unique document ID. with that ID the application can the select that document and overwrite it. To retrieve the document ID from the query, i use the following code in write.php
write.php
$_SESSION['DOCUMENT_ID'] = $DOCUMENT_ID;
This $DOCUMENT_ID is the document ID retrieved from the SELECT query. The script then finishes and transfers control back to the main application page.
Back on the application page i try to retreive the value but it doesnt seem to work. I can retrieve $_SESSION values that were set when the user first accesses the application (id) but now values set by the write.php (DOCUMENT_ID) page. For example, below shows the function called after the AJAX request has been successful:
function set_Mode()
{
var PHPvar_01 = <?php echo($_SESSION['id']); ?>;
alert(PHPvar_01); //WORKS FINE
var PHPvar_02 = <?php echo($_SESSION['DOCUMENT_ID']); ?>;
alert(PHPvar_02); //DOES NOT WORK.
};
How should i go about sending data retrieved from the PHP query script to the application, because $_SESSION does not seem to work here.
Thanks for any feedback.
at the end of write.php :
echo json_encode(array('id'=>$_SESSION['id'], 'DOCUMENT_ID'=>$_SESSION['DOCUMENT_ID']));
in your ajax call :
success: function(data) {
data = eval('('+data+')');
alert("Successfully Saved NEW document");
set_Mode(data.id, data.DOCUMENT_ID);
},
this should do the tricks !
In your write.php, you should echo the $DOCUMENT_ID at the end of the page, and then your success function will receive that in the html argument. Then you should call set_Mode with the html variable that was passed into the success function.
You can't call set_Mode until after the page is loaded, and after you know the document ID. You are writing the document ID into the set_Mode function before you know it, in the initial page load.
Well, your PHP code gets executed only once upon the initial loading of the page. The server detects a request to your site, loads the PHP document internally, parses it and delivers it to the client.
Therefore, when the AJAX call returns, the entire PHP script is not executed again, because the user didn't request the whole page but only sent a single request to your write.php.
Your write.php script must return the $DOCUMENT_ID in some way, e.g. echo it directly, then the success handler in the jQuery AJAX call can access it via the handler's parameter (see jQuery documentation).
You can't access variables on the server when the page is already loaded in the users browsers, other than with ajax.
You need to send something back, and in PHP all you have to do is echo something, and capture it in the success function of your Ajax call.
at the end of /database/write.php, do
echo $_SESSION['DOCUMENT_ID'];
and in JS
$.ajax({
url: "/database/write.php",
type: "POST",
data: {
docName: name,
docData: document_Data,
docMode: "new"
},
success: function(data) {
alert("Successfully Saved NEW document");
set_Mode();
if (data == 'something') {
//do something with the returned DOCUMENT_ID stored in the data variable
}
},
});
I have made a simple chat application which uses long-polling approach using jquery,
function sendchat(){
// this code sends the message
$.ajax({
url: "send.php",
async: true,
data: { /* send inputbox1.value */ },
success: function(data) { }
});
}
function listen_for_message(){
// this code listens for message
$.ajax({
url: "listen.php",
async: true,
timeout:5000,
success: function(data) { // the message recievend so display that message and make new request for listening new messages
$('#display').html(data);
listen_for_message();
}
});
}
THIS SHOULD HAPPEN : after page loaded the infinite request for listen.php occurs and when user sends message, the code sends message to database via send.php.
PROBLEM is, using firebug i've found that send.php request which is performed after listen.php request, is remains pending. means the request for send message is remains pending.
The issue was because of session locking;
both send.php and listen.php files use session variables,
so session is locked in listen.php file and the other file (here send.php file) can't be served after the session frees from serving another file ( here listen.php).
How do I implement basic "Long Polling"?
the link above is a similar question that may help you.
it does not have to be on a database, it can be saved on a tmp file, but your problem is that you are choking the browser by performing too many requests, any one browser handles two requests at a time, which means you should really allow the browser to finish the first requests first then do the second one... and so on...
you do not need to do send.php and listen.php, because you can do it simply on one page both of them.
function check(){
$.ajax({
url : 'process.php',
data : {msg:'blabla'/* add data here to post e.g inputbox1.value or serialised data */}
type : 'post',
success: function (r){
if(r.message){
$('#result').append(r.message);
check();//can use a setTimeout here if you wish
}
}
});
}
process.php
<?php
$msg = $_POST['msg'];//is blabla in this case.
$arg['message'] = $msg;//or grab from db or file
//obviously you will have to put it on a database or on a file ... your choice
//so you can differentiate who sent what to whom.
echo json_encode($arg);
?>
obviously this are only guide lines, but you will exhaust your bandwidth with this method, however it will be alot better because you have only one small file that returns either 0 to 1 byte of information, or more if there is a message posted.
I have not tested this so don't rely on it to work straight away you need a bit of changes to make it work but just helps you understand how you should do it.
however if you are looking for long pulling ajax there are loads of scripts out there already made and fine tuned and have been test, bug fixed and many minds help built it, my advice is don't re-invent the wheel
Sorry for maybe incorrect title for the topic, but this is the best that I came up with.
So, I'm building admin panel for a website.
I have a page, and in some part of the page, i'd like to refresh it and load another form.
let's say add a schedule, and somewhere down on the page I'd like to have this form displayed as soon as the link is clicked.
when a user saves it, I'd like that form to disappear and and in stead of that to have a list displaying all of the schedules.
I don't want to use frames - I'm not a supporter of frames. The panel is built using PHP.
Maybe this might be achived with Ajax? If yes -> How? any link to good example or tutorial.
yes this will be solved with ajax.
Here is a code example when the page is supposed to refresh
$('#button').click(function() {
$.ajax({
url: 'path/to/script.php',
type: 'post',
dataType: 'html', // depends on what you want to return, json, xml, html?
// we'll say html for this example
data: formData, // if you are passing data to your php script, needed with a post request
success: function(data, textStatus, jqXHR) {
console.log(data); // the console will tell use if we're returning data
$('#update-menu').html(data); // update the element with the returned data
},
error: function(textStatus, errorThrown, jqXHR) {
console.log(errorThrown); // the console will tell us if there are any problems
}
}); //end ajax
return false; // prevent default button behavior
}); // end click
jQuery Ajax
http://api.jquery.com/jQuery.ajax/
Script explained.
1 - User clicks the button.
2 - Click function initiates an XHR call to the server.
3 - The url is the php script that will process the data we are sending based on the values posted.
4 - The type is a POST request, which needs data to return data.
5 - The dataType in this case will be html.
6 - The data that we are sending to the script will probably be a serialization of the form element that is assigned to the variable formData.
7 - If the XHR returns 200, then log in the console the returned data so we know what we are working with. Then place that data as html inside the selected element (#update-menu).
8 - If there is an error have the console log the error for us.
9 - Return false to prevent default behavior.
10 - All done.