web-dev-qa-db-fra.com

Plusieurs boutons de soumission sur le formulaire HTML - désignez un bouton par défaut

J'ai un formulaire qui a trois boutons d'envoi comme suit:

<input type="submit" name="COMMAND" value="&lsaquo; Prev">
<input type="submit" name="COMMAND" value="Save">
<input type="reset"  name="NOTHING" value="Reset">
<input type="submit" name="COMMAND" value="Next &rsaquo;">
<input type="button" name="NOTHING" value="Skip &rsaquo;" onclick="location = 'yada-yada.asp';">

La rangée de boutons est un mélange de boutons de soumission, de réinitialisation et de JavaScript. L'ordre des boutons est sujet à changement, mais dans tous les cas, le bouton de sauvegarde reste entre les boutons précédents et suivants.

Le problème ici est que lorsqu'un utilisateur appuie sur Enter pour soumettre le formulaire, la variable de poste "COMMAND" contient "Prev"; normal, car il s’agit du premier bouton de soumission du formulaire. Je souhaite toutefois que le bouton "Suivant" soit déclenché lorsque l'utilisateur soumet le formulaire via le Enter bouton. C'est un peu comme si vous le définissiez comme bouton d'envoi par défaut, même si d'autres boutons l'avaient précédé.

126
Salman A

Ma suggestion est de ne pas combattre ce comportement. Vous pouvez effectivement modifier l'ordre en utilisant des flotteurs. Par exemple:

<p id="buttons">
<input type="submit" name="next" value="Next">
<input type="submit" name="prev" value="Previous">
</p>

avec:

#buttons { overflow: hidden; }
#buttons input { float: right; }

va effectivement inverser l'ordre et donc le bouton "Suivant" sera la valeur déclenchée en appuyant sur entrer.

Ce type de technique couvrira de nombreuses circonstances sans avoir à recourir à des méthodes JavaScript plus sophistiquées.

73
cletus

Le premier bouton est toujours le bouton par défaut; ça ne peut pas être changé. Pendant que vous pouvez essayez de résoudre le problème avec JavaScript, le formulaire se comportera de manière inattendue dans un navigateur Web sans script, et vous devrez réfléchir à certains cas. Par exemple, le code lié à par Zoran soumettra accidentellement le formulaire lorsqu’il entrera Appuyez sur dans un fichier <input type="button">, ce qui ne se produirait normalement pas et n'attraperait pas le comportement d'IE en soumettant le formulaire pour Entrée, appuyez sur un autre contenu du champ que le champ. Donc, si vous cliquez sur du texte dans un <p> dans le formulaire contenant ce script et appuyez sur Entrée, le mauvais bouton sera soumis ... particulièrement dangereux si, comme indiqué dans cet exemple, le véritable bouton par défaut est "Supprimer"!

Mon conseil serait d'oublier d'utiliser des hacks de script pour réaffecter des valeurs par défaut. Suivez le flux du navigateur et mettez simplement le bouton par défaut en premier. Si vous ne pouvez pas modifier la présentation pour vous donner l'ordre à l'écran souhaité, vous pouvez le faire en disposant d'abord un bouton invisible factice dans la source, avec le même nom/la même valeur que le bouton que vous souhaitez utiliser par défaut:

<input type="submit" class="defaultsink" name="COMMAND" value="Save" />

.defaultsink {
    position: absolute; left: -100%;
}

(Remarque: le positionnement est utilisé pour pousser le bouton hors écran car display: none et visibility: hidden ont des effets secondaires variables sur le navigateur selon que le bouton est pris par défaut ou non.)

80
bobince

Quick'n'dirty, vous pouvez créer une copie cachée du bouton d'envoi, qui devrait être utilisé en appuyant sur entrée.

Exemple CSS

input.hidden {
    width: 0px;
    height: 0px;
    margin: 0px;
    padding: 0px;
    outline: none;
    border: 0px;
}

Exemple HTML

<input type="submit" name="next" value="Next" class="hidden" />
<input type="submit" name="prev" value="Previous" />
<input type="submit" name="next" value="Next" />

Si quelqu'un tape maintenant dans votre formulaire, le bouton (caché) suivant sera utilisé comme émetteur.

Testé sur IE9, Firefox, Chrome et Opera

35
scotty86

