jQuery iframe file upload

Im building a file upload with jQuery, but Im getting a jQuery error trying to set the attributes of the form:

$(document).ready(function () {
    $("#formsubmit").click(function () {

        var iframe = $('<iframe name="postframe" id="postframe" class="hidden" src="about:none" />');

        $('div#iframe').append(iframe);

        $('#theuploadform').attr("action", "/ajax/user.asmx/Upload")
        $('#theuploadform').attr("method", "post")
        $('#theuploadform').attr("userfile", $('#userfile').val())
        $('#theuploadform').attr("enctype", "multipart/form-data")
        $('#theuploadform').attr("encoding", "multipart/form-data")
        $('#theuploadform').attr("target", "postframe")
        $('#theuploadform').submit();
        //need to get contents of the iframe

        $("#postframe").load(
            function () {
                iframeContents = $("iframe")[0].contentDocument.body.innerHTML;
                $("div#textarea").html(iframeContents);
            }
        );
    }
);


<div id="uploadform">
    <form id="theuploadform" action="">
        <input id="userfile" name="userfile" size="50" type="file" />
        <input id="formsubmit" type="submit" value="Send File" />
    </form>
</div>

<div id="iframe" style="width: 0px; height: 0px; display: none;">
</div>

<div id="textarea">
</div>

Answers:

Answer

It's not an official plugin, however here's an example on how you could wrap the form's submitting logic into a plugin.

Example:

<form method="post" enctype="multipart/form-data">
    <input name="file" type="file" />

    <input type="text" name="test" />

    <button type="submit">Submit</button>
</form>

<script>
    $('form').submit(function (e) {

        //prevent default submit
        e.preventDefault();

        //submit through frame
        $(this).frameSubmit({
            done: function (form, frame, options) {
                console.log('done!');
            },
            fail: function (form, frame, options) {
                console.log('fail!');
            },
            always: function (form, frame, options) {
                console.log('always!');
            }

            //custom hasError implementation if needed
            //by default if the frame's body HTML contains the text "unexpected error" or "server error"
            //it is treated as an error
            /*,hasError: function (frame) {
                return false;
            }*/
        });
    });

</script>

PLUGIN

!function ($, doc) {
    var _frameCount = 0,
        _callbackOptions = ['done', 'fail', 'always'],
        _hasFailed = function (frame) {
            var frameHtml = $(frame).contents().find('body').html();

            return /(server|unexpected)\s+error/i.test(frameHtml);
        },
        _createFrame = function () {
            return $('<iframe>').prop('name', 'jq-frame-submit-' + _frameCount++).hide().appendTo(doc.body);
        };

    $.fn.extend({
        frameSubmit: function (options) {

            return this.each(function () {
                var deferred = $.Deferred(),
                    form = this,
                    initialTarget = form.target,
                    hasTarget = form.hasAttribute('target'),
                    hasFailed = options.hasFailed || _hasFailed,

                    //The initial frame load will fire a load event so we need to
                    //wait until it fires and then submit the form in order to monitor
                    //the form's submission state.
                    $frame = _createFrame().one('load', function () {
                        $frame.one('load', function () {
                            deferred[hasFailed(this) ? 'reject' : 'resolve'](form, this, options);
                            $frame.remove();
                        });

                        form.submit();

                        //restore initial target attribute's value
                        if (hasTarget) form.target = initialTarget;
                        else form.removeAttribute('target');
                    });

                //attach handlers to the deferred
                $.each(_callbackOptions, function (i, optName) {
                    options[optName] && deferred[optName](options[optName]);
                });

                //make sure the form gets posted the to iframe
                form.target = $frame.prop('name');
            });
        }
    });
}(jQuery, document);
Answer

Your form target should be the same as iframe name, for example:

<form target="frame" 
      action="http://posttestserver.com/post.php?dir=example" 
      method="post"
      enctype="multipart/form-data">
    <input name="file" type="file"/>
</form>

<iframe name="frame"></iframe>

And after this you can attach event to input button to listen for 'change'. Furthemore you can get progress from server using jsonp and all of this will work in any browser event IE3+. Something like this:

$('input').change(function () {
    $('form').submit();
});

$.getJSON('/echo/jsonp/?callback=?', function(e, progress) {
    console.log(progress);
});
Answer

This is a good plugin to upload files using ajax

http://jquery.malsup.com/form/#file-upload

Answer

You know instead of fetching the same item multiple times, why not just reuse it:

var form = $('#theuploadform');
form.attr("action", "/ajax/user.asmx/Upload");
form.attr("method", "post");
// and so on

What kind of error are you having? can you post it?

UPDATE

Since you cannot set the attribute yourself here is a work around:

Put the form in an iframe, and attach an onchange event to the input button. when the user select a file, you trigger the necessary code to upload the file (submit), then the parent window can close the iframe.

Answer

I found the solution. This code works:

<script type="text/javascript">

    $(document).ready(function () {

        $("#formsubmit").click(function () {

            var iframe = $('<iframe name="postiframe" id="postiframe" style="display: none"></iframe>');

            $("body").append(iframe);

            var form = $('#theuploadform');
            form.attr("action", "/upload.aspx");
            form.attr("method", "post");

            form.attr("encoding", "multipart/form-data");
            form.attr("enctype", "multipart/form-data");

            form.attr("target", "postiframe");
            form.attr("file", $('#userfile').val());
            form.submit();

            $("#postiframe").load(function () {
                iframeContents = this.contentWindow.document.body.innerHTML;
                $("#textarea").html(iframeContents);
            });

            return false;

        });

    });

</script>


<form id="theuploadform">
    <input id="userfile" name="userfile" size="50" type="file" />
    <input id="formsubmit" type="submit" value="Send File" />
</form>

<div id="textarea">
</div>

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.