Topic: File Uploading - A possible attempt

Hey there,

As some people in the forum may know, I've been trying to get file uploads working with xajax.
Here's the first version of the file uploading stuff.  It makes a hidden iframe and handles all the uploading, so you dont have to update your page.  At the moment it can't respond with xajax commands yet.

The javascript file is at
http://www.concepts.net.nz/xajax/xajax_ … uploads.js

You can include it after you use the $xajax->printJavascript(); command

<head>
    <?php $xajax->printJavascript(); ?>
    <script type="text/javascript" src="xajax_js/xajax_file_uploads.js"></script>
</head>

and then you need is a registered xajax function named file_upload

function file_upload()
{
    $objResponse = new xajaxResponse();
    $objResponse->addAlert(print_r($_FILES,true));
    return $objResponse->getXML();
}
$xajax->registerFunction("file_upload");

which will have access to the $_FILES global (as above)


To create an xajax file uploader, you can either use
    xajax.newFileUpload(parent, id);
which creates a new file upload after the 'parent' id and given the name/id of 'id'
or
you can use your existing file inputs by giving them a className of "xajax_file" and running
    xajax.initFileInputs();
which will convert all the file inputs into xajax file uploaders

Questions/Comments required smile

Tested in Opera, IE, Firefox and Safari.  Safari has a bug that it wont upload the file as soon as you choose one but i've tried to get around that by getting it to submit onmouseout.

Re: File Uploading - A possible attempt

I tried to create file uploader but FF shows error:
"Error: objSibling has no properties
Source file: http://server/mstar/gbb/xajax/xajax_js/xajax.js
Line: 166 "

and IE shows: "'parentNode' is null or not an object"

Here is my code

function file_upload()
{
    $objResponse = new xajaxResponse();
    $objResponse->addAlert(print_r($_FILES,true));
    return $objResponse->getXML();
}
//#################################################################################

$xajax = new xajax();
//$xajax->debugOn();
$xajax->statusMessagesOn();
$xajax->errorHandlerOn();


$xajax->registerFunction("process_form");
$xajax->registerWaypointFunction("process_form");
$xajax->registerFunction("process_browse_url");
$xajax->registerWaypointFunction("process_browse_url");

$xajax->registerFunction("file_upload");

$xajax->processRequests();
$main=str_replace("::xajax_javascript::", $xajax->getJavascript('../xajax') ,$main);

Template:

...

::xajax_javascript::
<script language="javascript" type="text/javascript" src="../xajax/xajax_js/xajax_file_uploads.js"></script>
</BODY>
</HTML>

So could you give url with your sample, please? I'd like to see your working script and sample of using it.

Thanks.

3 (edited by AN 2006-03-21 4:09:08 PM)

Re: File Uploading - A possible attempt

BigBrownChunx wrote:

It makes a hidden iframe and handles all the uploading, so you dont have to update your page.  At the moment it can't respond with xajax commands yet.

WOW! That's fast!!


I can't try it right now, but be sure i will try it ASAP, and you'll have my commentaries/questions/etc.

I finally managed to use the iframe. From the iframe i can access a parent window's div and display messages like "The file is currently beeing uploded" or "The file couldn't be uploaded." And enable or disable buttons while in the process...

I guess that can be achieved in a more abstract way...

"input type=file" are so dumb! They don't even get a 'solid' border....

Do you have any idea how can I simulate a click on the "Browse" button ? Or how to obtain the same "open file" dialog ?


yikes

AN

Re: File Uploading - A possible attempt

I have an example uploaded at
http://www.concepts.net.nz/xajax/file_u … xample.php
It cheats at using the 'file has been uploaded' thing, but i'm trying to stick to a client-side-only method of uploading to make regular file uploads compatible

Re: File Uploading - A possible attempt

Hello, and first of all, thank you for this tool, it's really a must have !
I have no pb with firefox, but with IE I can't see the input forms !!??
I have IE 6.0.2900.2180.
I'm surprised that you say that you've tested it on IE

Re: File Uploading - A possible attempt

Thanks for that.  I have been testing it out on IE under Linux which didn't have support for the opacity filter that i accidentially left on.

