What I am trying to do is is use jQuery/Ajax to make a request to a PHP script and return a status update each time the foreach loop completes. I want to use the output to make a progress bar.
The problem I am having is the jQuery will only update the page once the whole script has completed. Is there a way to force either the jQuery or PHP to output on every loop and not just dump all of it on success function.
jQuery(document).ready(function($) {
$(document).on('click','#fetch-snowfall-data a',function () {
$(this).text('Fetching Snowfall Data...');
$.ajax({
type: "GET",
async: true,
url: "url.php",
data:{},
dataType: "html",
success: function(response){
$("#response_container").append(response);
$('#fetch-snowfall-data a').text('Fetch Snowfall Data');
}
});
return false;
});
});
PHP
foreach ( $results['resorts'] as $resort ) {
//Do all the things here
$count++;
echo $count .'/'. $results['total_rows'];
}
Thanks everyone for all your help. I eventually managed to get this all working properly and will share exactly how I did it for anyone else's future benefit.
There are 3 files that are required - The page you are loading from, the processing script and the listening script.
You will need to know how many rows you are going to process for everything to work. I load mine from php variable $results['total_rows']; in loading.php
Loading.php
jQuery(document).ready(function($) {
setTimeout(getProgress,1000);
$(document).on('click','#fetch-snowfall-data a',function () {
$(this).text('Fetching Snowfall Data...');
$.ajax({
url: 'process.php',
success: function(data) {
$("#response_container2").append(data);
}
});
setTimeout(getProgress,3000);
return false;
});
function getProgress(){
$.ajax({
url: 'listen.php',
success: function(data) {
if(data<=<?php echo $results['total_rows']; ?> && data>=1){
console.log(data);
$('#response_container').html('<div id="progress"><div class="progress-bar" role="progressbar" style="width:'+ (data / <?php echo $results["total_rows"] ?>)*100 +'%">'+ data + '/' +<?php echo $results["total_rows"] ?> +'</div></div>');
setTimeout(getProgress,1000);
console.log('Repeat');
} else {
$('#fetch-snowfall-data a').text('Fetch Snowfall Data');
console.log('End');
}
}
});
}
});
Process.php
foreach ( $results['resorts'] as $resort ) {
//Do all the things here you want to.
$count++;
session_start();
$_SESSION['progress'] = $count;
$_SESSION['total'] = $results['total_rows'];
session_write_close();
sleep(1);
}
unset($_SESSION['progress']);
Listen.php
session_start();
echo (!empty($_SESSION['progress']) ? $_SESSION['progress'] : '');
if (!empty($_SESSION['progress']) && $_SESSION['progress'] >= $_SESSION['total']) {
unset($_SESSION['progress']);
}
Some CSS for the progress bar
#progress {
height: 20px;
margin-bottom: 20px;
/* overflow: hidden; */
background-color: #f5f5f5;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.1);
box-shadow: inset 0 1px 2px rgba(0,0,0,.1);
}
.progress-bar {
float: left;
width: 0;
height: 100%;
font-size: 12px;
line-height: 20px;
color: #fff;
text-align: center;
background-color: #337ab7;
-webkit-box-shadow: inset 0 -1px 0 rgba(0,0,0,.15);
box-shadow: inset 0 -1px 0 rgba(0,0,0,.15);
-webkit-transition: width .6s ease;
-o-transition: width .6s ease;
transition: width .6s ease;
}
As suggested by adeneo, I dont think you can return partial content. I tried to research on this before with no avail. However, if anyone can correct me, i'll be very appreciative.
The end result for me is to do recursive ajax.
javascript
var data = '';
$(document).on('click','#fetch-snowfall-data a',function () {
ajaxCall(0);
});
function ajaxCall(num) {
$.ajax({
type: "POST",
async: true,
url: "url.php",
data: num,
dataType: "json",
xhr:function(){
//progress bar information here.
},
success: function(response) {
$("#response_container").append(response['data']);
if (response['check'] === 'next') {
var nextNum = num +1;
data += response['data'];
ajaxCall(nextNum); //call itself for the next iteration
}else if (response['check'] === 'done'){
data = response['data'];
//do stuff with the data here.
}else if (response['check'] === 'error') {
return response['data'];
}
},
error:function(xhr, status,error){
//error information here
}
});
}
For PHP:
Just make sure you output stuff in json with two information. Json.check: to see if you want to move into the next iteration, finish and output data, or report error. Json.data to output whatever data it needs. What you need to do is output each report at a time without foreach loop
--edit--
I found some topic on streaming for php
http://www.sitepoint.com/php-streaming-output-buffering-explained/
Best approach for (cross-platform) real-time data streaming in PHP?
Related
I'm using Ajax newsletter submit in Laravel.
I want to change the mail icon into checked icon if the data passed successfully.
Ajax:
success: function (json) {
container.find('.newsletter-notification').addClass('success').html("You've successfully subscribed to Newsletter.");
$('.newsletter-block .newsletter-content .content button:before').css('content', '\e080');
},
css
.newsletter-block .newsletter-content .content button:before
{
content: "\e01f";
font-family: 'simple-line-icons';
}
How can I change content: "\e01f" into content: "\e080"
Try This
CSS
.newsletter-block .newsletter-content .content button:before
{
content: "\e01f";
font-family: 'simple-line-icons';
}
.newsletter-block .newsletter-content .content button.success:before
{
content: "\e080";
font-family: 'simple-line-icons';
}
Javascript
success: function (json) {
var = newsLetterBtn = $('.newsletter-block .newsletter-content .content button');
container.find('.newsletter-notification').addClass('success').html("You've successfully subscribed to Newsletter.");
newsLetterBtn.addClass('success');
},
I'm having an image map with ajax hover to retrieve information from database table major_occurrence. But it's seems not working at all with the ajax call.
The hover is clickable so that it will redirect to another doRpMap.php showing the occurrence details.
Please advise on this matter. Thanks. *Pardon me being a programming newbie.
Am I doing the correct way for:
the variable to call back getOccCount.php $result in my Main Page?
how to insert the ajax call() into my <span>?
getOccCount.php
<?php
$location_id = $_GET['location_id'];
$query = "SELECT COUNT(occurrence_id) FROM major_occurrence WHERE '$location_id' = location_id GROUP BY location_id";
$result = mysqli_query($link, $query) or die(mysqli_error($link));
$array = mysql_fetch_row($result); //fetch result
echo json_encode($array);
?>
Main page
<style type="text/css">
#map {
margin:0;
padding:0;
width:950px;
height:1211px;
background:url(images/Campus-Map.jpg);
background-size: 950px 1211px;
font-family:arial, helvetica, sans-serif;
font-size:8pt;
}
#map li {
margin:0;
padding:0;
list-style:none;
}
#map li a {
position:absolute;
display:block;
background:url(blank.gif);
text-decoration:none;
color:#000;
}
#map li a span { display:none; }
#map li a:hover span {
position:relative;
display:block;
width:200px;
left:20px;
top:20px;
border:1px solid #000;
background:#fff;
padding:5px;
filter:alpha(opacity=80);
opacity:0.8;
}
#map a.rpc{
top: 1060px ;
left: 585px;
width: 78px;
height: 65px;
}
</style>
<body>
<script>
$(document).ready(function() {
$('#map span').hover(function () {
var $t = $(this);
var location_id = $t.attr("location_id");
$.ajax({
url: 'getOccCount.php',
data: "{location_id: location_id}",
dataType: 'json',
method: 'GET',
success: function (result) {
$t.html('Total Number of Occurrence: ' + result[0]);
}
}
});
});
</script>
<ul id="map">
<li><a class="rpc" href="doRPMap.php?location_id=1"><span location_id="1"><b>RPC</b></span></a></li>
</ul>
</body>
A complete solution will require some work. Let me give you a few ideas. I apologize for having trouble with formatting ... the {} function here doesn't seem to work properly for me.
As you stated, you want to query the number of incidents for a given location. In your getOccCount.php I don't see any mechanism of passing a location id. It appears that the query always returns ALL occurrences. You probably want to add a line similar to
$location_id = #$_REQUEST['location_id'];
and use that value in a WHERE clause in your query.
The <span> you have in your html doesn't have a location_id attribute:
<span><b>RPC</b></span>
So the line where you try to retrieve that attribute will not find anything:
var location_id = $(this).attr("location_id");
You're doing the same ajax call twice, in two different ways. The whole block starting with $.ajax({ makes a call to getOccCount.php, however, I don't see you doing anything with the data passed to the success callback.
Then again in the success callback function you write $.get("getOccCount.php", ... which essentially does the same call again. This time you're trying to pass the location_id parameter, which we already know is not looked at in getOccCount.php.
Where you are trying to store the result back in the span that the user hovered over you use $('#map>span') as a selector which will store the result in ALL spans.
So, a start to your solution could look like this:
<body>
<script>
$(document).ready(function() {
$('#map span').hover(function () {
var $t = $(this);
var location_id = $t.attr("location_id");
$.ajax({
url: 'getOccCount.php',
data: "{location_id: location_id}",
dataType: 'json',
method: 'GET',
success: function (result) {
$t.html('Total Number of Occurrence: ' + result[0]);
}
});
});
});
</script>
<ul id="map">
<li><a class="rpc" href="doRPMap.php?locID=1"><span location_id="1"><b>RPC</b></span></a></li>
</ul>
</body>
Like I said, a full solution will require more work, especially on passing the location_id into your query. Hope that my ideas will help make progress.
I'm trying to create a drag & drop calendar(Fullcalendar) and saving the new or edited items in a MySQL database.
But I'm having 2 problems at the moment.
First:
I can't drag & drop more then 1 item in the month view:
http://snag.gy/SF9wI.jpg
But if I drag a new one in the Week view ,It works : http://snag.gy/0tW2m.jpg
and if I go back to the Month view the ones I just created in the Week view are still there.
Second:
I'm new in ajax,jquery and I don't really know how to use $_post, so I can save my records in my MySQL database. I tried a few guides but no success.
MySQL database:
name: tblEvent
idEvent INT auto_increment PRIMARY KEY
fiTask INT
fiUser INT
dtStart DATETIME
dtEnd DATETIME
dtUrl VARCHAR(255)
dtAllDay TINYINT(1)
index.php:
<?php
include_once './Includes/functions.php';
?>
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<link href='../fullcalendar.css' rel='stylesheet' />
<link href='../fullcalendar.print.css' rel='stylesheet' media='print' />
<script src='../lib/moment.min.js'></script>
<script src='../lib/jquery.min.js'></script>
<script src='../lib/jquery-ui.custom.min.js'></script>
<script src='../fullcalendar.js'></script>
<script src='../lang/de.js'></script>
<script>
$(document).ready(function () {
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
var h = {};
/* initialize the external events
-----------------------------------------------------------------*/
$('#external-events .fc-event').each(function () {
// store data so the calendar knows to render an event upon drop
$(this).data('event', {
title: $.trim($(this).text()), // use the element's text as the event title
stick: true // maintain when user navigates (see docs on the renderEvent method)
});
// make the event draggable using jQuery UI
$(this).draggable({
zIndex: 999,
revert: true, // will cause the event to go back to its
revertDuration: 0 // original position after the drag
});
});
/* initialize the calendar
-----------------------------------------------------------------*/
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
slotEventOverlap: false,
eventLimit: true,
droppable: true, // this allows things to be dropped onto the calendar
events: "./event.php",
// Convert the allDay from string to boolean
eventRender: function (event, element, view) {
if (event.allDay === 'true') {
event.allDay = true;
} else {
event.allDay = false;
}
},
selectable: true,
selectHelper: true,
select: function (start, end, allDay) {
var title = prompt('Event Title:');
var url = prompt('Type Event url, if exits:');
var eventData;
if (title) {
var start = $.fullCalendar.formatDate(start, "yyyy-MM-dd HH:mm:ss");
var end = $.fullCalendar.formatDate(end, "yyyy-MM-dd HH:mm:ss");
$.ajax({
url: './add_event.php',
data: 'title=' + title + '&start=' + start + '&end=' + end + '&url=' + url,
type: "POST",
success: function (json) {
alert('Added Successfully');
}
});
$('#calendar').fullCalendar('renderEvent',
{
title: title,
start: start,
end: end,
allDay: allDay
},
true // make the event "stick"
);
}
$('#calendar').fullCalendar('unselect');
},
editable: true,
/*eventDrop: function (event, delta) {
var start = $.fullCalendar.formatDate(event.start, "yyyy-MM-dd HH:mm:ss");
var end = $.fullCalendar.formatDate(event.end, "yyyy-MM-dd HH:mm:ss");
$.ajax({
url: './update_events.php',
data: 'title=' + event.title + '&start=' + start + '&end=' + end + '&id=' + event.id,
type: "POST",
success: function (json) {
alert("Updated Successfully");
}
});
}*/
});
});
</script>
<style>
body {
margin-top: 40px;
text-align: center;
font-size: 14px;
font-family: "Lucida Grande",Helvetica,Arial,Verdana,sans-serif;
}
#wrap {
width: 1100px;
margin: 0 auto;
}
#external-events {
float: left;
width: 150px;
padding: 0 10px;
border: 1px solid #ccc;
background: #eee;
text-align: left;
}
#external-events h4 {
font-size: 16px;
margin-top: 0;
padding-top: 1em;
}
#external-events .fc-event {
margin: 10px 0;
cursor: pointer;
}
#external-events p {
margin: 1.5em 0;
font-size: 11px;
color: #666;
}
#external-events p input {
margin: 0;
vertical-align: middle;
}
#calendar {
float: right;
width: 900px;
}
</style>
</head>
<body>
<div id='wrap'>
<div id='external-events'>
<h3>Aufgaben</h3>
<?php
foreach (SelectTask() as $x) {
echo "<div class='fc-event'>" . $x['dtTask'] . "</div>";
}
?>
</div>
<div id='calendar'></div>
<div style='clear:both'></div>
</body>
</html>
event.php:
<?php
// List of events
$json = array();
// Query that retrieves events
$requete = "SELECT * FROM tblEvent";
// connection to the database
try {
$dbc = new PDO('mysql:host=10.140.2.19;dbname=dbcontrol', 'ymartins', 'a15370430x');
} catch (Exception $e) {
exit('Unable to connect to database.');
}
// Execute the query
$resultat = $dbc->query($requete) or die(print_r($dbc->errorInfo()));
// sending the encoded result to success page
echo json_encode($resultat->fetchAll(PDO::FETCH_ASSOC));
?>
add_event.php:
<?php
// Values received via ajax
$title = $_POST['title'];
$user = $_POST['user'];
$start = $_POST['start'];
$end = $_POST['end'];
$url = $_POST['url'];
// connection to the database
try {
$dbc = new PDO('mysql:host=10.140.2.19;dbname=dbcontrol', '****', ****);
} catch (Exception $e) {
exit('Unable to connect to database.');
}
// insert the records
$sql = "INSERT INTO tblEvent (dtTitle, dtStart, dtEnd, dtUrl) VALUES (:title, :start, :end, :url)";
$q = $dbc->prepare($sql);
$q->execute(array(':title' => $title, ':start' => $start, ':end' => $end, ':url' => $url));
?>
What am I doing wrong and how can I improve my script?
You may want to expand your question to include exactly what is going wrong/not working?
I see one issue at least:
your AJAX call should look like this:
$.ajax({
url: '/add_event.php',
data: {'title': title, 'start': start ...}
type: "POST",
success: function (json) {
alert('Added Successfully');
}
});
complete the 'data:' line... its a dict, not a GET Url encoded string when using POST.
you may also want to add a failure section to catch errors, or at least print out the value of the 'json' in case your php page throws an error (it will be in that variable of the success callback).
I'm working on Highchart and it's working fine but now when the page load. I want the png (image file) automatically downloaded. How can I do this?
<?php
$xcat = array('0-4', '5-9', '10-14', '15-19',
'20-24', '25-29', '30-34', '35-39', '40-44',
'45-49', '50-54', '55-59', '60-64', '65-69',
'70-74', '75-79', '80-84', '85-89', '90-94',
'95-99', '100 +');
$unit = "age";
$data1 = array("0"=>array("Seriesname"=>"Male","data"=>array("-1746181", "-1884428", "-2089758", "-2222362", "-2537431", "-2507081", "-2443179",
"-2664537", "-3556505", "-3680231", "-3143062", "-2721122", "-2229181", "-2227768",
"-2176300", "-1329968", "-836804", "-354784", "-90569", "28367", "-3878")),
"1"=>array("Seriesname"=>"Female","data"=>array("1656154", "1787564", "1981671", "2108575", "2403438", "2366003", "2301402", "2519874",
"3360596", "3493473", "3050775", "2759560", "2304444", "2426504", "2568938", "1785638",
"1447162", "1005011", "330870", "130632", "21208"))
);
echo NegativeBarChart("container2","Testing","Test",$xcat,$unit,$data1);
?>
<div id="container2" style="min-width: 400px; max-width: 800px; height: 400px; margin: 0 auto"></div>
I advice to familair with exporting options: http://api.highcharts.com/highcharts#exporting.buttons.contextButton.onclick and example http://jsfiddle.net/72E6v/ which introduce how to download chart automatically.
exporting: {
buttons: {
contextButton: {
menuItems: null,
onclick: function() {
this.exportChart();
}
}
}
EDIT:
Automatically downloading http://jsfiddle.net/8uDdb/1/
chart: {
events: {
load: function () {
var ch = this;
setTimeout(function(){
ch.exportChart();
},1);
}
}
},
I use the following jquery code to load a page...
$(function() {
$('#stats').load('statsto.php');
var visibleInterval = 60000;
var invisibleInterval = 120000;
$(function() {
setTimer();
$(document).bind('visibilitychange'), function() {
clearTimeout(timer);
setTimer();
};
});
function displayStats() {
$('#stats').load('statsto.php');
$.ajaxSetup({ cache: false });
}
function setTimer() {
timer = setInterval(displayStats, (document.hidden) ? invisibleInterval : visibleInterval);
}
});
and here is the style from statsto.php...
body {
font-family: Verdana;
font-size: 7px;
color: #FFFFFF;
background-color: #000000;
background-image: url("grad.png");
}
But the background image is not showing in internet explorer. I have tried using background: black url("grad.png"); but that also doesn't work. I have also tried including the style in the same page as the JQuery code, but still no luck.
Hmm.. Your issue may be with the .load() function itself (in Internet Explorer). I seem to remember encountering an issue with that a while back...
Try this
$.get('statso.php', function() {
$('#stats').html();
});