Bonjour les gens

J'ai un formulaire qui poste une image
Une barre de progression déclenché par un onclick

Problème lorsque je submit le formulaire, le onclick ne se lance pas...

Voici le code :

<!DOCTYPE html>
<html>
<head>
<script>

function _(el){
    return document.getElementById(el);
}
function envoisfichier(){
    var file = _("photo1").files[0];
    // alert(file.name+" | "+file.size+" | "+file.type);
    var formdata = new FormData();
    formdata.append("photo1", file);
    var ajax = new XMLHttpRequest();
    ajax.upload.addEventListener("progress", progressHandler, false);
    ajax.addEventListener("load", completeHandler, false);
    ajax.addEventListener("error", errorHandler, false);
    ajax.addEventListener("abort", abortHandler, false);
    ajax.open("POST", "file_upload_parser.php");
    ajax.send(formdata);
}
function progressHandler(event){
    _("controle").innerHTML = event.loaded+" bytes sur "+event.total;
    var percent = (event.loaded / event.total) * 100;
    _("progressBar").value = Math.round(percent);
    _("statut").innerHTML = "Un instant s'il vous plait..."+Math.round(percent)+"% ";
}
function completeHandler(event){
    _("statut").innerHTML = event.target.responseText;
    _("progressBar").value = 0;
}
function errorHandler(event){
    _("statut").innerHTML = "erreur d'envois";
}
function abortHandler(event){
    _("statut").innerHTML = "envois interropu";
}
</script>
</head>
<body>

<form id="upload_form" enctype="multipart/form-data" method="post" action="file_upload_parser.php">
  <input type="file" name="photo1" id="photo1"><br>
  <input type="submit" value="envois" onclick="envoisfichier()">

  <id="statut"><br/>
  <p id="controle"></p><br/>
  <progress id="progressBar" value="0" max="100" style="width:300px;"></progress>
</form>
</body>
</html>

Comment faire ?

18 réponses


utilisateur
Auteur
Réponse acceptée

Bon voila une solution avec un gif d'attente + un petit texte

<!doctype html>
<head>
  <title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
</head>
<body>

<form id="upload_form" enctype="multipart/form-data" method="post" action="file_upload_parser.php">
<input type="file" name="photo1" id="photo1"><br>
<input type="submit" id="submit" value="Envoyer"></input>
</form>
<div id="zoneTexte"><img src='../img/ajax-loader.gif' > envois en cours...</div>

<script>
    $("div#zoneTexte").hide();
       $("#upload_form").submit(function (){
            $("div#zoneTexte").show();
        });
</script>
</body>
</html>

C'est une solution par défaut mais elle me parrait valable.

Merci à Christophe Badoux et tout ceux qui m'on aidé

Bonjour,

