2010-10-21 5 views
0

Je voudrais utiliser ces deux plugins JQuery sur la même forme:plugins JQuery: Utilisez jquery-upload-progress et validation jquery ensemble

Le comportement que je voudrais avoir:

  1. Validez le formulaire avec le plugin de validation
  2. Si aucune erreur ne démarre le téléchargement et le plugin uploadProgress. En cas d'erreur, affichez-les et ne démarrez pas le plugin uploadProgress.

Les deux plugins fonctionnent bien séparément. Quand j'applique les deux sur le même formulaire, cela fonctionne bien si tout est correct. Lorsque le formulaire contient des erreurs, le fichier uploadProgress démarre (les fonctions de démarrage et de chargement s'exécutent), mais pas le téléchargement réel. Il montre une barre de téléchargement qui ne changera jamais parce que le formulaire n'est pas soumis.

Je pense que le problème vient du fait que les deux plugins enregistrent quelque chose à exécuter quand le bouton submit est pressé.

Voici mon JavaScript (mis à jour après la première réponse, mais le problème est toujours là):

/* --------------------------------- 
* 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 
     }); 
}); 

Et le code HTML connexe:

<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: la div progress_container est caché par CSS au chargement de la page.

Mon correctif temporaire pour le problème était de désactiver la validation sur submit et d'utiliser uniquement les autres événements, mais je voudrais aussi valider sur submit.

Répondre

1

Le problème est que jquery-plugin-validation soumet le formulaire avant JQuery-upload-progress modifier la forme PARAM "action" avec identifiant "X-Progress-ID".Pour résoudre ce problème, vous avez besoin d'une solution de contournement: définissez l'identificateur "X-Progress-ID" à formater avant d'initialiser la validation du plugin et transmettez cet identificateur à JQuery-upload-progress.

Exemple de code:

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 et passe généré UUID

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

et enfin fixer à jquery.uploadProgress.js 1) ajouter UUID au constructeur

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

2) modifier la fonctionnalité de liaison:

 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); 

C'est tout.

+0

Malheureusement je n'ai plus accès au code, c'était en 2010 ... Donc je ne peux pas tester ta réponse, désolé. Avez-vous pu le tester avec succès? –

+0

Oui, je rencontre le même problème. et cette solution le corrige. – duzvik

0

La progression du téléchargement se connecte à l'événement de soumission. Et ainsi votre forme est "soumission" d'abord et ensuite arrêtée par la validation. Si vous enregistrez d'abord la validation, puis le téléchargement, cela pourrait fonctionner.

Vous pouvez/devriez aussi vérifier si vous voulez démarrer le téléchargement au rappel "start".

Soit dit en passant:

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

Seens un peu à beaucoup, il est 2 fois la même fonction.

$(function() { 

devrait fonctionner correctement.

Ce "devrait" travail:

$.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 
}); 
    }); 
+0

Malheureusement, cela ne fonctionne pas. J'ai essayé de mettre les deux dans le même $ (document) .ready() pour m'assurer d'enregistrer la validation avant la progression du téléchargement. J'ai exactement le même comportement. Vous pouvez voir le premier message pour avoir le code mis à jour. –

+0

Le problème avec la fonction de démarrage de la progression du téléchargement est que même si je vérifie la validation à l'intérieur, je ne sais pas comment l'arrêter et la fonction de téléchargement est appelée et émet des erreurs. –

+0

J'ai ajouté un 'cocher si valide' à la fonction de démarrage du plugin de téléchargement, peut-être que cela fonctionnera? – Milo