JQuery 插件:一起使用 jquery-upload-progress 和 jquery 验证

发布于 2024-09-28 14:05:30 字数 5087 浏览 0 评论 0原文

我想在同一表单上使用这两个 JQuery 插件:

我想要的行为:

  1. 使用验证插件验证表单
  2. 如果没有错误,则启动上传和 uploadProgress 插件。如果出现错误,请显示它们并且不要启动 uploadProgress 插件。

这两个插件单独工作效果很好。当我将两者应用在同一张表格上时,如果一切正确,效果很好。当表单中存在错误时,uploadProgress 会启动(启动和上传函数运行),但实际上传不会。它显示的上传栏永远不会改变,因为表单未提交。

我认为问题来自于两个插件注册了一些东西来在按下提交按钮时执行。

这是我的 JavaScript(在第一个答案后更新,但问题仍然存在):

/* ---------------------------------
 * Parameters for the form validator
 * --------------------------------- */
$.validator.setDefaults({
        highlight: function(input) {
                $(input).addClass("highlight");
        },
        unhighlight: function(input) {
                $(input).removeClass("highlight");
        }
});

$(document).ready(function(){
    /* ----------------------
     * Validator registration
     * ---------------------- */
    $("#upload_form").validate({
        rules: {
            title: {
                required: true,
                minlength: 5,
                maxlength: 100
            },
            file: {
                required: true,
                accept: 'ogg|ogv|avi|mpe?g|mov|wmv|flv|mp4'
            }
        },
        messages: {
            title: {
                required: "Please enter a title for the video",
                minlength: jQuery.format("The title must be at least {0} characters long"),
                maxlength: jQuery.format("The title must be shorter than {0} characters")
            },
            file: {
                required: "Please choose a video file to upload",
                accept: "Please choose a valid video file (ogg, ogv, avi, mpg, mpeg, mov, flv, mp4)"
            }
        }
    });

    /* ---------------
     * Upload progress
     * --------------- */
    $('#upload_form').uploadProgress({
            /* scripts locations for safari */
            jqueryPath: "{{MEDIA_URL|default:'/media/'}}js/jquery.uploadProgress.js",
            uploadProgressPath: "{{MEDIA_URL|default:'/media/'}}js/jquery.uploadProgress.js",

            /* selector or element that will be updated */
            progressBar: "#progress_indicator",

            /* progress reports url */
            progressUrl: '/upload/progress/',

            /* function called just before starting the upload */
            start: function() {
                $("#upload_form").hide();
                filename = $("#id_file").val().split(/[\/\\]/).pop();
                fmts = gettext("Uploading %(filename)s...");
                dat = {
                    filename: filename
                };
                s = interpolate(fmts,dat,true);
                $("#progress_filename").html(s);
                $("#progress_container").show();
            },

            /* function called each time bar is updated */
            uploading: function(upload) {
                if (upload.percents >= 100) {
                    window.clearTimeout(this.timer);
                    fmts = gettext("Saving %(filename)s...");
                    dat = {
                        filename: filename
                    };
                    s = interpolate(fmts,dat,true);
                    $("#progress_filename").html(s);
                } else {
                    fmts = gettext("Uploading %(filename)s : %(percents)s%...");
                    dat = {
                        filename: filename,
                        percents: upload.percents
                    };
                    s = interpolate(fmts,dat,true);
                    $("#progress_filename").html(s);
                }
            },

            /* how often will bar be updated */
            interval: 1000
        });
});

以及相关的 HTML:

<form id="upload_form" action="/upload/" method="post" enctype="multipart/form-data">
        <label for="id_title">Title</label>: <input id="id_title" type="text" name="title"/>
        <br/>
        <label for="id_description">Description</label>: <input id="id_description" type="text" name="description" />
        <br/>

        <label for="id_file">File</label>: <input type="file" name="file" id="id_file" />
    </div>
    <div>
        <!-- <button type="submit" class="accept" >Submit</button> -->
        <input type="submit" value="Submit" />
    </div>
</form>


<div id="progress_container">
    <div id="progress_filename"></div>
    <div id="progress_bar">
        <div id="progress_indicator"></div>
    </div>
