views:

15

answers:

1

Hi !

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.

A: 

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
});
    });
Milo
Unfortunately it does not work. I tried putting both in the same $(document).ready() to make sure to register the validation before the upload progress. I have exactly the same behavior. You can see the first message to have the updated code.
Marc Demierre
The problem with the start function of the upload progress is that even if I check the validation inside it, I don't know how to stop it and the uploading function is called and throws errors.
Marc Demierre
I've added a 'check if valid' to the start function of the upload plugin, maybe that will work?
Milo