have a look now.

Re: File Uploading - A possible attempt

Your Example doesn't work and i cant get it work too.

I can choose a file and the also begins (and probably is successful), but i get the following error in the Firefox js-console

Error: uploadIframe.contentDocument.body has no properties
Source File: http://www.concepts.net.nz/xajax/xajax_js/xajax_file_uploads.js
Line: 67

and the "Uploading..." don't disappear.

I'm using Firefox 1.5.0.1

Greats.

PS: Same behavior in IE 7 Beta 2

Re: File Uploading - A possible attempt

Same with opera 9 build 8303...

JavaScript - http://www.concepts.net.nz/xajax/file_upload_example.php
Timeout thread: delay 100 ms
Error:
name: TypeError
message: Statement on line 67: Could not convert undefined or null to object
Backtrace:
  Line 67 of linked script http://www.concepts.net.nz/xajax/xajax_js/xajax_file_uploads.js
    if (uploadIframe.contentDocument.body.innerHTML.indexOf("</xjx>") !== - 1)
    else
      Line 1 of unknown script 
    xajax._fileProgressCheck("uploadFileInput1-xajaxWork1143140099648");

Re: File Uploading - A possible attempt

Well, under IE I can now see the inputs, but it's a bit ugly...
I have a shift to the right for the first one, and the div appears like a input where you can't see fully the button  (ok it's not a real matter) , I can make a screen capture if you want.
With IE, after I choose a file nothing change ! ( no uploading process)
and with portable firefox 1.5 I experiment also the trouble of the persistent "Uploading....."

Re: File Uploading - A possible attempt

Thanks for pointing out about the errors.  when i've been testing it the response from my server has been too quick for these errors to come up.  i'll fix them up when i get home.

Re: File Uploading - A possible attempt

Sorry for budding in but I've found an example of the best file uploading demo & code (not xajax - sigh!) at w2box, http://labs.beffa.org/w2box/demo/.

I'm just going through their code now. w2box's demo has additional features (in the same page) of:
- displaying files uploaded and the stats of each file!
- delete files
- download files

I'm hoping to integrate w2box with xajax big_smile

Re: File Uploading - A possible attempt

That's pretty cool smile  And something I'm hoping to aim for, certainly looks good.

Have u looked at my version of it at all?

Re: File Uploading - A possible attempt

Hi,

I've only had a chance to try out your demo and quickly "scan" through your code. It's great that you've provided an example. I'll be using your code as a reference point for the integration of course since there are underlying similarities:)

Re: File Uploading - A possible attempt

love the progress bar thing though,
any idea how he does it?  i havn't spent much time going through the source code, but it looks like he has a lot of extra cgi files to deal with uploaded file sizes or something?

i'm also thinking of including file_upload as a proposed plugin for a proposed plugin system for xajax.  not sure if it'll make it into v0.5, but we'll see.

Re: File Uploading - A possible attempt

The upload progress stuff he was doing was via PERL CGI scripts, so it's out of scope for a PHP library. smile

BBC, I haven't had time to delve into your code yet, but I would *love* some kind of file upload ability to be included with xajax 0.5. Making it a plugin sounds like a good idea. Once we hash out a plugin system, we can work to get that going.

Project manager for xajax

16 (edited by dragoni 2006-04-05 12:54:07 AM)

Re: File Uploading - A possible attempt

Hi,