</div>

注意:progress_container div 在页面加载时通过 CSS 隐藏。

我对问题的临时解决方案是停用提交时的验证并仅使用其他事件,但我也想在提交时进行验证。

I would like to use these two JQuery plugins on the same form :

The behavior that I would like to have:

  1. Validate the form with the validation plugin
  2. If no error start the upload and the uploadProgress plugin. If errors, show them and don't start the uploadProgress plugin.

The two plugins work well separately. When I apply both on the same form, it works well if all is correct. When there are errors in the form, the uploadProgress starts (the start and uploading functions run) but the actual upload doesn't. It shows an upload bar that will never change because the form is not submitted.

I think that the problem comes from the fact that the two plugins register something to execute when the submit button is pressed.

Here is my JavaScript (updated after the first answer, but the problem is still here):

/* ---------------------------------
 * Parameters for the form validator
 * --------------------------------- */
$.validator.setDefaults({
        highlight: function(input) {
                $(input).addClass("highlight");
        },
        unhighlight: function(input) {
                $(input).removeClass("highlight");
        }
});

$(document).ready(function(){
    /* ----------------------
     * Validator registration
     * ---------------------- */
    $("#upload_form").validate({
        rules: {
            title: {
                required: true,
                minlength: 5,
                maxlength: 100
            },
            file: {
                required: true,
                accept: 'ogg|ogv|avi|mpe?g|mov|wmv|flv|mp4'
            }
        },
        messages: {
            title: {
                required: "Please enter a title for the video",
                minlength: jQuery.format("The title must be at least {0} characters long"),
                maxlength: jQuery.format("The title must be shorter than {0} characters")
            },
            file: {
                required: "Please choose a video file to upload",
                accept: "Please choose a valid video file (ogg, ogv, avi, mpg, mpeg, mov, flv, mp4)"
            }
        }
    });

    /* ---------------
     * Upload progress
     * --------------- */
    $('#upload_form').uploadProgress({
            /* scripts locations for safari */
            jqueryPath: "{{MEDIA_URL|default:'/media/'}}js/jquery.uploadProgress.js",
            uploadProgressPath: "{{MEDIA_URL|default:'/media/'}}js/jquery.uploadProgress.js",

            /* selector or element that will be updated */
            progressBar: "#progress_indicator",

            /* progress reports url */
            progressUrl: '/upload/progress/',

            /* function called just before starting the upload */
            start: function() {
                $("#upload_form").hide();
                filename = $("#id_file").val().split(/[\/\\]/).pop();
                fmts = gettext("Uploading %(filename)s...");
                dat = {
                    filename: filename
                };
                s = interpolate(fmts,dat,true);
                $("#progress_filename").html(s);
                $("#progress_container").show();
            },

            /* function called each time bar is updated */
            uploading: function(upload) {
                if (upload.percents >= 100) {
                    window.clearTimeout(this.timer);
                    fmts = gettext("Saving %(filename)s...");
                    dat = {
                        filename: filename
                    };
                    s = interpolate(fmts,dat,true);
                    $("#progress_filename").html(s);
                } else {
                    fmts = gettext("Uploading %(filename)s : %(percents)s%...");
                    dat = {
                        filename: filename,
                        percents: upload.percents
                    };
                    s = interpolate(fmts,dat,true);
                    $("#progress_filename").html(s);
                }
            },

            /* how often will bar be updated */
            interval: 1000
        });
});

And the related HTML:

<form id="upload_form" action="/upload/" method="post" enctype="multipart/form-data">
        <label for="id_title">Title</label>: <input id="id_title" type="text" name="title"/>
        <br/>
        <label for="id_description">Description</label>: <input id="id_description" type="text" name="description" />
        <br/>

        <label for="id_file">File</label>: <input type="file" name="file" id="id_file" />
    </div>
    <div>
        <!-- <button type="submit" class="accept" >Submit</button> -->
        <input type="submit" value="Submit" />
    </div>
</form>


<div id="progress_container">
    <div id="progress_filename"></div>
    <div id="progress_bar">
        <div id="progress_indicator"></div>
    </div>
</div>

Note : the progress_container div is hidden via CSS at page load.