Ensemble type=submit au bouton que vous souhaitez utiliser par défaut et type=button à d'autres boutons. Maintenant, dans le formulaire ci-dessous, vous pouvez appuyer sur la touche Entrée dans n’importe quel champ, et le bouton Render fonctionnera (même s’il s’agit du deuxième bouton du formulaire).

Exemple:

    <button id='close_button' class='btn btn-success'
            type=button>
      <span class='glyphicon glyphicon-edit'> </span> Edit program
    </button>
    <button id='render_button' class='btn btn-primary'
            type=submit>             <!--  Here we use SUBMIT, not BUTTON -->
      <span class='glyphicon glyphicon-send'> </span> Render
    </button>

Testé dans FF24 et Chrome 35.

34
dmitry_romanov

Si vous utilisez jQuery, cette solution issue d'un commentaire fait ici est plutôt astucieuse:

$(function(){
    $('form').each(function () {
        var thisform = $(this);
        thisform.prepend(thisform.find('button.default').clone().css({
            position: 'absolute',
            left: '-999px',
            top: '-999px',
            height: 0,
            width: 0
        }));
    });
});

Il suffit d'ajouter class="default" au bouton que vous voulez utiliser par défaut. Il place une copie cachée de ce bouton au tout début du formulaire.

28
Dave

Je le ressuscite parce que je cherchais une méthode non JavaScript pour le faire. Je ne faisais pas partie des gestionnaires de clés, et le système de positionnement CSS entraînait la rupture de l'ordre des tabulations, le repositionnement CSS ne changeant pas cet ordre.

Ma solution est basée sur la réponse à https://stackoverflow.com/a/9491141 .

La source de la solution est ci-dessous. tabindex est utilisé pour corriger le comportement du bouton caché dans les tabulations, ainsi que pour aria-hidden afin d'éviter que le bouton ne soit lu par des lecteurs d'écran/identifiés par des aides techniques.

<form method="post" action="">
  <button type="submit" name="useraction" value="2nd" class="default-button-handler" aria-hidden="true" tabindex="-1"></button>
  <div class="form-group">
    <label for="test-input">Focus into this input: </label>
    <input type="text" id="test-input" class="form-control" name="test-input" placeholder="Focus in here and press enter / go" />
  </div>

1er bouton dans DOM 2ème bouton dans DOM 3ème bouton dans DOM

CSS essentiel pour cette solution:

.default-button-handler {
  width: 0;
  height: 0;
  padding: 0;
  border: 0;
  margin: 0;
}
5
Shan Plourde

Une autre solution, utilisant jQuery:

$(document).ready(function() {
  $("input").keypress(function(e) {
    if (e.which == 13) {
      $('#submit').click();
      return false;
    }

    return true;
  });
});

Cela devrait fonctionner sur les formulaires suivants, faisant de "Update" l'action par défaut:

<form name="f" method="post" action="/action">
  <input type="text" name="text1" />
  <input type="submit" name="button2" value="Delete" />
  <input type="submit" name="button1" id="submit" value="Update" />
</form>

Aussi bien que:

<form name="f" method="post" action="/action">
  <input type="text" name="text1" />
  <button type="submit" name="button2">Delete</button>
  <button type="submit" name="button1" id="submit">Update</button>
</form>

Cela intercepte la touche Entrée uniquement lorsqu'un champ de saisie du formulaire est activé.

1
Dave Jarvis

Vous ne devriez pas utiliser de boutons du même nom. C'est une mauvaise sémantique. Au lieu de cela, vous devriez modifier votre backend pour rechercher différentes valeurs de nom en cours de définition:

<input type="submit" name="COMMAND_PREV" value="&lsaquo; Prev">
<input type="submit" name="COMMAND_SAVE" value="Save">
<input type="reset"  name="NOTHING" value="Reset">
<input type="submit" name="COMMAND_NEXT" value="Next &rsaquo;">
<input type="button" name="NOTHING" value="Skip &rsaquo;" onclick="window.location = 'yada-yada.asp';">

Puisque je ne sais pas quelle langue vous utilisez sur le backend, je vais vous donner un pseudocode:

if (input name COMMAND_PREV is set) {

} else if (input name COMMAND_SAVE is set) {

} else if (input name COMMENT_NEXT is set) {

}
0
Corey Ballou