Reputation: 293
I have a multi-step form where the form on Step3 submits to Step4.php. Step4 is a results page, and it takes some time to load, so I wanted to try and implement a progress bar or a loading bar or something when the user clicks the step3 submit button before Step4.php actually loads. I would think I could do this with jquery? But, I'm not sure how. Is it possible to do this without having to use jquery to post the data to step4.php?
Upvotes: 1
Views: 7246
Reputation: 1204
A Simple PHP Upload Progress Bar :
in upload.php
<?php
//get unique id
$up_id = uniqid();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Upload your file</title>
<!--Progress Bar and iframe Styling-->
<link href="style_progress.css" rel="stylesheet" type="text/css" />
<!--Get jQuery-->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.js" type="text/javascript"></script>
<!--display bar only if file is chosen-->
<script>
$(document).ready(function() {
//show the progress bar only if a file field was clicked
var show_bar = 0;
$('input[type="file"]').click(function(){
show_bar = 1;
});
//show iframe on form submit
$("#form1").submit(function(){
if (show_bar === 1) {
$('#upload_frame').show();
function set () {
$('#upload_frame').attr('src','upload_frame.php?up_id=<?php echo $up_id; ?>');
}
setTimeout(set);
}
});
});
</script>
</head>
<body>
<h1>Upload your file </h1>
<div>
<?php if (isset($_GET['success'])) { ?>
<span class="notice">Your file has been uploaded.</span>
<?php } ?>
<form action="" method="post" enctype="multipart/form-data" name="form1" id="form1">
Name<br />
<input name="name" type="text" id="name"/>
<br />
<br />
Your email address <br />
<input name="email" type="text" id="email" size="35" />
<br />
<br />
Choose a file to upload<br />
<!--APC hidden field-->
<input type="hidden" name="APC_UPLOAD_PROGRESS" id="progress_key" value="<?php echo $up_id; ?>"/>
<!---->
<input name="file" type="file" id="file" size="30"/>
<!--Include the iframe-->
<br />
<iframe id="upload_frame" name="upload_frame" frameborder="0" border="0" src="" scrolling="no" scrollbar="no" > </iframe>
<br />
<!---->
<input name="Submit" type="submit" id="submit" value="Submit" />
</form>
</div>
</body>
</html>
In upload_frams.php
<?php
$url = basename($_SERVER['SCRIPT_FILENAME']);
//Get file upload progress information.
if(isset($_GET['progress_key'])) {
$status = apc_fetch('upload_'.$_GET['progress_key']);
echo $status['current']/$status['total']*100;
die;
}
//
?>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.js" type="text/javascript"></script>
<link href="style_progress.css" rel="stylesheet" type="text/css" />
<script>
$(document).ready(function() {
setInterval(function()
{
$.get("<?php echo $url; ?>?progress_key=<?php echo $_GET['up_id']; ?>&randval="+ Math.random(), {
//get request to the current URL (upload_frame.php) which calls the code at the top of the page. It checks the file's progress based on the file id "progress_key=" and returns the value with the function below:
},
function(data) //return information back from jQuery's get request
{
$('#progress_container').fadeIn(100); //fade in progress bar
$('#progress_bar').width(data +"%"); //set width of progress bar based on the $status value (set at the top of this page)
$('#progress_completed').html(parseInt(data) +"%"); //display the % completed within the progress bar
}
)},500); //Interval is set at 500 milliseconds (the progress bar will refresh every .5 seconds)
});
</script>
<body style="margin:0px">
<!--Progress bar divs-->
<div id="progress_container">
<div id="progress_bar">
<div id="progress_completed"></div>
</div>
</div>
<!---->
</body>
In style_progress.css
/*iframe*/
#upload_frame {
border:0px;
height:40px;
width:400px;
display:none;
}
#progress_container {
width: 300px;
height: 30px;
border: 1px solid #CCCCCC;
background-color:#EBEBEB;
display: block;
margin:5px 0px -15px 0px;
}
#progress_bar {
position: relative;
height: 30px;
background-color: #F3631C;
width: 0%;
z-index:10;
}
#progress_completed {
font-size:16px;
z-index:40;
line-height:30px;
padding-left:4px;
color:#FFFFFF;
}
Thanks, Chintu
Upvotes: 0
Reputation: 88846
If this is an upload progress bar:
The first part is installing something on the PHP side that you can hook into.
The APC extension includes an upload hook mechanism. You may already have this installed, as it's a common opcode cache for PHP (and will be included by default in PHP6).
Once APC is installed, you need to set up both the PHP page and PHP handler sides.
PHP page:
<?php
$uploadId = uniqid('', true);
?>
<script type="text/javascript">
function uploadProgress() {
$.ajax({
url: 'url/to/handler.php',
data: ({ progressId: <?php echo $uploadId; ?> }),
success: displayProgress
});
}
function displayProgress(data) {
// Do something with data['current'] and data['total'] here
// Possibly using a JQuery UI Progressbar
// http://jqueryui.com/demos/progressbar/
}
</script>
...
<!-- Your other form elements would be on this form, too -->
<form action="step4.php" enctype="multipart/form-data">
<input type="hidden" name="APC_UPLOAD_PROGRESS" value="<?php echo uploadId; ?>" />
<input type="file" name="file" />
<input type="submit" onClick="setInterval(uploadProgress, 1000); return false;" />
</form>
You will also need a script on the PHP side to call via AJAX. It's been awhile since I've done AJAX with PHP, but something like this should do:
<?php
$returnData = array('current' => 0, 'total' => 0);
if (!empty($_GET['progressId'])) {
$uploadProgress = apc_fetch('upload_' . $_GET['progressId']);
if (!empty($uploadProgress)) {
$returnData['current'] = $uploadProgress['current'];
$returnData['total'] = $uploadProgress['total'];
}
}
echo json_encode($returnData);
Edit: Whoops, there's nothing in the original post that says this is an upload progress bar
Upvotes: 0
Reputation: 1727
I solved this in a MySQL loading program by outputting a simple page with the progress bar, flushing the output with flush(). I then output a simple snippet of javascript:
$('#progressbar').progressbar({value: 0});
I also call flush after outputting this JS snippet. You have to continually output these snippets each time you want to update the progressbar.
Upvotes: 0
Reputation: 19147
As peter says, this is very difficult to do from ajax. Often what people do instead is use a tiny Flash applet which provides the file upload and progress bars. I know both Gmail and Wordpress do this, many others as well. There are many pre-made ones that you just have to drop in and use:
Upvotes: 0
Reputation: 25620
It is very hard to do progress bars for ajax requests. You don't really have access to the request in a way to give the user accurate information with a progress bar. You are better off giving your users a spinner showing them that the script is working on loading things.
Upvotes: 1