je pense que le probleme vient du fait que lorsque tu cliques sur le bouton de soumission, le comportement par defaut du formulaire (a savoir envoyer les informations a la page definie dans l'attribut action) prend le dessus.

Pour contrer ca, il faut definir ta methode dans le onsubmit de <form> et surtout placer un event.preventDefault() pour annuler la soumission via la methode actuelle. Il va cependant te falloir faire une requete AJAX pour envoyer les informations.

oui effectivement quand je modifie le submit en button, la progression fonctionne mais je n'accède pas à la page d'après
J'ai tenté ceci :

<!DOCTYPE html>
<html>
<head>
<script>

function _(el){
    return document.getElementById(el);
}
function envoisfichier(){
    var file = _("photo1").files[0];
    // alert(file.name+" | "+file.size+" | "+file.type);
    var formdata = new FormData();
    formdata.append("photo1", file);
    var ajax = new XMLHttpRequest();
    ajax.upload.addEventListener("progress", progressHandler, false);
    ajax.addEventListener("load", completeHandler, false);
    ajax.addEventListener("error", errorHandler, false);
    ajax.addEventListener("abort", abortHandler, false);
    ajax.open("POST", "file_upload_parser.php");
    ajax.send(formdata);
}
function progressHandler(event){
    _("controle").innerHTML = event.loaded+" bytes sur "+event.total;
    var percent = (event.loaded / event.total) * 100;
    _("progressBar").value = Math.round(percent);
    _("statut").innerHTML = "Un instant s'il vous plait..."+Math.round(percent)+"% ";
}
function completeHandler(event){
    _("statut").innerHTML = event.target.responseText;
    _("progressBar").value = 0;
}
function errorHandler(event){
    _("statut").innerHTML = "erreur d'envois";
}
function abortHandler(event){
    _("statut").innerHTML = "envois interropu";
}

function go{

    document.forms['upload_form'].submit();
}

</script>
</head>
<body>

<form id="upload_form" enctype="multipart/form-data" method="post" action="file_upload_parser.php">
  <input type="file" name="photo1" id="photo1"><br>
  <input type="button" value="envois" onclick="envoisfichier(); go()">

  <id="statut"><br/>
  <p id="controle"></p><br/>
  <progress id="progressBar" value="0" max="100" style="width:300px;"></progress>
</form>
</body>
</html>

c'est idem sa semble etre soit l'un soit l'autre, le soucis c'est qu'il faut la progression puis l'accès à l'autre page...

Bonjour.
Pour commencer, en général, il ne faut faire appel qu'à une fonction dans le onclick en HTML.
Ensuite, tu n’interromps toujours pas l'action du bouton de soumission.

Heu.... oui mais du coup comment je peux faire pour réaliser en premier la progression du chargement et ensuite l'affichage de la page cible ?

Ha mais je suis en train de penser, je me demande si c'est la bonne démarche parce que le but est de faire patienter l'utilisateur durant l'upload du formulaire ?!? wow je suis perdu là lol...
En fait il n'y a pas de première phase "ulpload" puis "submit" je pense que je me trompe. C'est upload avec visualisation de la progression qu'il faut que je fasse.

Du coup Lartak et prbaron je ne dois pas interrompre l'action de soumission mais plutot avoir un visuel de celui ci ....

Désolé si cela n'est pas votre but, mais ne serait-il pas plus logique d'utiliser un plug-in plutôt que de réinventer la roue ? D'autant plus que d'expérience, l'upload est un element particulièrement sensible pour les browser (debuggage en vue). C'est encore pire lorsqu'on y ajoute des event preload.

Je pense qu'un plugin serait plus simple en effet. Ensuite, si tu dois interrompre l'acte de soumission habituel et lancer la requete via JS. C'est le seul moyen d'avoir un visuel pendant l'upload.

Ok. Je n'ai pas de grandes compétences en javasrcipt et le formulaire est déjà fait. Comme il est assez important avec des champs qui s'affichent celon des choix faits avec des listes déroulantes, ect... je suis pas très emballé pour tout revoir et soumettre le formulaire via JS.
Par contre, je pense que matérialiser l'attente avec un petit gif + un texte genre "Un instant s'il vous plait" pourrais convenir.
reste que j'ai toujours ce problème de devoir afficher une div contenant le gif+la phrase avec le onclick sur le submit...
Comment faire ?

Tu peux envoyer ton formulaire dans l'etat actuel. Les plug-in actuels proposent de poster ton form en POST via Ajax, donc aucune différence avec ton code.
Au fait, un truc me chifone dans ton onclick. Tu post ton fichier en ajax et direct tu post en Submit ton form ??? T'es pas sensé attendre le 100% de ton upload ? j'ajouterai une condition à ton go et en plus je l'ajouterai à la function completeHandler()

Désolé j'écris ce code vite fait sans garantie. Mais ca donne des idées j'éspère.

var sendForm = function(){
    var file = _("photo1").files[0];
    if(file){
        envoisfichier();
    } else {
        go();
    }
}

et ton function: completeHandler()

function completeHandler(event){
    _("statut").innerHTML = event.target.responseText;
    _("progressBar").value = 0;
    go();
}

l'action du lancement en jQuery

_('#sendForm').on('click', function(event){
    event.preventDefault();
    sendForm();
});

ton button donnerait ceci:

<button type="submit"  id="sendForm">Envois</button>

Merci Christophe, si si dans l'idéal c'est bien d'attendre le 100% de l'upload ce serais vraiment la solution parfaite. Je te remercie pour les éléménts que tu as fait je teste ça dessuite...

Voila ce que ça donne :

<!DOCTYPE html>
<html>
<head>
<script>
var sendForm = function(){
    var file = _("photo1").files[0];
    if(file){
        envoisfichier();
    } else {
        go();
    }
}

function _(el){
    return document.getElementById(el);
}

/*function envoisfichier(){
    var file = _("photo1").files[0];
    var formdata = new FormData();
    formdata.append("photo1", file);
    var ajax = new XMLHttpRequest();
    ajax.upload.addEventListener("progress", progressHandler, false);
    ajax.addEventListener("load", completeHandler, false);
    ajax.addEventListener("error", errorHandler, false);
    ajax.addEventListener("abort", abortHandler, false);
    ajax.open("POST", "file_upload_parser.php");
    ajax.send(formdata);
}*/

function progressHandler(event){
    _("controle").innerHTML = event.loaded+" bytes sur "+event.total;
    var percent = (event.loaded / event.total) * 100;
    _("progressBar").value = Math.round(percent);
    _("statut").innerHTML = "Un instant s'il vous plait..."+Math.round(percent)+"% ";
}

function completeHandler(event){
    _("statut").innerHTML = event.target.responseText;
    _("progressBar").value = 0;
    go();
}

function errorHandler(event){
    _("statut").innerHTML = "erreur d'envois";
}

function abortHandler(event){
    _("statut").innerHTML = "envois interropu";
}

function go{
    document.forms['upload_form'].submit();
}

_('#sendForm').on('click', function(event){
    event.preventDefault();
    sendForm();
});
</script>
</head>
<body>

<form id="upload_form" enctype="multipart/form-data" method="post" action="file_upload_parser.php">
  <input type="file" name="photo1" id="photo1"><br>
  <!--<input type="button" value="envois" onclick="envoisfichier()">-->
  <button type="submit"  id="sendForm">Envois</button>

  <id="statut"><br/>
  <p id="controle"></p><br/>
  <progress id="progressBar" value="0" max="100" style="width:300px;"></progress>
</form>
</body>
</html>

Au submit du formulaire, ça poste l'image hein ça c'est ok mais sans afficher la progression. C'est due au fait que du coup le boutton étant un submit ça poste le formulaire directement non ?

Tu ne fais à aucun moment le traitement du formulaire en Javascript.
Pour qu'il n'y ait pas de rechargement de la page, il te faut faire le traitement du formulaire via Javascript pour envoyer les données à ton fichier file_upload_parser.php.
Apprends comment faire pour envoyer des données d'un formulaire à un fichier et en récupérer une réponse, selon si le traitement s'est bien passé ou non du coté PHP.

<!DOCTYPE html>
<html>
<head>
<script>
var sendForm = function(){
    var file = _("photo1").files[0];
    if(file){
        envoisfichier();
    } else {
        go();
    }
}

function _(el){
    return document.getElementById(el);
}

function envoisfichier(){
    var file = _("photo1").files[0];
    var formdata = new FormData();
    formdata.append("photo1", file);
    var ajax = new XMLHttpRequest();
    ajax.upload.addEventListener("progress", progressHandler, false);
    ajax.addEventListener("load", completeHandler, false);
    ajax.addEventListener("error", errorHandler, false);
    ajax.addEventListener("abort", abortHandler, false);
    ajax.open("POST", "file_upload_parser.php");
    ajax.send(formdata);
}

function progressHandler(event){
    _("controle").innerHTML = event.loaded+" bytes sur "+event.total;
    var percent = (event.loaded / event.total) * 100;
    _("progressBar").value = Math.round(percent);
    _("statut").innerHTML = "Un instant s'il vous plait..."+Math.round(percent)+"% ";
}

function completeHandler(event){
    _("statut").innerHTML = event.target.responseText;
    _("progressBar").value = 0;
    go();
}

function errorHandler(event){
    _("statut").innerHTML = "erreur d'envois";
}

function abortHandler(event){
    _("statut").innerHTML = "envois interropu";
}

function go{
    document.forms['upload_form'].submit();
}

_('#sendForm').on('click', function(event){
    event.preventDefault();
    sendForm();
});
</script>
</head>
<body>

<form id="upload_form" enctype="multipart/form-data" method="post" action="file_upload_parser.php">
  <input type="file" name="photo1" id="photo1"><br>
  <!--<input type="button" value="envois" onclick="envoisfichier()">-->
  <button type="submit"  id="sendForm" >Envois</button>

  <id="statut"><br/>
  <p id="controle"></p><br/>
  <progress id="progressBar" value="0" max="100" style="width:300px;"></progress>
</form>
</body>
</html>

ok voila ce que je comprends :


_('#sendForm').on('click', function(event){
    event.preventDefault();
    sendForm();
});

au clic sur l'élément sendForm ça lance la fonction deux fonctions event.preventDefault(); qui annule toute les actions en cours PUIS sendForm();

var sendForm = function(){
    var file = _("photo1").files[0];
    if(file){
        envoisfichier();
    } else {
        go();
    }
}

sendForm(); met les informations de la photo1 en variable, si c'est un fichier, on va à la fonction envoisfichier() qui elle affiche normalement la barre de progression PUIS poste le formulaire et affiche la page cible file_upload_parser.php

J'ai bon ? hélas ça uplode l'image sans afficher la barre

A mais attend t'utilise carrement pas jQuery :/ T'as fais du JS brute. Ca faisait longtemps que j'avais pas revu ca ;)

corrige:

_('#sendForm').on('click', function(event){
    event.preventDefault();
    sendForm();
});

par

_('sendForm').click(function(){
    sendForm();
});

et le bouton change le par un type "button"
comme ça:

<button type="button"  id="sendForm">Envois</button>

Oui la condition verifie si il existe un fichier preloadé.

Lartak a peut-être raison, tu devrais regarder un peu du côté les actions JS côté form HTML.

Encore une chose privilegie le JS en pied de page et non dans la <head>, ca ralentit l'affichage. Oui je sais les standard blablabla. Mais bon en vrai la vie n'est pas toute rose, même pour le W3C. ;)

