jquery ajax progress with custom calculation - php

I need advice on my ajax progress bar while executing a long PHP script treating pictures.
I know there are plenty of questions on stackoverflow already like
Show progress for long running PHP script
or JQuery ajax progress via xhr
or update progress bar using ajax request seconds)
Most of the examples I see are using the file size to calculate the progress.
But in my case I would like to calculate percentage based on images_treated / total_images.
So I still can't make this work as I want.
In JS bellow I commented the not working progress function I took from another question and dataType: 'json' for tests but I would prefer if I can still use a JSON return.
Questions
The console.log() will only log once - when the full script is done. Am I doing it wrong?
What should I write to replace the comment?
in some answers, the PHP headers are set to header('Content-Type: application/octet-stream'); is it mandatory or just nicer?
Javascript:
$.ajax(
{
type: 'GET',
// dataType: 'json',
url: formAction,
data: 'addImagesToArticle',
cache: false,
xhr: function()
{
var xhr = new window.XMLHttpRequest();
// Download progress.
xhr.addEventListener("progress", function(e)
{
console.log(e);
// I saw this piece of code from another question it is supposed to work... Maybe my PHP?
/*var lines = e.currentTarget.response.split("\n");
var progress = lines.length ? lines[lines.length-1] : 0;
$('#progress').text(progress);*/
}, false);
return xhr;
}
});
My PHP is quite big so I just explain quickly: in the loop on pics I have variables $images_treated and $total_images. After the loop, a summary is returned to JS via JSON in an object like {error: bool, message: string, ...} so if there is a way to make the progress work without echoing but setting a JSON variable that would be perfect!
Thank you for your help!
[EDIT] to add context details.
I want to use this in an admin side, in an article edition with a WYSIWYG, I have dropzone taking care of my multiple images uploads.
then I see the preview of images while each image is put in temp folder on server. I can then remove some images if needed and once all images are definitive, i click a button that will process them for resizing 2 sizes and inject figure tags with img in the article WYSIWYG editor.

Waw I found a solution!
I am happy to discover that new thing I did not know about PHP and share with people who also don't know (in step 3 bellow)!
#riccardo was right talking about socket - which I don't know so well - but I did not need to go that far.
So I had multiple things to solve in my case before being able to get closer of my goal.
not using xhr.addEventListener("progress"... but a second ajax call in a timer: it will also be lighter-weight in resource consumption.
rather than using a timer like setInterval or setTimeout - as requests are async it may come in unwanted order - use a recursive call in callback of first call like:
function trackProgress()
{
$.getJSON('create-a-new-page.html', 'ajaxTrackProgress=1', function(response)
{
var progress = response.progress;
$('#progress').text(progress);
if (progress < 100) trackProgress();
});
}
then realize that my second script call is delayed by first script still running? yes. So the key here is session_write_close()!
I could dig in this way thanks to this good post:
https://stackoverflow.com/a/1430921/2012407
and I posted a very simple example here to reply to another question: https://stackoverflow.com/a/38334673/2012407
Thank you for all your help in comments guys, it led me to this solution. ;)

Related

Change php property based on browser width

