如何只提交表单的输入文件提交文件和其他字段?

时间:2011-10-19 17:37:44

标签: php jquery html ajax

怎么了?

互联网上有很多关于制作ajax-jquery表单来上传图片的例子。像这样:

<form id="imageform" method="post" enctype="multipart/form-data" action='ajaximage.php'> 
<input type="file" name="photoimg" id="photoimg" />
</form>

使这个表单上传文件并不困难,但我需要别的东西。

我的表格比那个大一点。

示例:

<form id="imageform" method="post" enctype="multipart/form-data" action='ajaximage.php'> 
<input type="file" name="photoimg" id="photoimg" />
<input type="text" name="foo"/>
<input type="text" name="bar"/>
<input type="submit" value="FINALLY DO THE SUBMIT"/>
</form>

什么是重要的?

好吧,我希望文件输入字段上传文件onchange事件。但我不希望孔形式提交。还有其他领域需要完成,毕竟用户将进行最终提交。

我在后端没有问题,我的PHP引擎正在等待和工作,但我不知道如何在前端做到这一点。

任何sugestions?

3 个答案:

答案 0 :(得分:1)

要通过javascript提交文件,您必须先阅读其内容。不幸的是,用HTML4做不到这一点,HTML4没有任何读取本地文件的API。

但是有一种解决方法,基本上你需要将表单的动作重定向到隐藏的IFrame。因此,当提交带有文件字段的表单时,结果将显示在IFrame中。但由于它是隐藏的,用户不会看到它。使用Form标记的'target'属性可以实现此效果。

HTML:

<iframe id="blah"></iframe>
<form id="imageform" target="blah" method="post" enctype="multipart/form-data" action='ajaximage.php'> 
    <input type="file" name="photoimg"/>
    <input type="text" name="foo"/>
    <input type="text" name="bar"/>

    <input type="submit" value="FINALLY DO THE SUBMIT"/>
</form>

使用Javascript:

$('#imageform input').change(function () {
    // This is called when any input changes
    $(this)
        .siblings()
            .attr('disabled', '')  // Disable the other inputs
        .end()
            .parent()
                .submit() // Submit the form
            .end()
        .siblings()
            .removeAttr('disabled'); // Re-enable the inputs
});

当然,如果您不想写所有内容,可以使用jQuery plugin

答案 1 :(得分:1)

您可以使用target元素的<form>属性提交表单,而无需重新加载页面。仍会发送额外字段,但通过动态交换<form>属性(例如actionenctype),您可以确保将文件输入发送到您背后的某个位置 - 端。

我编写了一个简单的JavaScript + jQuery组件,可以让您快速设置AJAX上传器。它将自动处理属性更改并让您的后端触发前端的回调:

var uploader = {

    functionBegin: function () {},
    functionCallback: function () {},

    formID: '',
    formAction: '',

    buttonID: '',

    originalAction: '',
    originalTarget: '',
    originalEnctype: '',
    originalOnSubmit: '',

    isSetup: false,

    // Initializes the AJAX uploader
    init: function(formID, buttonID, formAction, beginFunction, callbackFunction) {

        // Sets up the optional callback functions
        this.functionBegin = beginFunction;
        this.functionCallback = callbackFunction;

        // Sets up the selectors and upload form atributes
        this.formID = formID;
        this.buttonID = buttonID;
        this.formAction = formAction;

        // If we haven't already, create the invisible IFRAME that our form will target
        if(!this.isSetup) {
            $(formID).append('<iframe id="AU_IFrame" name="AU_IFrame" src="about:blank" style="width:0;height:0;border:0px solid #fff;"></iframe>');
            this.isSetup = true;
        }

        // If a button selector was defined, we hook it's click event
        if(buttonID) {
            $(buttonID).click(function () {
                uploader.triggerBegin();
                return false;
            });
        }

    },

    // Begins the file upload
    triggerBegin: function() {

        // Backs up the original form attributes
        this.originalAction = $(this.formID).attr('action');
        this.originalTarget = $(this.formID).attr('target');
        this.originalEnctype = $(this.formID).attr('enctype');
        this.originalOnSubmit = $(this.formID).attr('onSubmit');

        // Sets up the form with our upload attributes
        $(this.formID).attr('action', this.formAction);
        $(this.formID).attr('target', 'AU_IFrame');
        $(this.formID).attr('enctype', 'multipart/form-data');

        // Call our 'on upload begin' callback, if defined
        if(this.functionBegin) {
            this.functionBegin();
        }

        // Submit the upload form
        $(this.formID).submit();

        // Now that it's already uploaded, revert back to the original attributes
        $(this.formID).attr('action', this.originalAction);
        $(this.formID).attr('target', this.originalTarget);
        $(this.formID).attr('enctype', this.originalEnctype);
        $(this.formID).attr('onSubmit', this.originalOnSubmit);

    },

    // This can be called from the back-end, will trigger the user-defined callback
    triggerCallback: function(params) {
        if(this.functionCallback) {
            this.functionCallback(params);
        }
    }


};

以下是有关如何在HTML表单中应用此内容的示例:

<form name="test" method="POST" action="regularForm.php">
    <input id="fileInput" name="fileInput" type="file" />
    <input type="text" name="foo" />
    <input type="text" name="bar" />
    <input type="submit" value="Send" />
</form>

<script type="text/javascript">
    $(function () {

        uploader.init(
            '#fileInput', // File field selector
            null, // Upload button selector (Optional, since we'll upload on change, this won't be needed here)
            'fileUpload.php', // Upload action
            function () { // Callback on upload begin (optional)
                alert("Starting upload!");
            }, 
            function (params) { // Callback on upload end/error (called by the back-end, optional)
                alert("Upload successful");
            }
        );

        $('#fileInput').change( upload.triggerBegin ); // automatically upload on file input change

    });
</script>

要正确触发回调,只需确保您的后端运行以下内容(假设您使用的是PHP):

$someParameter = "whatever you want to return in the callback";

echo '<script type="text/javascript">';
echo 'if(top.uploader && top.uploader.triggerCallback) { top.uploader.triggerCallback("'.$someParameter.'"); }';
echo '</script>';

您可以自然地调整参数以使其返回,例如,文件URL,上传状态,大小等。

对于其他解决方案,如果没有HTML5,唯一的选择是使用Flash / Silverlight / Java小程序或Google Gears插件,它们将处理文件的拾取和上传。有一堆jQuery插件可以实现所有替代方案作为渐进式回退:

答案 2 :(得分:0)