Quantcast

Forums | MacLife

You are not logged in.

#1 2009-01-28 7:43 pm

resedit
Chicken Little
Royal Wombat
From: /dev/null
Registered: 1999-11-01
Posts: 50393
Website

progress bar

I've been playing a little bit with http://pecl.php.net/package/uploadprogress/

Their example works just swell - it's a two image upload bar where the action for the submit is an iframe that uses javascript to then update the parent page - a javascript function in the parent page reloads the iframe to get the new progress data from the server.

I can't have my action be an iframe - my action has to be to a different page as their is more data than just image uploads - I can do the same thing they do by using javascript to open a new window on submit, the new window containing an iframe that fetches the data, but I'd rather not do that.

I tried having javascipt "onsubmit" for the form update an iframe, but it seems when you do that, the actual submit doesn't happen until the onsubmit action completes, so the page gets stuck in a loop until the browser decides too much recursion has taken place and kills it.

Is there a way to have onsubmit spawn a javascript process that continues to run while exiting to let the actual submit happen?

One way I was thinking of was maybe with a meaningless hidden form element that has an onchange action, and onsubmit changes that hidden element and exits (thus spawning the onchange) but that seems a little bit hackish and I'm not sure it would work.


In her right hand Jenny held the Bible of her mother
Jenny had a pistol in the other
-- Steve Taylor

Offline

 

#2 2009-01-28 8:45 pm

Miles
Now I fight for wisdom!
Administrator
From: Michigan
Registered: 2001-07-21
Posts: 4506
Website

Re: progress bar

resedit wrote:

Is there a way to have onsubmit spawn a javascript process that continues to run while exiting to let the actual submit happen?

Any continuous javascript loop will lock up the browser.  You need to use setTimeout.

Offline

 

#3 2009-01-28 9:17 pm

resedit
Chicken Little
Royal Wombat
From: /dev/null
Registered: 1999-11-01
Posts: 50393
Website

Re: progress bar

Miles wrote:

resedit wrote:

Is there a way to have onsubmit spawn a javascript process that continues to run while exiting to let the actual submit happen?

Any continuous javascript loop will lock up the browser.  You need to use setTimeout.

I am usimg setTimeout - with the function calling itself

But it seems that when done from onsubmit - the actual http post doesn't happen until the onsubmit script exits, which of course is a problem because it is suppose to monitor the file upload part of the post.

If I launch a new window with onsubmit then the new window opens, the post is done, and the new window can monitor the upload - but I'd really rather not go there (I despise new windows when other people use them, so I'm not keen on doing it myself)

I'd rather just have the upload progress bar on the form page - so that when the upload is done the page refreshes to the action page and I don't have to worry about having JavaScript close the progress bar window that it opened onsubmit (and a new window may not even work with people who's preferences don't allow new windows to be opened).

Last edited by resedit (2009-01-28 9:18 pm)


In her right hand Jenny held the Bible of her mother
Jenny had a pistol in the other
-- Steve Taylor

Offline

 

#4 2009-01-28 9:25 pm

resedit
Chicken Little
Royal Wombat
From: /dev/null
Registered: 1999-11-01
Posts: 50393
Website

Re: progress bar

I'm going to try the onchange method with a hidden input, so the post action changes the value of the hidden input to trigger the iframe that fetches the upload progress from the server, but that just seems hackish.


In her right hand Jenny held the Bible of her mother
Jenny had a pistol in the other
-- Steve Taylor

Offline

 

#5 2009-01-30 10:22 pm

resedit
Chicken Little
Royal Wombat
From: /dev/null
Registered: 1999-11-01
Posts: 50393
Website

Re: progress bar

I ended up just using window.new rather than trying to use an iframe inside the form submit page to fetch the upload progress data- it seems popup blockers (at least mine) doesn't block that, and since it isn't an advertisement popup, it isn't that offensive.

I'm sure the code could be cleaner, the downside is that (at least in firefox) a 0px X 0px iframe shows a little bit. Using the proper xhtml object works well with FireFox 3 w/o the visual hint of an iframe but I've heard that using object in place of iframe doesn't work well with some (all?) versions of IE.

for those interested - this requires the following (beta) PCEL module -
http://pecl.php.net/package/uploadprogress/