Okay, so i have searched for hours to no avail (most likely because i am not phrasing the question correctly).
Anyway, i would like to change the "list" property of the following script to "big" depending on the size of the client window.
SCRIPT
<div id="calWrap" class="comType">
?php
$calendar_type='list'; //Possible value: mini, big, list
include("3c-events/calendar.php");
?
</div>
Any help would be greatly appreciated, i have come across a few posts with scripts i thought would do the trick; however, either through poor implementation or some other reason they failed.
Thanks in advance….
I would suggest getting the size of the viewport with javascript and then sending them to the php on load. Then write some code to check the size and set "calender_type" accordingly.
var viewportWidth = $(window).width();
var viewportHeight = $(window).height();
send the code to the php page with ajax
$.ajax({url: "page.php", type: "post", data: {"size": size}})
you would then return the calender at its proper size. and place it into a designated container.
.done(function(html) {
$('#someContainer').html(html);
}(;

Refresh PHP functions with JavaScript

i need a a script that will refresh the functions:
$ping, $ms
every 30 seconds, with a timer shown,
i basicly got this script:
window.onload=function(){
var timer = {
interval: null,
seconds: 30,
start: function () {
var self = this,
el = document.getElementById('time-to-update');
el.innerText = this.seconds;
this.interval = setInterval(function () {
self.seconds--;
if (self.seconds == 0)
window.location.reload();
el.innerText = self.seconds;
}, 1000);
},
stop: function () {
window.clearInterval(this.interval)
}
}
timer.start();
}
but it refreshes the whole page, not the functions i want it to refresh, so, any help will be appriciated, thanks!
EDIT:
I forgot to mention that the script has to loop infinatly
This here reloads the whole page:
window.location.reload();
Now what you seem to want to do is reload portions of the page, those portions having been generated by php functions. Unfortunately php is server side so that means you cant get the client browser to run php. Your server runs the php to generate stuff that browsers can understand. In a web browser open a page you made using php and choose to view source and you'll see what I mean.
Here's what you'll need to do:
Make your two functions ping and ms accessable via ajax
Instead of window.location.reload() do a call to jQuery.ajax. on success write to your page
Here's what I think would be the ideal way of dealing with this... I haven't seen the php side of your problem but anyway:
make a file called ping.php and put all your ping function code in there. ditto for ms
in your original php file that called those functions, make a div at each point where you wanted a function call. Give them appropriate ids. Eg: "ping_contents" and "ms_contents"
You can populate these with some initial data if you want.
In your js put in something like this:
jQuery.ajax(
{
url : url_of_ping_function,
data : {anything you need},
type : 'POST', //or 'GET'
dataType: 'html',
success : function(data)
{
document.getElementById("ping_contents").innerHTML = data;
}
});
do another one for the other function
What you want is AJAX, Asynchronous JavaScript and XML
You can use jQuery for that.
I can put an example here, but there is a lot of information to be found on the internet. In the past I wrote my own AJAX code, but since I started using jQuery, it's all a lot easier. Look at the jQuery link I provided. There is some usefull information. This example code might be the easiest to explain.
$.ajax({
url: "test.php"
}).done(function() {
alert("done");
});
A some moment, for example on a click on a button, the file test.php is executed. When it's done, a alert box with the text "done" is shown. That's the basic.

How to display a 'live' count of total files uploaded?

I am looking to display the total number of files in a database. To clarify, say I had a website where people could upload pictures of their cars, and I wanted to display a live number of how many pictures there are, what would be the best way to do this? Javascript, php? A mix? I envision a div with a number saying "Total Pictures: x" and where x would be whatever the live total is. I plan on using MySQL to store all the data on the website. Is this even recommended to have something communicate with the server this much? Is there a name for displaying a live number? Thanks!
If you are thinking to use the AngularJS way, you could create a Poller service which polls every second (assuming your /counter.php returns json):
app.factory('Poller', function($http, $timeout) {
var data = { response: {}};
var poller = function() {
$http.get('/counter.php').then(function(r) {
data.response = r.data;
$timeout(poller, 1000);
});
};
poller();
return {
data: data
};
});
Then your controller:
app.controller('CounterCtrl', function(Poller, $scope){
$scope.counter = Poller.data;
});
And finally in your view:
{{counter.response}}
You can read more about $http
Set up a PHP script that queries the database and returns the total file upload count. After that, you can use JavaScript on the page to periodically call the server in a specified interval of time and fetch the count data from your PHP script. Using jQuery and GET, you can do something like this:
jQuery(function($){
setInterval(function(){
$.get( '/counter.php', function(fileUploadCount){
$('#counter').html( fileUploadCount );
});
},20000); // 20 seconds
});
In your HTML:
<p><span id='counter'>xx</span> files have been uploaded so far!</p>
Hope this helps!
How live do you want it to be? Just whenever someone updates the site it's going to have the new value or do you actually want it to update in near real-time?
If it's the latter you have to use Javascript against some kind of API that returns the amount of files in the database. I can't help you with that bit since you are using PHP, but it shouldn't be too hard. Just return some JSON looking something like
{ fileCount: 45020 }
Client-side you have a few options. You have the different javascript frameworks like AngularJS and EmberJS (and many more), as well as just 'plain old' javascript and frameworks like jQuery
The keyword is really AJAX, even if that is just a sort of buzzword for using javascript to make websites dynamic.
I am a fan of using AngularJS because it's easy, but I'll try to give you some pointers for using jQuery first. Note that I have not used jQuery in years now.
The jQuery way
jQuery has a function called jQuery.getJSON(), and according to the documentation you can use that function something like this:
// Assign handlers immediately after making the request,
// and remember the jqxhr object for this request
var jqxhr = $.getJSON( "http://example.com/api/fileCount.json")
.done(function(data) { console.log(data) })
.fail(function() { console.log( "error" ); })
.always(function() { console.log( "complete" ); });
So this means we can call an endpoint and fetch some data using jQuery.
Here is a link to a tutorial about the basics of jQuery by the way.
jQuery makes us able to do things like this:
<div id="divTest1"></div>
<script type="text/javascript">
$("#divTest1").text("Hello, world!");
</script>
When that is executed the div with id "divTest1" will contain the text 'Hello, world!'.
That sounds like something we could use here!
Javascript also has this really nice function called setTimeout(), which allows us to make it call a function later.
This describes how to use jQuery with setTimeout()
As you can see it also shows us jQuery.documentReady(), which is an event that fires when the website is finished loading, so it is a good place to put code we want executed.
The example below shows how to use jQuery to hide a div with id=div after 3 seconds.
jQuery(document).ready(function () {
setTimeout( "jQuery('#div').hide();",3000 ); //hide a div after 3 seconds
});
Combining these things you should be able to make a repeating call that fetches data from your server and then updates a div or another element with the data you have fetched.
Just create a function which uses jQuery.getJSON() to fetch data, and then at the bottom of that add a setTimeout call to run itself in X seconds (however often you want it to update).
In jQuery.documentReady() you call that function the first time the document loads.
And in the .done() bit of the getJSON() call you add the data you got from the server to your div with whatever html you want. I showed you how to use $("#divTest1").text(), but there is also a .html() which acts the same but you should use it to add html to a element.
The angular way would be to use AngularJS's $http to do the same thing, but I wouldn't recommend learning AngularJS until you have a bit of a better grasp on Javascript.
When you do though, I highly recommend it. It's a much better approach than using jQuery.
You can read about AngularJS here
I hope this helps!

visual traceroute similar "yougetsignal.com", how to update div on demand/periodically

this is my first question in a forum ever i think ;-).
I will try to be as clear as possible with the question.
I´m trying to build a visual traceroute similar to that on yougetsignal.com by kirk ouimet.
It is actually working already using bash (traceroute,ping,host,) php/javascript, but I´m having some trouble with Javascript/AJAX.
Kirk updates the traced host-list periodically or via some kind of ajax-interrupt on the right side of the trace. I only know how to do it in one pass with one single Javascript xmlhttp-call and then echo a table into a standard w3school-livesearch-DIV.
http://www.yougetsignal.com/tools/visual-tracert/
I also don´t know if he does the traceroute with a cmd-line-tool like linux´s "traceroute".
Mine is working fine by first tracerouting, then doing reverse-lookup using "host" and then
pinging all hosts in the list again to get the rrt.
Is there any way to poll a txt-file (the traces) and then echo the output on demand to
a DIV?
I´m grateful for any hint.
Stefan
p.s.: the google-maps plotting works fine, it´s about the process of updating the traced-hosts
on demand for users (and me) to enjoy.
What you can do by using jQuery for ajax calls:
setInterval(function () {
$('#yourdiv').load('http://domain.com/yourfile');
}, 30000);
This code will load pregenerated html content to a specified div container every 30s. If you don't what to load a temporary generated html/php content, you can build an API and then add the data comming back dynamically on the DOM every time.
setInterval(function () {
$.getJSON('yourAPIUrl', function (data) {
$.each(data, function (item) {
// do something with the retrieved data, add it to the DOM for example
}
});
}, 30000);

Ajax post works in chrome but no data recieved on server with ie and firefox

I need to retrieve and process a image (png) generated by a flash application. When a user clicks a link I :
var dataImgBase64 = document.getElementById("flashApp").getThumbnail();
So the flash app sends me a image in base64. Then I:
var params = 'b=' + encodeURIComponent(dataImgBase64);
$.ajax({
type: "POST",
url: "arrival.php",
data: params,
success: function (msg) {
$("#ppp").html(msg);
}
});
heres is arrival.php:
$data = $_POST['b'];
echo strlen($data);
In chrome I get the expected size of around 900k but in ie and firefox I get 0. I checked with firebug and I do send the post data but it cuts in the middle with a message that firebug as reached its post size limit.
Is it possible to do what I want the way I want? If not what else could I do? I tried playing around with some settings like:
processDataBoolean: false,
contentType: "application/x-www-form-urlencoded",
Nothing worked.
editL the server is a shared hosting account on linux.
Why do you do it with ajax? Can't you just insert the specfied path in the src attribute in a img tag?
Since no one can help me I helped myself! After testing I found out I can send in a single ajax request 1000000 '1's but it will fail on all browsers for 1000001 '1's.
I have a hard time finding information because everywhere I look on the net its talks about a file upload dialog (and I got my data from a flash pluguin on the webpage very different context.
So as of now my solution is to split the data and send it thru many ajax connections.
I'll leave the question open in case someone passes by and has a better answer.

Categories