Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery Multiple Dynamic Forms to Multiple Dynamic iFrames

I'm creating a multi-file upload. In the validation process where I build the list of files (before they are submitted), the first dynamically created <form> will submit and work as expected but the other dynamically created <form>'s will not. This doesn't work in IE7+ or FireFox...

Also to note, this code is in SharePoint 2007 in case there are any restrictions anyone can point out! Thanks!

Use Case

  1. User clicks browse and selects a file...
  2. The <input type="file" /> control is hidden.
  3. jQuery wraps a <form> around the <input type="file" /> and adds a new <iframe> that the form is referencing as the target for the response and submits the form.
  4. On the server side, I run some validation and send back file name, size, and an option to remove.
  5. In the <iframe> (response) the user sees something like Winter.jpg | 10 KB | (x) remove
  6. jQuery clone()'s the <input type="file" class="uploader" /> control and append()'s it to the <div> in case the user desires to upload more.
  7. Note: keep in mind the clone(), <form>, and <iframe> are given unique IDs for the id, name, and target respectively. The .ashx file has been tested and works. I'm confused why I can't keep creating new <form>s, <input type="file"/>'s, and <iframe>'s and adding to the list...

HTML

<div id="files">
    <div class="field">
        <input id="file" type="file" name="file" class="uploader" value="Browse..." />
    </div>
</div>

Javascript
Sorry, the code might be a bit sloppy-- trial and error here...

<script type="text/javascript">
    $('.uploader').live('change', function(){
        var $clone = $(this).parent().clone();
        var filename = $(this).val().substring($(this).val().lastIndexOf('\\')+1);

        //var $form = $('<form id="uploadForm" action="_layouts/GetFileInfo.ashx" method="post" target="fileinfo" enctype="multipart/form-data">');
        var $form = $('<form>').attr('id', 'uploadForm').attr('action', '_layouts/GetFileInfo.ashx').attr('method', 'post').attr('target', 'fileinfo').attr('enctype', 'multipart/form-data');
        var $result = $('<iframe name="fileinfo' + _uploadId + '" src="upload.html" frameBorder="0" allowtransparency="true" style="width: 250px; height: 25px; border:0;">');

        $form[0].id += _uploadId;
        $form[0].target += _uploadId;
        $clone.find('input')[0].id += _uploadId;
        $clone.find('input')[0].name += _uploadId;

        //remove button
        $('<div class="remove" style="float:right;">').html("x").appendTo($(this).parent());

        //append the goodness           
        $(this).parent().append($result);
        $(this).wrap($form);

        //let the form render and submit
        window.setTimeout(function(){
            $('#files form').last().submit();
        }, 1000);

        $(this).hide();

        $clone.find('input').val('');

        $(this).parents('#files').append($clone);

        _uploadId++;
    });
</script>

I figured you guys might ask so here's the rendered HTML...

Rendered HTML

<div style="float: left;" class="col" id="files">
    <div class="field">
        <form id="uploadForm0" action="_layouts/GetFileInfo.ashx" method="post" target="fileinfo0" enctype="multipart/form-data">
            <input type="file" value="Browse..." class="uploader" name="file" id="file" style="display: none;">
        </form>
        <div style="float: right;" class="remove">x</div>
        <iframe frameborder="0" style="width: 250px; height: 25px; border: 0pt none;" allowtransparency="true" src="upload.html" name="fileinfo0"></iframe>
    </div>
    <div class="field">
        <form id="uploadForm1" action="_layouts/GetFileInfo.ashx" method="post" target="fileinfo1" enctype="multipart/form-data">
            <input type="file" value="Browse..." class="uploader" name="file0" id="file0" style="display: none;">
        </form>
        <div style="float: right;" class="remove">x</div>
        <iframe frameborder="0" style="width: 250px; height: 25px; border: 0pt none;" allowtransparency="true" src="upload.html" name="fileinfo1"></iframe>
    </div>
    <div class="field">
       <input type="file" value="Browse..." class="uploader" name="file01" id="file01">
    </div>
</div>
like image 964
pixelbobby Avatar asked Feb 13 '12 18:02

pixelbobby


1 Answers

All, this issue still remains but I implemented jQuery Forms (which also works w/ multipart forms by using iframes), changed the design a bit, and it works.

If I had to guess, I think the issue was caused somewhere in creating the <form>, <input type="file" />, and other elements on-the-fly in JS. It was as though SharePoint had a rule or listener that was incercepting the form submit() event and return false; not allowing it to get to the ASHX handler...

I use the same HTML above, only now the JavaScript uses a single <input type="file /> control and <form>. I append the result via $.ajaxSubmit({success: function(result)}).

I still clone() the inputs and append them with the result. When the user selects to upload the images I simply create a <form> object in JS and use $.ajaxSubmit on that as well.

I iterate thru the context.Request.Files in C# and attach them to the associated ListItem in SharePoint 2007.

Cheers,
Bobby

like image 85
pixelbobby Avatar answered Nov 07 '22 21:11

pixelbobby