My temporary fix for the problem was to deactivate the validation on submit and only use the other events, but I would like to validate on submit too.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不一样的天空 2024-10-05 14:05:30

问题是 jquery-plugin-validation 在 JQuery-upload-progress 使用“X-Progress-ID”标识符修改表单参数“action”之前提交表单。

要解决此问题,您需要以下解决方法:在初始化插件验证之前设置“X-Progress-ID”标识符,并将该标识符传递给 JQuery-upload-progress。

代码示例:

var UUID="";
for (i = 0; i < 32; i++) {  UUID += Math.floor(Math.random() * 16).toString(16); }
$("#myform").validate({
   rules:{....},
   submitHandler: function(form) {
        /* patch the form-action tag to include the progress-id if X-Progress-ID has been already added just replace it */
        if(old_id = /X-Progress-ID=([^&]+)/.exec($("#myform").attr("action"))) {
            var action = $("#myform").attr("action").replace(old_id[1], UUID);
            $("#myform").attr("action", action);
        } else {
            var action = $("#myform").attr("action");
            var action_sep = (action.lastIndexOf("?") != -1) ? "&": "?";
            $("#myform").attr("action", action + action_sep + "X-Progress-ID=" + UUID);
        }           

        form.submit();
   }
});

然后初始化 JQuery-upload-progress 并传递生成的 UUID

    $(" $("#myform").uploadProgress({
        uuid:  UUID,
        jqueryPath:....,
        uploadProgressPath:...,

,最后修复 jquery.uploadProgress.js
1) 在构造函数中添加 uuid

