Comment le bouton Soumettre par défaut sur un formulaire HTML est-il déterminé?
si un formulaire est présenté mais pas par un bouton spécifique, tel que
- en appuyant sur inscrire
- utilisant
HTMLFormElement.submit()
dans JS
comment un navigateur est-il censé déterminer lequel des boutons soumettre multiples, le cas échéant, à utiliser comme celui appuyé?
ceci est significatif à deux niveaux:
- l'appel d'un
onclick
événement handler attaché à un bouton Soumettre - les données renvoyées au serveur web
Mes expériences jusqu'à présent ont montré que:
- en appuyant sur entrer , Firefox, Opera et Safari utiliser le premier bouton Soumettre dans le formulaire
- en appuyant sur entrer , C'est-à-dire utilise soit le premier bouton Soumettre ou aucun selon les conditions que je n'ai pas été capable de comprendre
- tous ces navigateurs n'utilisent aucun pour un js submit
que dit la norme?
si cela pouvait aider, voici mon code de test (Le PHP n'est pertinent que pour ma méthode de test, pas pour ma question elle-même)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Test</title>
</head>
<body>
<h1>Get</h1>
<dl>
<?php foreach ($_GET as $k => $v) echo "<dt>$k</dt><dd>$v</dd>"; ?>
</dl>
<h1>Post</h1>
<dl>
<?php foreach ($_POST as $k => $v) echo "<dt>$k</dt><dd>$v</dd>"; ?>
</dl>
<form name="theForm" method="<?php echo isset($_GET['method']) ? $_GET['method'] : 'get'; ?>" action="<?php echo $_SERVER['SCRIPT_NAME']; ?>">
<input type="text" name="method" />
<input type="submit" name="action" value="Button 1" onclick="alert('Button 1'); return true" />
<input type="text" name="stuff" />
<input type="submit" name="action" value="Button 2" onclick="alert('Button 2'); return true" />
<input type="button" value="submit" onclick="document.theForm.submit();" />
</form>
</body></html>
14 réponses
si vous soumettez le formulaire par Javascript (c.-à-d. formElement.submit()
ou quelque chose d'équivalent), alors aucun des boutons soumettre sont considérés comme réussis et aucune de leurs valeurs ne sont incluses dans les données soumises. (Notez que si vous soumettez le formulaire en utilisant submitElement.click()
, alors le fichier soumettre auquel vous avez fait référence est considéré comme actif; ceci n'entre pas vraiment dans le champ de votre question puisque ici le bouton Soumettre est sans ambiguïté, mais j'ai pensé que je l'inclurais pour les personnes qui lisent la première partie et se demandent comment faire un bouton Soumettre réussie via la soumission de formulaire JS. Bien sûr, les manipulateurs du formulaire vont continuer à tirer de cette façon alors qu'ils ne le feraient pas via form.submit()
donc c'est une autre bouilloire de poisson...)
si le formulaire est soumis en tapant entrée alors que dans un champ non-textarea, alors c'est en fait à l'agent utilisateur de décider ce qu'il veut ici. Le specs ne dit rien sur la soumission d'un formez en utilisant la touche enter dans un champ de saisie de texte (si vous appuyez sur un bouton et l'activez en utilisant l'espace ou autre, alors il n'y a aucun problème puisque ce bouton de soumission spécifique est utilisé sans ambiguïté). Tout ce qu'il dit, c'est qu'un formulaire doit être soumis quand un bouton Soumettre est activé, ce n'est même pas une exigence que de frapper entrée par exemple un texte entrée soumettra le formulaire.
je crois Qu'Internet Explorer choisit le bouton Soumettre qui apparaît en premier dans la source; j'ai un sentant que Firefox et Opera choisissent le bouton avec le tabindex le plus bas, retombant sur le premier défini si rien d'autre n'est défini. Il y a aussi des complications à savoir si les submits ont un attribut de valeur non par défaut IIRC.
ce qu'il faut retenir, c'est qu'il n'y a pas de norme définie pour ce qui se passe ici et que c'est entièrement au gré du navigateur - donc, autant que possible, dans ce que vous faites, essayez d'éviter de vous fier à un comportement particulier. Si vous devez vraiment savoir, vous pouvez probablement découvrir le comportement des différentes versions de navigateur mais quand j'ai examiné cela il y a un certain temps il y avait quelques conditions assez alambiquées (qui sont bien sûr sujettes à changement avec les nouvelles versions de navigateur) et je vous conseille de l'éviter si possible!
Andrezj l'a presque cloué... Mais voici une solution de navigation croisée facile.
prendre une forme comme celle-ci:
<form>
<input/>
<button type="submit" value="some non-default action"/>
<button type="submit" value="another non-default action"/>
<button type="submit" value="yet another non-default action"/>
<button type="submit" value="default action"/>
</form>
et réfacteur à ceci:
<form>
<input/>
<button style="overflow: visible !important; height: 0 !important; width: 0 !important; margin: 0 !important; border: 0 !important; padding: 0 !important; display: block !important;" type="submit" value="default action"/>
<button type="submit" value="some non-default action"/>
<button type="submit" value="another non-default action"/>
<button type="submit" value="yet another non-default action"/>
<button type="submit" value="still another non-default action"/>
<button type="submit" value="default action"/>
</form>
étant donné que la spécification du W3C indique que plusieurs boutons de soumission sont valides, mais omet les conseils sur la façon dont l'agent-utilisateur devrait les traiter, les fabricants de navigateur sont laissés à mettre en œuvre comme ils le jugent bon. J'ai trouvé qu'ils vont soumettre la première soumettre bouton dans le formulaire, ou soumettre le prochain bouton Soumettre après le champ formulaire qui a actuellement focus.
malheureusement, il suffit d'ajouter un style d'affichage : aucun; ne fonctionnera pas car la spécification W3C indique qu'un élément caché doit être exclu des interactions avec les utilisateurs. Alors cache-le à la vue de tous!
ci-dessus est un exemple de la solution que j'ai fini par mettre en production. La touche Entrée déclenche la forme par défaut la soumission est un comportement comme prévu, même si d'autres valeurs non par défaut sont présentes et précèdent le bouton Soumettre par défaut dans le DOM. Bonus pour l'interaction souris / clavier avec des entrées explicites de l'utilisateur tout en évitant les gestionnaires javascript.
Remarque: l'utilisation de la tabulation à travers le formulaire ne sera pas afficher le focus pour tout élément visuel encore va encore causer le bouton invisible pour être sélectionné. Pour éviter ce problème, il suffit de définir les attributs tabindex en conséquence et d'omettre un attribut tabindex sur le le bouton Soumettre invisible. Alors qu'il peut sembler déplacé de promouvoir ces styles à !important, ils devrait empêcher tout cadre ou les styles de boutons existants d'interférer avec ce correctif. En outre, ces styles en ligne sont certainement mauvaise forme, mais nous sommes en train de prouver des concepts ici... ne pas écrire de code de production.
HTML 4 ne le rend pas explicite. Le projet de travail HTML5 actuel spécifie que le premier bouton Soumettre doit être le par défaut:
a
form
le bouton par défaut de l'élément est premier bouton Soumettre dans l'arbre de commande dont "1519120920 formulaire" propriétaire , c'est queform
élément.si l'agent utilisateur supporte la location l'utilisateur soumet un formulaire implicitement (par exemple, sur certaines plates-formes de frapper la touche "entrée" tout un champ de texte est centré implicitement soumet le formulaire), puis le faire pour un formulaire dont bouton par défaut a un défini activation du comportement doit faire en sorte que l'agent de l'utilisateur à exécuter les étapes d'activation de clic synthétique sur ce bouton par défaut .
je pense que ce post aurait de l'aide si quelqu'un veut le faire avec jQuery:
http://greatwebguy.com/programming/dom/default-html-button-submit-on-enter-with-jquery /
la solution de base est:
$(function() {
$("form input").keypress(function (e) {
if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
$('input[type=submit].default').click();
return false;
} else {
return true;
}
});
});
et un autre que j'ai aimé était:
jQuery(document).ready(function() {
$("form input, form select").live('keypress', function (e) {
if ($(this).parents('form').find('button[type=submit].default, input[type=submit].default').length <= 0)
return true;
if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
$(this).parents('form').find('button[type=submit].default, input[type=submit].default').click();
return false;
} else {
return true;
}
});
});
j'ai eu un formulaire avec 11 boutons soumettre sur elle, et il utiliserait toujours le premier bouton Soumettre lorsque l'Utilisateur a appuyé sur ENTRER. J'ai lu ailleurs qu'il n'est pas une bonne idée (mauvaise pratique) d'avoir plus d'un bouton submit d'un formulaire, et le meilleur moyen pour ce faire est le bouton que vous voulez tant que par défaut, comme le seul bouton de soumission du formulaire. Les autres boutons doivent être transformés en" TYPE=BUTTON " et un événement onClick ajouté qui appelle votre propre routine soumettre en Javascript. Quelque chose comme ceci :-
<SCRIPT Language="JavaScript">
function validform()
{
// do whatever you need to validate the form, and return true or false accordingly
}
function mjsubmit()
{
if (validform()) { document.form1.submit(); return true;}
return false;
}
</SCRIPT>
<INPUT TYPE=BUTTON NAME="button1" VALUE="button1" onClick="document.form1.submitvalue='button1'; return mjsubmit();">
<INPUT TYPE=BUTTON NAME="button2" VALUE="button2" onClick="document.form1.submitvalue='button2'; return mjsubmit();">
<INPUT TYPE=SUBMIT NAME="button3" VALUE="button3" onClick="document.form1.submitvalue='button3'; return validform();">
<INPUT TYPE=BUTTON NAME="button4" VALUE="button4" onClick="document.form1.submitvalue='button4'; return mjsubmit();">
ici, button3 est la valeur par défaut, et bien que vous soumettiez le formulaire avec les autres boutons, la routine mjsubmit Les valide. HTH.
cela peut maintenant être résolu en utilisant flexbox
:
HTML
<form>
<h1>My Form</h1>
<label for="text">Input:</label>
<input type="text" name="text" id="text"/>
<!-- Put the elements in reverse order -->
<div class="form-actions">
<button>Ok</button> <!-- our default action is first -->
<button>Cancel</button>
</div>
</form>
CSS
.form-actions {
display: flex;
flex-direction: row-reverse; /* reverse the elements inside */
}
explication
En utilisant flex box, nous pouvons inverser l'ordre des éléments dans un conteneur qui utilise display: flex
en utilisant également la règle CSS: flex-direction: row-reverse
. Cela ne nécessite pas de CSS ou caché élément. Pour les navigateurs plus anciens qui ne prennent pas en charge flexbox, ils obtiennent toujours une solution réalisable, mais les éléments ne seront pas inversés.
j'ai lutté avec la même question depuis que j'ai eu le bouton Soumettre au milieu de La dont redirigé soumettre à une autre page, comme ainsi:
<button type="submit" onclick="this.form.action = '#another_page'">More</button>
lorsque l'Utilisateur a appuyé sur la touche enter, ce bouton a été cliqué au lieu d'un autre bouton Soumettre.
donc j'ai fait quelques tests primitifs en créant un from avec plusieurs boutons de soumission et différentes options de visibilité et en activant le bouton onclick event alerting qui a été cliqué: https://jsfiddle.net/aqfy51om/1/
Navigateurs et OS es que j'ai utilisé pour le test:
WINDOWS
- Google Chrome 43 (allez google :D)
- Mozilla Firefox 38
- Internet Explorer 11
- Opéra 30.0
OSX
- Google Chrome 43
- Safari 7.1.6
la plupart de ces navigateurs ont cliqué sur le tout premier bouton malgré les options de visibilité appliquées sauf et Safari qui a cliqué sur le troisième bouton, qui est "visible" à l'intérieur de "caché" conteneur:
<div style="width: 0; height: 0; overflow: hidden;">
<button type="submit" class="btn btn-default" onclick="alert('Hidden submit button #3 was clicked');">Hidden submit button #3</button>
</div>
donc ma suggestion, que je vais utiliser moi-même, est:
si vous avez plusieurs boutons soumettre avec signification différente, puis inclure le bouton Soumettre avec l'action par défaut au début du formulaire qui est soit:
- pleinement visible
- emballé dans un conteneur avec
style="width: 0; height: 0; overflow: hidden;"
MODIFIER
Une autre option pourrait être de désactiver le bouton (toujours au début de la de) style="position: absolute; left: -9999px; top: -9999px;"
, vient de l'essayer dans IE-worked , mais je n'ai aucune idée de ce qu'il peut foirer d'autre, par exemple impression..
de vos commentaires:
une conséquence est que, si vous avez plusieurs formulaires soumis au même script, tu ne peux pas te fier à submit boutons pour les distinguer.
je dépose un <input type="hidden" value="form_name" />
dans chaque forme.
si soumettre avec javascript: ajouter soumettre des événements aux formulaires, ne pas cliquer événements à leurs boutons. Les utilisateurs de Saavy ne touchent pas souvent leur souris.
lorsque vous avez plusieurs boutons soumettre dans un seul formulaire et un utilisateur appuie sur la touche ENTER pour soumettre le formulaire à partir d'un champ de texte, ce code remplace la fonctionnalité par défaut, en appelant l'événement soumettre sur le formulaire à partir de l'événement de presse clé. Voici le code:
$('form input').keypress(function(e){
if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)){ $(e.target).closest('form').submit(); return false; }
else return true;
});
étrange que le premier bouton Enter va toujours au premier bouton indépendamment est visible ou non, p.ex. en utilisant jquery show/hide()
. L'ajout de l'attribut .attr('disabled', 'disabled')
empêche de recevoir le bouton Enter submit complètement. C'est un problème par exemple lors du réglage de la visibilité du bouton Insérer/Modifier+Supprimer dans les boîtes de dialogue d'enregistrement. J'ai trouvé moins hackish et le placement simple Edit devant Insert
<button type="submit" name="action" value="update">Update</button>
<button type="submit" name="action" value="insert">Insert</button>
<button type="submit" name="action" value="delete">Delete</button>
et utiliser le code javascript:
$("#formId button[type='submit'][name='action'][value!='insert']").hide().attr('disabled', 'disabled');
$("#formId button[type='submit'][name='action'][value='insert']").show().removeAttr('disabled');
ma recette:
<form>
<input type=hidden name=action value=login><!-- the magic! -->
<input type=text name=email>
<input type=text name=password>
<input type=submit name=action value=login>
<input type=submit name=action value="forgot password">
</form>
il enverra le champ caché par défaut si aucun des boutons n'est 'cliqué'.
s'ils sont cliqués, ils ont la préférence et sa valeur est passée.
une autre solution que j'ai utilisée est d'avoir juste un bouton dans la forme, et de simuler les autres boutons.
voici un exemple:
<form>
<label for="amount">Amount of items</label>
<input id="amount" type="text" name="amount" />
<span id="checkStock" class="buttonish">Check stock</span>
<button type="submit" name="action" value="order">Place order</button>
</form>
ensuite, Je style les éléments de portée pour ressembler à un bouton. Un auditeur JS observe la portée et exécute l'opération désirée une fois cliqué.
pas nécessairement bon pour toutes les situations, mais au moins c'est assez facile à faire.
De la spécification HTML 4 :
Si un formulaire contient plus d'un bouton soumettre, seul le activée le bouton Soumettre est un succès.
cela signifie qu'avec plus d'un bouton Soumettre et aucun activé (cliqué), aucun ne devrait être réussi.
et je dirais que c'est logique: Imaginez un formulaire énorme avec plusieurs boutons de soumission. En haut, il y a un "delete this le bouton"Enregistrer", puis beaucoup d'entrées suivent et en bas il y a un bouton"Mettre à jour cet enregistrement". Un utilisateur qui frappe enter alors qu'il se trouve dans un champ au bas du formulaire ne soupçonnerait jamais qu'il frappe implicitement le "supprimer cet enregistrement" à partir du haut.
donc je pense que ce n'est pas une bonne idée d'utiliser le premier ou tout autre bouton que l'utilisateur ne définit pas (cliquez) un. Néanmoins, les navigateurs le font bien sûr.
EDIT: Désolé, lors de la rédaction de cette réponse, je pensais à soumettre les boutons dans le sens général. La réponse ci-dessous ne concerne pas plusieurs boutons type="submit"
, car il ne laisse qu'un seul type="submit"
et changer l'autre à type="button"
. Je laisse la réponse ici comme référence au cas où aide quelqu'un qui peut changer le type
dans leur forme:
pour déterminer quel bouton est pressé en appuyant sur enter, vous pouvez le marquer avec type="submit"
, et les autres boutons les marquent avec type="button"
. Par exemple:
<input type="button" value="Cancel" />
<input type="submit" value="Submit" />