Voici le code actuel :

<!DOCTYPE html>
<html>
<head>

</head>
<body>

<form id="upload_form" enctype="multipart/form-data" method="post" action="file_upload_parser.php">
  <input type="file" name="photo1" id="photo1"><br>
  <!--<input type="button" value="envois" onclick="envoisfichier()">-->
<button type="button"  id="sendForm">Envois</button>

  <id="statut"><br/>
  <p id="controle"></p><br/>
  <progress id="progressBar" value="0" max="100" style="width:300px;"></progress>
</form>
</body>
<script>

var sendForm = function(){
    var file = _("photo1").files[0];
    if(file){
        envoisfichier();
    } else {
        go();
    }
}

function _(el){
    return document.getElementById(el);
}

function envoisfichier(){
    var file = _("photo1").files[0];
    var formdata = new FormData();
    formdata.append("photo1", file);
    var ajax = new XMLHttpRequest();
    ajax.upload.addEventListener("progress", progressHandler, false);
    ajax.addEventListener("load", completeHandler, false);
    ajax.addEventListener("error", errorHandler, false);
    ajax.addEventListener("abort", abortHandler, false);
    ajax.open("POST", "file_upload_parser.php");
    ajax.send(formdata);
}

function progressHandler(event){
    _("controle").innerHTML = event.loaded+" bytes sur "+event.total;
    var percent = (event.loaded / event.total) * 100;
    _("progressBar").value = Math.round(percent);
    _("statut").innerHTML = "Un instant s'il vous plait..."+Math.round(percent)+"% ";
}