I'm using it on php 5.2.5 (custom built) on CentOS 5.2 x86_64 - here's the code -

before your file inputs in your form, you have to assign a unique file identifier -

Code:

<input type="hidden" name="UPLOAD_IDENTIFIER" value="<?php echo $upid;?>" />

generate a random $upid however you like, but it seems the hidden input type must be BEFORE the file inputs or it doesn't work.

Here's the php for the window to open via onsubmit - pass the UPLOAD_IDENTIFER to it via $_GET when opening the window

Code:

<?php 
if (isset($_GET['ID'])) {
   $id = $_GET['ID'];
   }
?>
<!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 name="generator" content="Bluefish 1.0.7"/>
<script type="text/javascript">

function getInfo() {
   var rand_no = Math.random();
   mySrc = "uploadiframe.php?ID=<?php echo($id);?>" + "&foo=" + rand_no;
   ifr = document.getElementById("ifr");
   ifr.src = mySrc;
   }
   
function noData() {
   //alert("nodata");
   var myStatus = document.getElementById("status");
   value = myStatus.getAttribute("name");
   if ( value < 5 ) {
      newValue = (value + 1);
      myStatus.setAttribute("name",newValue);
      setTimeout("getInfo()",1000);
      } else {
      var myDiv = document.getElementById("progressbar");
      myStyle = "width: 100%; height: 2em; background-color: #ca0000;";
      myDiv.setAttribute("style",myStyle);
      myString = "Please Wait";
      myText = document.createTextNode(myString);
      var myPar = document.createElement("p");
      myDiv.removeChild(myDiv.firstChild)
      myPar.appendChild(myText);
      myDiv.appendChild(myPar);
      anotherString = "Processing Image(s) ...";
      anotherText = document.createTextNode(anotherString);
      var anotherPar = document.getElementById("blah");
      anotherPar.removeChild(anotherPar.firstChild);
      anotherPar.appendChild(anotherText);      
      setTimeout("window.close()",4000);
      }
   }

function uploadBar(percent) {
   var myStatus = document.getElementById("status");
   myStatus.setAttribute("name",8);
   var myDiv = document.getElementById("progressbar");
   myStyle = "width: " + percent + "%; height: 2em; background-color: #ca0000;";
   myDiv.setAttribute("style",myStyle);
   myString = percent + "%";
   myText = document.createTextNode(myString);
   var myPar = document.createElement("p");
   myDiv.removeChild(myDiv.firstChild)
   myPar.appendChild(myText);
   myDiv.appendChild(myPar);
   setTimeout("getInfo()",1000);
   }
   

</script>
<title>Upload Progress</title>
</head>

<body>
<p id="blah">Upload Progress:</p>
<div id="progressbar" style="height: 2em;"><p>0%</p></div><div style="clear: both;"></div>
<iframe id="ifr" src="uploadiframe.php?ID=<?php echo $id;?>" width="0px" height="0px" name="ifr"></iframe>
<div id="status" name="0"></div>
</body>
</html>

Here's the code for iframe -

Code:

<?php
$info = uploadprogress_get_info($_GET['ID']);
?>
<html>
<head>

<script type="text/javascript">
<?php
if ($info !== null) {
   $percent=round(100 * ($info['bytes_uploaded']/$info['bytes_total']));
   print "parent.uploadBar($percent);\n";
} else {
   print "parent.noData();\n";
}
?>
</script>
</head>

<body></body></html>

There's a reason why I have the

Code:

<div id="status" name="0"></div>

and increment it when the iframe doesn't have data to send

Maybe there's a better way to do it - but if a file uploads too quickly, there never will be any data, so that gives the window a timeout at which it closes if it doesn't get any data after several successive reloads of the iframe.

Keep in mind I generally despise JavaScript - and am fairly new to it, so there undoubtedly is a better way to do some of the things I do. But anyway, it seems before this PECL module, the only way to get a true file upload progress bar in php was to use something other than php on the server to process the file upload, so since this is pure php (with JavaScript on the client side, but give stateless nature of http I don't think avoiding client side scripting is possible) I though some might be interested in it.


In her right hand Jenny held the Bible of her mother
Jenny had a pistol in the other
-- Steve Taylor

Offline

 

Board footer

Powered by PunBB 1.2.6
© Copyright 2002–2005 Rickard Andersson