views:

29

answers:

2

I'm trying to load an image selected by the user through an element.

I added a onchange event handler to the input element like this:

<input type="file" name="picField" id="picField" size="24" onchange="preview_2(this);" alt=""/>

and the preview_2 function is:

var outImage ="imagenFondo";
function preview_2(what){
    globalPic = new Image();
    globalPic.onload = function() {
        document.getElementById(outImage).src = globalPic.src;
    }
    globalPic.src=what.value;
}

where outImage has the id value of the tag where I want the new picture to be loaded.

However, it appears that the onload never happens and it does not load anything to the html.

What should I do?

+1  A: 

You cannot (in most security concious browsers) get the full path of a file from a file input box, nor can you access the data. The only viable solution would be to submit the form to a hidden iframe and have the file pre-uploaded to the server. Then, when that request completes you could set the src of the image to the location of the uploaded file.

From MSDN, applying to IE 8 and later:

The fully qualified filename of the selected file is returned only when this [security] setting is enabled. When the setting is disabled, Internet Explorer 8 replaces the local drive and directory path with the string C:\fakepath\ in order to prevent inappropriate information disclosure.

To illustrate, suppose you attempt to upload a file named C:\users\contoso\documents\file.txt. When you do this, the value of the value property is set to c:\fakepath\file.txt.

Most other browser have exhibited this behaviour for quite some time.

Andy E
right, so there´s no way I can upload an image selected from the user just as simply as it sounds...?
Valentina
@Valentine: no, it's not as straightforward as you might have hoped for. Very little is in the web development world ;-)
Andy E
Lol... would it work if: through that <input type=file> I upload the image to the server right away and after that load the image to the html (from the server)?
Valentina
@Valentina: yes. There may also be other solutions in the form of Flash or Java based file uploaders, but remember that not everyone has these components installed in their browsers.
Andy E
@Andy: yes, I'm looking for x-browser solutions so I think I'll give it a try using the server option. Thank you very much!
Valentina
A: 

Andy E is correct that there is no HTML-based way to do this; but if you are willing to use Flash, you can do it. The following works reliably on systems that have Flash installed. If your app needs to work on iPhone, then of course you'll need a fallback HTML-based solution.

Flash uploading also has other advantages -- Flash gives you the ability to show a progress bar as the upload of a large file progresses. (I'm pretty sure that's how Gmail does it, by using Flash behind the scenes, although I may be wrong about that.)

Here is a sample Flex 4 app that allows the user to pick a file, and then displays it:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
               creationComplete="init()">
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
    <s:Button x="10" y="10" label="Choose file..." click="showFilePicker()" />
    <mx:Image id="myImage" x="9" y="44"/>
    <fx:Script>
        <![CDATA[
            private var fr:FileReference = new FileReference();

            // Called when the app starts.
            private function init():void
            {
                // Set up event handlers.
                fr.addEventListener(Event.SELECT, onSelect);
                fr.addEventListener(Event.COMPLETE, onComplete);
            }

            // Called when the user clicks "Choose file..."
            private function showFilePicker():void
            {
                fr.browse();
            }

            // Called when fr.browse() dispatches Event.SELECT to indicate
            // that the user has picked a file.
            private function onSelect(e:Event):void
            {
                fr.load(); // start reading the file
            }

            // Called when fr.load() dispatches Event.COMPLETE to indicate
            // that the file has finished loading.
            private function onComplete(e:Event):void
            {
                myImage.data = fr.data; // load the file's data into the Image
            }
        ]]>
    </fx:Script>
</s:Application>
Mike Morearty
To clarify, for those who are worried about security: Flash doesn't allow you to access ANY local file -- it only allows you to access a local file that has been explicitly, interactively pointed to by the user. This is similar to what HTML does (it lets you upload any explicitly specified file to the server), except that Flash also allows local access in addition to the ability to upload the file.
Mike Morearty
I uploaded the executable Flash app here so you can try it out: http://www.morearty.com/preview/FileUploadTest.html
Mike Morearty