My ajax code is
function senddata()
{
var ajaxRequest; // The variable that makes Ajax possible!
// Create a function that will receive data sent from the server
ajaxRequest.onreadystatechange = function()
{
if(ajaxRequest.readyState == 4)
{
document.getElementById("showdata").innerHTML=ajaxRequest.responseText;
}
}
ajaxRequest.open("GET", Handler.php?key=" + value, true);
ajaxRequest.send(null);
}
I have huge amount of data that gets retrieved through ajax. Now when i call this function, it takes much time to show data. I want here is that as the data gets retrived, it should be displayed on the screen. No need to show whole retrieved data only when everything is fetched but display data as it gets fetched.
You're going to want to approach this with the same style of thinking as if you were implementing a pagination system.
I cannot see your Handler.php code, so it might make things difficult as we need to edit things in there.
Make Handler.php accept limit and offset or page query var(s)
Add the appropriate code in your PHP to handle that (and the case where none are provided, don't just sent everything! default limit to 10 and offset to 0.)
Functionalize your ajax request and make it paginate:
function getdata(limit, offset)
{
limit = limit || 10;
offset = offset || 0;
var ajaxRequest; // The variable that makes Ajax possible!
// Create a function that will receive data sent from the server
ajaxRequest.onreadystatechange = function()
{
if(ajaxRequest.readyState == 4)
{
document.getElementById("showdata").innerHTML=ajaxRequest.responseText;
// make Handler.php send 'end' when no results have been returned
if (ajaxRequest.responseText && ajaxRequest.responseText != 'end') {
getdata(limit, offset + limit);
}
}
}
ajaxRequest.open("GET", Handler.php?key=" + value + '&limit=' + limit +
'&offset=' + offset, true);
ajaxRequest.send(null);
}
getData();
Just make sure Handler.php sends end when there is no more data.
Related
Good morning,
I have script that updates voluminous data (for exemple 3000Lines) and I have to show to user progress of db updates on progress bar or just the number of lines affected.
I'm working on PHP codeigniter and AJAX
I had an idea to use session codeigniter to store modified variable (incrementation) on the session value on each Loop and call function that give me the session variable as JSON array, but the problem is that the session wouldn't change itself after first update (for exemple: starting with 0 and modified to 20, after that all process on 20)
I don't know how to get better solution to do it. If you can help me it will be really cool.
Thank's to all
PHP won't output anything until the script has fully completed, but you can change that:
ob_implicit_flush(true);
for ($i = 0; $i < ob_get_level(); $i++) {
ob_end_clean();
}
Put this in your PHP script before you start processing your data. As you process parts of your data, output something to tell the AJAX request the progress; for example:
PHP:
$completed_updates = 0;
$last_echoed_progress = 0;
$progress_echo_interval_seconds = 2;
while ($completed_updates < $amount_of_db_updates_to_do) {
do_db_update();
$completed_updates++;
if ($last_echoed_progress + $progress_echo_interval_seconds < time()) {
echo ($completed_updates / $amount_of_db_updates_to_do) * 100;
$last_echoed_progress = time();
}
}
jQuery's .ajax also (by default) won't call the success function with the data until all the data has been received (i.e. script ended), so create a custom XHR object with an event listener that receives the data while the script is still running:
JS:
var last_response_length = 0;
$.ajax({
... // All your other settings
xhr: function() {
var xhr = new XMLHttpRequest(); // Create a custom XHR object
xhr.onprogress = function(data) {
var response = data.currentTarget.response, // Get the output
progress = response.slice(last_response_length) | 0; // Remove old output
$( '#progress-bar' ).val(progress); // Update the progress bar
last_response_length = response.length; // Track where the old data is (so they can be removed when new data is received)
};
return xhr; // IMPORTANT! Return the custom XHR for .ajax to use
},
success: function(response) {
$( '#progress-bar' ).val(100); // All done!
}
});
Obviously modify the code to suit your needs, and experiment a little. Keep in mind that PHP has an execution time limit of 30 seconds by default, so you may need to change this inside your script:
set_time_limit(0);
This allows your script (and only that one) to run without time limits. Put it at the very top. Use caution!
When Method of the senderform is POST, everything works fine. However, as soon as I change the method to GET, I don't receive anything on the server.
function ajaxSubmit(destinationElement, senderform) {
var xmlreq = new XMLHttpRequest();
var params = new FormData(senderform);
xmlreq.open(senderform.method, senderform.action, true);
if (/\/content\.php$/.test(senderform.action))
xmlreq.onreadystatechange = receiveTable;
else xmlreq.onreadystatechange = receiveText;
xmlreq.send(params);
}
I know that I could manually append key-value pairs at the end of Action address, but the problem is that I don't know which form is going to be passed with what fields.
I would prefer native javaScript if possible.
How can I send a GET request using XMLHttpRequest with key-value pairs from senderform which points to form Element (the same way as it already works for POST requests)?
First parameter is a reference to submit button, or form element itself. Second is callback function for XMLHttpRequest.
var ajaxSubmit = function(sender, callback) {
var xmlreq = new XMLHttpRequest(), params;
// look around for the sender form and key-value params
if (sender.form !== undefined)
{
params = new FormData(sender.form);
params.append(sender.name, sender.value);
sender = sender.form;
}
else params = new FormData(sender);
var actAddress = sender.action;
// append the params to the address in action attribute
if (sender.method == 'get')
{
var firstRun = true;
for (var key of params.keys())
{
if (firstRun)
{
actAddress += '?';
firstRun = false;
}
else actAddress += '&';
actAddress += key + "=" + params.get(key);
}
}
xmlreq.open(sender.method, actAddress, true);
xmlreq.onreadystatechange = callback;
if (sender.method == 'get')
xmlreq.send();
else xmlreq.send(params);
}
Therefore you can use it as
<form onsubmit="ajaxSubmit(this,callbackFx)" >
<!-- or -->
<input onclick="ajaxSubmit(this,callbackFx)" type="submit" name="" value=""/>
</form>
Are you sure the problem is not the PHP script? I see no reference that https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#send() with FormData needs POST to work, but if the PHP script takes the info from $POST or something (My PHP is rusty), the behavior would be different.
Since you can't create a useable body in a GET request (see below), then the other option is to use params in the url.
function buildGetUrlParams(baseUrl, paramsObj) {
var builtUrl = baseUrl + "?";
Object.keys(paramsObj).forEach(function(key) {
builtUrl += key + "=" + paramsObj[key] + "&";
});
return builtUrl.substr(0, builtUrl.length - 1);
}
document.getElementById('finalUrl').innerText = buildGetUrlParams('http://test.url.com', { name:'James', occupation:'web design' });
<div id="finalUrl"></div>
An HTTP GET request can contain a body, but there is no semantic meaning to that body. Which means, in simple terms, that a server doesn't have any reason to, nor have any knowledge of how, to process the body of a GET request. If it's possible to write a server that could do this, it would be bad practice as per the HTTP/1.1 specs:
if the request method does not include defined semantics for an entity-body, then the message-body SHOULD be ignored when handling the request.
And that's basically why it's not working. If you want to send any sort of data that the server is able to respond to, then you'll need to use a different HTTP method.
This answer also explains this issue.
I am working on a project that uses a function I called AjaxRequest which handles all AJAX requests I make. I have no problems in making the request however getting the request back is the issue and placing it where I want it on my page is becoming stressful.
HTML BIT
<body onLoad="calling();">
<div id="status">Status: </div>
</body>
JAVASCRIPT BIT
function calling() {
var answer = ajaxRequest("testing", "test.php", "test=test");
document.getElementById("status").innerHTML += answer[1];
document.getElementById("status").innerHTML += " " + answer[3];
}
function ajaxRequest(app, location, credentials) {
var extras = "";
if(credentials === "" || credentials) {
extras = "&" + credentials;
}
var ajax = ajaxObj("POST", location);
ajax.onreadystatechange = function() {
if(ajaxReturn(ajax) == true) {
var obj = JSON.parse(ajax.responseText);
var arrayObj = [];
for(var i in obj) { arrayObj.push([i, obj[i]]); }
return arrayObj;
}
}
ajax.send("app=" + app + extras);
}
there are two other functions running: ajaxObj and ajaxReturn but I excluded those because they is not the problem. Furthermore, I am trying to make ajaxRequest an efficient function that could be used by more than one application without having to rewrite all the code in more than one location. All error handling acquires before the actual use of ajaxRequest.
PHP BIT
<?php
if($_POST['app'] == "testing") {
$hey = array('success' => 1, 'message' => 'Successful');
echo json_encode($hey);
exit();
}
?>
I'm using calling as a javascript function that does all error handling, this is just basic for the whole of my project however I try to get the JSON from php and convert it to array and the issue is returning the array into calling. I try to display the information on the page yet nothing works.
I am not looking to use any JQuery for my project so I would like to exclude the use of it for this piece of code.
If you want, you could set the header before sending back the json.
header('Content-Type: application/json');
Usually you don't need it, but it will tell your javascript that it's json, and the array will be transform in a javascript object. It work with Jquery, but I assume it'll work without too
I'm having a great deal of difficulty with this - I seem to be going in circles.
What I'm trying to do is POST data to a web service from a javascript on a client.
in the examples below, valFname, valLname, valPhone, and valZip all have valid string values:
function checkOffers(){
// data collection from loaded form...
var postData = "'FirstName':'" + valFname ;
postData +="','LastName':'" + valLname ;
postData +="','PhoneNumber':'" + valPhone ;
postData += "','Zipcode':'" + valZip+"'";
initialize(postData);
}
function initialize(postData) {
//var postMsg = createSoapHeader(msg);
var url = "https://server.company.com:9999/analytics/webservices/webservice.asmx/SamplePriorityOfferList";
request.open("POST", url, false)
request.onreadystatechange = function(){
if(this.readyState===4){
//request is complete. handle it
processData;
}
};
request.send(postData);
}
function processData(){
response = request.responseXML.xml;
alert("Returned Data:" + response);
}
I am calling the checkOffers function on the PageLoad event - I want the web service to fire without having to click a button, link, etc.
I'm getting nulls back from my request, but should be getting data.
Any comments, tips, or suggestions are greatly appreciated.
This line:
if(this.readyState===4){
should be:
if(this.readyState==4){
That should at least get you seeing the alert.
OK, so I cannot seem to be able to change the global variable of systemPath after it goes through the ajax.It will work inside of ajax, but I need that updated variable outside of ajax. basically I'm trying to create an array of paths from xml and use them to locate other xml files that I can generate a table from.
Does anyone know what's going on here? Does ajax run before the variable is set and that is why I get an array length of 0 after the ajax?
var systemPath = new Array();
var techDigestArr = new Array();
var addToArray = function(thisarray, toPush){
thisarray.push(toPush);
}
$.ajax({
url: fullPath+"technical/systems/systems.xml",
dataType: ($.browser.msie) ? "text" : "xml",
success: function(data){
var xml;
if (typeof data == "string") {
xml = new ActiveXObject("Microsoft.XMLDOM");
xml.async = false;
xml.loadXML(data);
} else {
xml = data;
}
$(xml).find("system").each(function(){
var urlString = fullPath + "technical/system_" + $(this).attr("id") + "/" + $(this).attr("id") + "tech-digest.xml <br />";
//alert(urlString);
$("#td-articles").append(systemPath.length + urlString);
addToArray(systemPath,urlString);
//systemPath.push(urlString);
});
$("#msg-output").append("total - " +systemPath.length);//Returns 48
},//END SUCCSESS
error: function(){
alert("Sorry - ");
history.go(-1);
}
});//END AJAX CALL
$(document).ready(function(){
//$("#msg-output").append("total - " + systemPath.length); Returns 0
});
The ajax is ran asynchronously. Things execute in this order in your code.
stuff before $.ajax()
$.ajax() initiates an ajax call (while waiting for the response it continues to run the rest of the code)
stuff after $.ajax()
success callback
Note that depending on how fast the call is 3 and 4 might occur in reverse order (not the case here)
So when $(document).ready() is executed the ajax call might not have returned yet, so the code in the success callback didn't have a chance to execute. If you are lucky and have a fast connection than maybe the response will come before document ready, but it's unlikely.
Just so you can see that the global variable gets updated you can set a timeout:
$(document).ready(function(){
setTimeout(function(){
$("#msg-output").append("total - " + systemPath.length);
//if the delay set below is more than the time between the ajax request and the server response than this will print the correct value
},2000);
});