0

I'm trying to achieve ajax-like-file-upload-using-hidden-iframe. Obviously there are many plugins available for that purpose, but I think my requirements are a bit different. So I'm trying to achieve it as follows:

HTML:

    <!DOCTYPE>
    <html> 
    <style>
        .file_upload{cursor:pointer;color:blue;text-decoration:underline;}
    </style>
    <body>
        <div class="file_upload" id="upload1" name="doc1" >Upload doc1</div>
        <div class="file_upload" id="upload2" name="doc2" >Upload doc2</div>
        <div id="iframe_div"></div>
    </body>
    </html>  

JQUERY:

$(document).ready(function(){
                $(".file_upload").click(function(event){
                    var itr = $(".file_upload").length;
                    var iframeName = $(this).attr('name') + itr;
                    var iframeId = $(this).attr('id') + itr;
                    $('<iframe />', {
                        name: iframeName,
                        id: iframeId,
                        src: 'about:blank'
                    }).appendTo('#iframe_div');
                    //append form to body of the iframe
                    $('<form>',{
                        name: iframeName + '_form',
                        id: iframeId + '_form',
                        action: 'actionName.action',
                        method: 'POST',
                        enctype: 'multipart/form-data'
                    }).appendTo('#' + iframeId).find('body');
                    //append file input
                    //trigger 'click' using $('#file_fld_id').trigger('click')
                    //browse to file and use 'onchange' to trigger
                                      auto-submit of  the form
                    //replace the 'file-upload' div with a progress bar...
                   //remove the iframe when upload is complete
                });
            });

In Short:

1. Open browse window onclick of a div.

2. Upload the file using hidden iframe.

But I think I'm too knowledgeable(in jquery) to achieve this. Or is it really possible?? If so please help/redirect/anything.....how come this obvious functionality has to be implemented with work-arounds(flash,obex,silverlight,....)..ahhh.

EDIT(to clarify a bit):

As I mentioned 'my iframe is dynamic'...the reason is that my file inputs are supposed to be inside an already existing form with a separate action(struts2). I've got yet another action for file upload. As we can't have form inside a form, so what I'm trying is to use a div inside my existing form for file uploading with the other action. And I've got different docs to be uploaded separately within this form. So basically I'm trying to replace each div(one being used for file upload) with a separate iframe having its own form(but same action would handle the upload) which will get auto-submitted the moment user clicks 'open' while browsing the file. I hope I'm clearer now.

Amarjeet Kumar
  • 57
  • 1
  • 2
  • 10

1 Answers1

1

Ok, here the sample.It may not work on all browsers, I just checked on chrome 22, it will not work with different domain (same origin policy)

HTML:

<div id="hello">You will be asked to submit a file</div>
<div id="temp">
<iframe>
 
</iframe>
</div>
<button id="SelectFile">Select File</button>
<div id="filedialog">
    <form method="POST" action="/test.php" >
   <input type="file">
    </form>
</div>
​

CSS

#temp ,#filedialog{
 display:none;   
}

js:

var frame = $('#temp iframe');
var frameinit = function() {
    frame.contents().find('body').children().remove();
    frame.contents().find('body').append($('#filedialog').html());
    frame.contents().find('input').change(function() {
        frame.contents().find('form').submit();
    });
};
frameinit();
$('#SelectFile').click(

function() {
    frame.contents().find('input').click();
    frame.load(function() {
        //JSfiddle's error message from iframe
        var data = frame.contents().find('.pageHeader');
        $('body').append($('<div>').html(data));
        frameinit();
    });
});​
​

please note that you can't trigger click on file dialog without real browser click.

zb'
  • 8,071
  • 4
  • 41
  • 68
  • Well,1st of all thanks for the help . I at least have a direction now. I've updated the question. Please have a look and suggest accordingly. – Amarjeet Kumar Nov 04 '12 at 11:31
  • and what problem to do that with my code ? you can generate any form inside iframe... – zb' Nov 04 '12 at 11:33
  • I can't use the form tag in html....anyway I'm accepting your answer for I'm hopeful I can solve. But it would have been greatful if you could show me how to access the DOM of dynamic iframe. That code of mine is not appending the form. – Amarjeet Kumar Nov 04 '12 at 11:40
  • You shouldn't use form tag in html, it is just sample, as you can see i generate form in iframe using html() function, which return string. iframe accessed using contents() - it is $(document) of the inner iframe. – zb' Nov 04 '12 at 11:44
  • hmmm...I'm working on it.. will update if done. As of now I'm able to trigger the file dialog without really clicking the 'browse'....have a look..(http://jsfiddle.net/qv3MG/ ).but donno if I would be able trigger it when the file input lies inside iframe and also the moment I click it doesn't exist!! – Amarjeet Kumar Nov 04 '12 at 11:53
  • that what I mean, it should be click somewhere and the handler of that click can make click to the file, but you can't trigger click without any click. In my code you not clicking browse too, it can be button, ui-button, div, link, anything – zb' Nov 04 '12 at 12:05
  • 1
    check [this](http://jsfiddle.net/oceog/wu4mr/3/) - all dynamic, iframe, form, etc... – zb' Nov 04 '12 at 12:12
  • I too was doing the same...it should save some of my time...thanks a lot. – Amarjeet Kumar Nov 04 '12 at 12:17
  • what could be the reason that it is not working in strts2.?? iframe in created but form it not getting appended. – Amarjeet Kumar Nov 05 '12 at 11:40
  • I have no idea about struts2 or any java :) Just can suggest to check generated scripts/pages as java is server side – zb' Nov 05 '12 at 21:52