options = $.extend({
        uuid:   false,
        dataType: "json",
        interval: 2000,
        progressBar: "#progressbar",

2) 更改绑定功能:

        return this.each(function(){
        $(this).bind('submit', function() {
            var uuid = options.uuid;
            if(!options.uuid ){
                uuid = "";
                for (i = 0; i < 32; i++) { uuid += Math.floor(Math.random() * 16).toString(16); }
            }

            /* update uuid */
            options.uuid = uuid;
            /* start callback */
            options.start(uuid);

仅此而已。

Problem is that jquery-plugin-validation submits form before JQuery-upload-progress modify form param "action" with "X-Progress-ID" identifier.

To fix this problem you need following workaround: set "X-Progress-ID" identifier to form before initializing plugin-validation and pass this identifier to JQuery-upload-progress.

Code example:

var UUID="";
for (i = 0; i < 32; i++) {  UUID += Math.floor(Math.random() * 16).toString(16); }
$("#myform").validate({
   rules:{....},
   submitHandler: function(form) {
        /* patch the form-action tag to include the progress-id if X-Progress-ID has been already added just replace it */
        if(old_id = /X-Progress-ID=([^&]+)/.exec($("#myform").attr("action"))) {
            var action = $("#myform").attr("action").replace(old_id[1], UUID);
            $("#myform").attr("action", action);
        } else {
            var action = $("#myform").attr("action");
            var action_sep = (action.lastIndexOf("?") != -1) ? "&": "?";
            $("#myform").attr("action", action + action_sep + "X-Progress-ID=" + UUID);
        }           

        form.submit();
   }
});

Than initialize JQuery-upload-progress and pass generated UUID

    $(" $("#myform").uploadProgress({
        uuid:  UUID,
        jqueryPath:....,
        uploadProgressPath:...,

and finally fix at jquery.uploadProgress.js
1) add uuid at constructor

options = $.extend({
        uuid:   false,
        dataType: "json",
        interval: 2000,
        progressBar: "#progressbar",

2) change binding functionality:

        return this.each(function(){
        $(this).bind('submit', function() {
            var uuid = options.uuid;
            if(!options.uuid ){
                uuid = "";
                for (i = 0; i < 32; i++) { uuid += Math.floor(Math.random() * 16).toString(16); }
            }

            /* update uuid */
            options.uuid = uuid;
            /* start callback */
            options.start(uuid);

Thats all.

本王不退位尔等都是臣 2024-10-05 14:05:30

上传进度连接到提交事件。因此,您的表单首先“提交”,然后由验证停止。
如果您先注册验证,然后上传,它可能会起作用。

您还可以/应该检查是否在“开始”回调中开始上传。

顺便说一下:

$(document).ready(function() {
$(function() {

看起来有点太多了,它是同一个函数的 2 倍。

$(function() { 

应该可以正常工作。

这个“应该”可以工作:

$.validator.setDefaults({
    highlight: function(input) {
            $(input).addClass("highlight");
    },
    unhighlight: function(input) {
            $(input).removeClass("highlight");
    } });

    $(function() {
/* ----------------------
* Init form validation
* ---------------------- */
$("#upload_form").validate({
    rules: {
        title: {
            required: true,
            minlength: 5,
            maxlength: 100
        },
        file: {
            required: true,
            accept: 'ogg|ogv|avi|mpe?g|mov|wmv|flv|mp4'
        }
    },
    messages: {
        title: {
            required: "Please enter a title for the video",
            minlength: "The title must be at least 5 characters long",
            maxlength: "The title must be shorter than 100 characters"
        },
        file: {
            required: "Please choose a video file to upload",
            accept: "Please choose a valid video file (ogg, ogv, avi, mpg, mpeg, mov, flv, mp4)"
        }
    }
});

/* ---------------
 * Upload progress
 * --------------- */
$('#upload_form').uploadProgress({
    /* selector or element that will be updated */
    progressBar: "#progress_indicator",

    /* progress reports url */
    progressUrl: '/upload/progress/',

    /* function called just before starting the upload */
    start: function() {
        if (!$("#upload_form").valid()) {
           return false;
        }


        $("#upload_form").hide();
        $("#progress_filename").html("Uploading file...");
        $("#progress_container").show();
    },

    /* function called each time bar is updated */
    uploading: function(upload) {
        if (upload.percents >= 100) {
            window.clearTimeout(this.timer);
            $("#progress_filename").html(Saving file...);
        } else {
            $("#progress_filename").html("Uploading file : " + upload.percents + "%...");
        }
    },

    /* how often will bar be updated */
    interval: 1000
});
    });

The upload progress connectes to the submit event. And thus yiour form is "submitting" first and then stopped by the validation.
If you first register the validation and then the upload it might work.

You could/should also check wether to to start the upload at the "start" callback.

By the way:

$(document).ready(function() {
$(function() {

seens a bit to much, it's 2 times the same function.

$(function() { 

should work fine.

This "should" work:

$.validator.setDefaults({
    highlight: function(input) {
            $(input).addClass("highlight");
    },
    unhighlight: function(input) {
            $(input).removeClass("highlight");
    } });

    $(function() {
/* ----------------------
* Init form validation
* ---------------------- */
$("#upload_form").validate({
    rules: {
        title: {
            required: true,
            minlength: 5,
            maxlength: 100
        },
        file: {
            required: true,
            accept: 'ogg|ogv|avi|mpe?g|mov|wmv|flv|mp4'
        }
    },
    messages: {
        title: {
            required: "Please enter a title for the video",
            minlength: "The title must be at least 5 characters long",
            maxlength: "The title must be shorter than 100 characters"
        },
        file: {
            required: "Please choose a video file to upload",
            accept: "Please choose a valid video file (ogg, ogv, avi, mpg, mpeg, mov, flv, mp4)"
        }
    }
});

/* ---------------
 * Upload progress
 * --------------- */
$('#upload_form').uploadProgress({
    /* selector or element that will be updated */
    progressBar: "#progress_indicator",

    /* progress reports url */
    progressUrl: '/upload/progress/',

    /* function called just before starting the upload */
    start: function() {
        if (!$("#upload_form").valid()) {
           return false;
        }


        $("#upload_form").hide();
        $("#progress_filename").html("Uploading file...");
        $("#progress_container").show();
    },

    /* function called each time bar is updated */
    uploading: function(upload) {
        if (upload.percents >= 100) {
            window.clearTimeout(this.timer);
            $("#progress_filename").html(Saving file...);
        } else {
            $("#progress_filename").html("Uploading file : " + upload.percents + "%...");
        }
    },

    /* how often will bar be updated */
    interval: 1000
});
    });
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文