Unfortnately, I have a day job so I can only work on this on my spare time:( I tried hacking with w2box but I couldn't get the perl script to work on my PC.

I would LOVE to have a file upload progress bar. I did find another good example, http://blog.joshuaeichorn.com/archives/ … r-updates/ from another PHP Ajax library called HTML_Ajax. The code is pure PHP and javascript. There's also a demo.

17 (edited by mickey9801 2006-04-10 7:33:00 PM)

Re: File Uploading - A possible attempt

I have check through the codes and found that the iframe form will submit to file_upload_example.php in traditional way, but there is no code to handle the submitted matter. So I added some code right after $xajax = new xajax(); Because   finally the file uploaded is not handled by xajax responser function, I have removed  the code $xajax->registerFunction("file_upload"); I also added a handler function at the end of the php file. Of cause, you may submit the file to other upload handling php file other then file_upload_example.php itself. But this may need to modify the js file.

Another problem why IE does not work is because IE act as a XML parser if we return XML back to the iframe, and therefore the javascript function will not work. I modified the handler function so that it will not return XML.

file_upload_example.php (revised)

<?php
require "xajax.inc.php";
$xajax = new xajax();

if (isset($_POST['xajax']) && $_POST['xajax']=='file_upload') {
    echo file_upload();
    exit();
}
?>
<html>
    <head>
        <? $xajax->printJavascript(); ?>
        <script language="javascript" type="text/javascript" src="xajax_js/xajax_file_uploads.js"></script>
    </head>
    <body onload="showSource();">
        <h1>xajax File Upload Test</h1>
        Method 1 - Setting classname to "xajax_file" on existing file input and using xajax.initFileInputs();<br/>
        <input type="file" class="xajax_file" id="uploadFileInput1" />
        <script type="text/javascript">
        <!--
            xajax.initFileInputs();
        -->
        </script>
        <br/><br/>
        Method 2 - Using a containing div and xajax.newFileUpload();<br/>
        <div id="uploadDiv"></div>
        <script type="text/javascript">
        <!--
            xajax.newFileUpload('uploadDiv','uploadFileInput2');
        -->
        </script>
        <br/><br/>
        Page Source:<br/>
        <textarea style="width: 590px; height: 150px;" id="pagesource"></textarea>
        <script type="text/javascript">
        <!--
            function showSource()
            {
                //xajax.$('pagesource').innerHTML = xajax.viewSource().replace('<','<').replace('>','>');
            }
            //don't get page source here: causes infinite loop
            //showSource();
        -->
        </script>
        <br/>Original Source:<br/>
        <textarea style="width: 590px; height: 150px;"><?=htmlentities(file_get_contents('file_upload_example.php'));?></textarea>
    
    </body>
</html>
<?php
function file_upload()
{
    return "UPLOAD DONE \n".var_export($_FILES,true);
}
?>

xajax_file_uploads.js (revised)

if (xajax)
{
    xajax.initFileInputs = function ()
    {
        inputs = document.getElementsByTagName('input');
        for( var i=0; i < inputs.length; i++)
        {
            inp=inputs[i];
            if (!inp.className)
                continue; //doesnt have a class defined
            if (inp.className.indexOf('xajax_file')==-1)
                continue; //not an xajax file upload
            if (inp.style.visibility=='hidden')
                continue; //already converted this file upload
            xajax.newFileUpload(inp.id, inp.id+'-'+xajax.workId);
            inp.style.visibility = 'hidden';
            inp.style.height = '0';
            inp.style.width = '0';
        } 
    }
    xajax.newFileUpload = function(sParentId, sId)
    {
        xajax.insertAfter(sParentId, 'iframe', sId);
        newFrame = xajax.$(sId);
        newFrame.name=sId;
        newFrame.style.height="35px";
        newFrame.style.height="35";
        newFrame.style.width="300";
        newFrame.style.overflow="hidden";
        newFrame.position="relative";
        newFrame.scrolling="no";
        newFrame.allowtransparency=true;
        newFrame.style.backgroundColor="transparent";
        //need to wait for Mozilla to notice there's an iframe
        setTimeout('xajax._fileUploadContinue("'+sId+'");', 20);
    }
    xajax._fileUploadContinue = function(sId)
    {
        //uploadIframe = window.frames[sId];
        uploadIframe = xajax.$(sId);
        if (!uploadIframe.contentDocument)
        {
            //fix for internet explorer
            uploadIframe.contentDocument = window.frames[sId].document;
        }
        uploadIframe.contentDocument.body.style.backgroundColor="transparent";
        uploadIframe.contentDocument.xajax=this;
        uploadIframe.contentDocument.body.innerHTML='<span id="workId" style="font-size:0px;height: 0px;position:absolute;">'+xajax.workId+'</span><form style="position:absolute;top:0;left:0;height:98%;width:98%;margin:0;padding:0;overflow:hidden;" name="iform" action="'+xajaxRequestUri+'" method="post" enctype="multipart/form-data"><input id="file" type="file" name="file" onchange="document.xajax._fileUploading(\''+sId+'\');document.iform.submit();" onmouseout="if(this.value)document.iform.submit();"/><input type="hidden" name="xajax" value="file_upload" /></form>';
        uploadIframe.style.border='0';
    }
    xajax._fileUploading = function(sId)
    {
        uploadIframe = xajax.$(sId);
        xajax.insertAfter(sId, 'div', sId+'-progress');
        uploadProgress = xajax.$(sId+'-progress');
        uploadIframe.style.visibility='hidden';
        uploadIframe.style.width='0';
        uploadIframe.style.height='0';
        uploadProgress.innerHTML='Uploading...';
        uploadProgress.style.fontSize="25";
        setTimeout('xajax._fileProgressCheck("'+sId+'");', 100);
    }
    xajax._fileProgressCheck = function(sId)
    {
        uploadIframe = xajax.$(sId);
        if (!uploadIframe.contentDocument)
        {
            //fix for internet explorer
            uploadIframe.contentDocument = window.frames[sId].document;
        }
        uploadProgress = xajax.$(sId+'-progress');
        if (uploadIframe.contentDocument.body.innerHTML.indexOf('UPLOAD DONE') !== -1)
        {
            //this isn't a proper detection, but we'll work on it later
            uploadProgress.innerHTML='Upload Finished';
        } else {
            setTimeout('xajax._fileProgressCheck("'+sId+'");', 100);
        }
    }
}

But I don't know how to remove the frame border in IE. Hope that anyone could help to solve this problem.

Fedora Cord 3 / Apache 2.0.53 / PHP 4.3.11 / MySQL 4.1.13

Re: File Uploading - A possible attempt

I'm really trying to go with the last solution dragoni is doing.  its clever that they're redirecting the form submission to another iframe like that, but i worry about if you have a standard <input type="file"> in the middle of the <form> tags.

does the following mess up any browsers:

<form>
   <input type='text' />
   <form>
      <input type='file' />
   </form>
</form>

if others have tried doing something like this (i really have never tried nesting <form> tags) and it's ok, then i'll go with this approach, and it'll be a really quick change over to have a cool file upload going.  and i might even consider including it as part of xajax?

19 (edited by q_no 2006-04-27 2:37:03 PM)

Re: File Uploading - A possible attempt

This thread is really interesting and I can't wait for any final results... but is it true that every (php)ajax solution needs a php extension to display a real progressbar (not just an animated fake) to check for the filesizes? I've spend alot of time in thinking about possible solutions to figure it out on my own, but I don't have any idea to find out which file in my phptemp-dir is the one that's currenty processed.
It would be great to have an (x)ajax file upload at all, but it without a real progessbar it wouldn't be cool wink

Re: File Uploading - A possible attempt

q_no wrote:

but is it true that every (php)ajax solution needs a php extension to display a real progressbar (not just an animated fake) to check for the filesizes?

yes.

For a start, PHP doesn't have cross-process communication, so the uploading process couldn't tell a progressbar process how far through it is.
Secondly, PHP doesn't start executing until after the file has been uploaded, so theres no way to tell what the name of the temporary file is that xajax is uploading to.

q_no wrote:

but it without a real progessbar it wouldn't be cool

Sorry, I guess I'm going to have to be uncool then smile

Re: File Uploading - A possible attempt

LoL, Did you got anything fixed already?

Re: File Uploading - A possible attempt

Maybe this is helpfull

http://wiki.bluga.net/HTML_AJAX/ProgressMeter

Re: File Uploading - A possible attempt

Yep there are a lot of methods for doing file uploads without progress bars
there are also a lot of methods for doing file uploads with progress bars, but patching PHP
this link talks about using perl as a backend for accepting file uploads which i'm not happy about

Re: File Uploading - A possible attempt

Did you had an look at my post in the vanity board??

Re: File Uploading - A possible attempt

yep.  it just did uploading right, using a php function to make the uploading HTML?
it's something close but not quite there for what i see as an ultimate solution to put into xajax.