function completeHandler(event){
    _("statut").innerHTML = event.target.responseText;
    _("progressBar").value = 0;
    go();
}

function errorHandler(event){
    _("statut").innerHTML = "erreur d'envois";
}

function abortHandler(event){
    _("statut").innerHTML = "envois interropu";
}

function go{
    document.forms['upload_form'].submit();
}

_('sendForm').click(function(){
    sendForm();
});

</script>
</html>

Je me suis noté de mettre le code JS en pied de page. Bon je vais regarder parceque là ni l'upload ni la barre ne fonctionne.
Disons que là c'est juste un besoin ponctuel je me disais pas besoin de savoir changer un moteur pour changer l'ampoule du phare... mais effectivement il conviens d'avoir les notions de base j'entends bien

Attention: tu dois mettre dans le body. Non en effet cela ne fonctionnera pas. En fait la déclaration de tes variables m'a fait pensé à jQuery du coup oublie ça :

_('sendForm').click(function(){
    sendForm();
});

et met directement

<button type="button" onclick="sendForm();">Envois</button>

Après c'est tjr compliqué de coder sans analyser le code au complet. Encore pire quand la personne en face n'est pas à l'aise avec le sujet ;)

:-) Tu as raison
J'ai testé et ça ne fonctionne toujours pas.
C'est pourquoi je laisse tomber je perd trop de temps avec ça. Par contre il faut toujours que l'utilisateur puisse avoir un visuel quelquonque de l'uplod du formulaire

Donc j'ai regardé ce matin un code minimaliste qui conviendrais peux-tu me dire ce que tu en pense ...

<!doctype html>
<head>
  <title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
</head>
<body>

<form id="upload_form" enctype="multipart/form-data" method="post" action="file_upload_parser.php">
<input type="file" name="photo1" id="photo1"><br>
<input type="submit" id="submit" value="Envoyer"></input>
</form>
<div id="zoneTexte">envois en cours...</div>

<script>
    $("div#zoneTexte").hide(); 
        if $("#upload_form").submit(function (){
            $("div#zoneTexte").show();
        });
</script>
</body>
</html>

ça ne fonctionne pas mais je me dit que 4 lignes à débuguer ce serais plus facile

Le but est d'afficher un texte pendant l'upload du formulaire et avant qu'il redirige sur la page cible file_upload_parser.php