2010-11-17 6 views
6

J'ai un formulaire qui télécharge le fichier dans un iframe. J'aimerais tenir sa soumission jusqu'à ce que je vérifie si c'est valide avec ajax. Comment puis-je faire ceci ? Mon code met en pause la soumission et renvoie le résultat de la validation (actuellement juste une fonction fictive qui renvoie 'result': 'true') mais l'action 'submit' n'est pas effectuée. Aussi est-il normal qu'il faut ~ 2s pour afficher les données de réponse après avoir obtenu le statut de réponse 200?Soumettre un formulaire de soumission pour validation

Voici mon html:

<div id="message" style="background:black; width:400px; height:80px; display:none; color:white;"> 
</div> 
<h1>Submit</h1> 
<form action="{{upload_url}}" target="upload_target" method="POST" id="file_upload_form" enctype="multipart/form-data"> 
    {% render_upload_data upload_data %} 
    <table>{{ form }}</table>  
    <p> 
     <input type="hidden" maxlength="64" name="myfileid" value="{{ myfileid }}" > 
    </p> 
    <p> 
     <input type="submit" id="file_upload_submit" value="Submit" /> 
    </p> 
    <iframe id="upload_target" name="upload_target" src="" style="width:0;height:0;border:0px solid #fff;"></iframe> 
</form> 

Js:

$(function() { 

    $('#file_upload_submit').click(function(e){ 
     e.preventDefault(); 
     var fileUploadForm = document.getElementById('file_upload_form'); 

     $.ajax({ 
      type: "POST", 
      url: '/artifact/upload/check-form/', 
      data: 'foo=bar', 
      dataType: "json", 
      success: function(data){ 
       if(data['result'] == "true"){ 
        $("#message").show(); 
        $("#message").fadeIn(400).html('<span>'+data["message"]+'</span>'); 
        setTimeout(function(){ 
         $("#message").fadeOut("slow", function() { 
          $("#message").hide(); 
         }); 
        }, 1500); 
        $('#file_upload_form').attr('target','upload_target').submit(function(){ 
         alert('Handler for .submit() called.'); 
         return false; 
        }); 
       } 
       else{ 
        $("#message").show(); 
        $("#message").fadeIn(400).html('<span">'+data["message"]+'</span>'); 
        setTimeout(function(){ 
         $("#message").fadeOut("slow", function() { 
          $("#message").hide(); 
         }); 
        }, 1500);      
        return false; 
       } 
      } 
     }); 
     return false;   
    }); 

});  

</script> 

et lien: http://ntt.vipserv.org/artifact/


EDIT

Avec le code ci-dessous I Je suis en mesure d'effectuer la validation, puis lorsque le résultat est positif, le formulaire est soumis. Maintenant, si je code en dur cible pour le formulaire, mon alerte n'est pas affichée et je suis à peu près sûr que le téléchargement n'est pas effectué (malheureusement la liste des uploads est rafraichie tous les 8h je sais si ça marche depuis un moment). Si la cible n'est pas spécifiée, le fichier est téléchargé avec la redirection, de sorte que tout l'écouteur d'événement 'submit' est omis.

<script> 
    $('#fake_upload_submit').click(function(e){ 
     e.preventDefault(); 

     var fileUploadForm = document.getElementById('file_upload_form'); 
     fileUploadForm.addEventListener("submit", function() { 
      alert("sent in iframe"); 
      fileUploadForm.target = 'upload_target'; 
     }, false);  

     $.ajax({ 
      type: "POST", 
      url: '/artifact/upload/check-form/', 
      data: 'foo=bar', 
      dataType: "json", 
      success: function(data){ 
       if(data['result'] == "true"){ 
        $("#message").show(); 
        $("#message").fadeIn(400).html('<span>'+data["message"]+'</span>'); 
        setTimeout(function(){ 
         $("#message").fadeOut("slow", function() { 
          $("#message").hide(); 
         }); 
        }, 1500); 

        fileUploadForm.submit(); 

       } 
       else{ 
        $("#message").show(); 
        $("#message").fadeIn(400).html('<span">Response false</span>'); 
        setTimeout(function(){ 
         $("#message").fadeOut("slow", function() { 
          $("#message").hide(); 
         }); 
        }, 1500);      
        return false; 
       } 
      } 
     }); 
     return false;   
    }); 
</script> 

html:

<div id="message" style="background:black; width:400px; height:80px; display:none; color:white;"> 
</div> 
<h1>Submit</h1> 
<form action="{{upload_url}}" method="POST" target="" id="file_upload_form" enctype="multipart/form-data"> 
    {% render_upload_data upload_data %} 
    <table>{{ form }}</table>  
    <p> 
     <input type="hidden" maxlength="64" name="myfileid" value="{{ myfileid }}" > 
    </p> 
    <p> 
     <input type="submit" style="display:none" id="true_upload_submit" value="Submit" /> 
    </p>  
    <iframe id="upload_target" name="upload_target" src="" style="width:0;height:0;border:0px solid #fff;"></iframe> 
</form> 
    <p> 
     <input type="submit" id="fake_upload_submit" value="Submit" /> 
    </p> 

Répondre

0

Je pense que vous pourriez être plus penser la soumission de la forme, mais je pourrais aussi être en train de lire ce mal. Je peux également ne pas avoir tous les faits. Ne serait-il pas préférable de simplement soumettre le formulaire via l'appel ajax et de renvoyer le résultat de la soumission (validation échouée ou réussie)?

Code Pseudo:

jQuery:

var formData = data; 
ajax(formData); 

Traitement de formulaire:

if(valid) { 
    submit(formData); 
    return true; 
} else { 
    return false; 
} 

Je peux fournir le code réel si nécessaire.

+0

Vous ne pouvez pas publier un fichier en utilisant AJAX. – Guffa

+0

@Guffa - oui vous pouvez: http://api.jquery.com/jQuery.post/ –

+0

J'ai la situation suivante. Le fichier du formulaire sera envoyé à un serveur distant dans iframe. Le reste des champs va être utilisé pour créer une instance d'objet localement. Donc l'objet local ne sera créé que lorsque tous les champs seront correctement remplis. – mastodon

1

Après la validation, vous enregistrez un nouveau gestionnaire d'événements de soumission, mais il n'y a rien qui soumette le formulaire, vous devrez donc cliquer à nouveau sur le bouton pour le soumettre.

Vous pouvez simplement soumettre le formulaire au lieu d'ajouter un gestionnaire soumettre:

$('#file_upload_form').attr('target','upload_target').submit(); 
+0

J'ai un .submit dans la ligne 21. Juste ajouté l'alerte là pour vérifier si elle est traitée. Mais il n'est pas affiché:/ – mastodon

+0

@mastodon: L'ajout d'un gestionnaire pour l'événement submit ne soumet pas le formulaire. – Guffa

0

Il serait probablement plus facile pour vous (si peut-être plus ennuyeux pour vos utilisateurs) si vous avez utilisé XHR synchrone au lieu de asynchrone.

Vous pouvez également intercepter la soumission de formulaire à l'aide de JavaScript et l'envoyer en utilisant XHR ssi la validation côté serveur réussit.

0

Comment éviter le problème, avoir un bouton de soumission caché pour soumettre le formulaire et avoir un bouton visible qui commence la validation et si tout va bien alors il clique sur le bon bouton de soumission caché?

+0

cela peut être une solution, mais actuellement l'action .submit est en quelque sorte ignorée, donc mon formulaire ne sera pas soumis. – mastodon

+0

quand j'ai dit caché je voulais mettre style = "display: none" et ne pas mettre Visible = "False" sur le bouton si c'est ce que vous voulez dire – AndreasKnudsen

+0

http://paste.pocoo.org/show/292764/ celui-là aussi, mais l'alerte de soumettre n'est pas montrée. – mastodon

0

Guffa is correct.Je crois que le changement suivant fera fonctionner le premier script. Changer

     $('#file_upload_form').attr('target','upload_target').submit(function(){ 
         alert('Handler for .submit() called.'); 
         return false; 
        }); 

à

     $('#file_upload_form').attr('target','upload_target').submit(); 

C'est votre débogage qui a cassé la soumission. Si vous souhaitez conserver le débogage, modifiez le code:

     $('#file_upload_form').attr('target','upload_target').submit(function(){ 
         alert('Handler for .submit() called.'); 
         return true; 
        }).submit(); 

Vous devez appeler submit() seul pour déclencher l'événement de soumission. Si la fonction de soumission renvoie false, elle ne continuera pas, vous devez donc la renvoyer à true à la place.

Ceci est la troisième version de cette question que vous avez publiée. Je suis d'accord avec les autres que vous pouvez aborder votre problème d'une manière qui est trop compliquée. C'est un cas où vous voudrez peut-être éviter complètement JavaScript et optez pour un article HTML simple. Y at-il une raison impérieuse pour laquelle ce n'est pas une option?