Jak określa się domyślny przycisk Wyślij w formularzu HTML?

Jeśli formularz jest przesłany, ale nie za pomocą żadnego konkretnego przycisku, takiego jak

  • naciskając Enter
  • using HTMLFormElement.submit() in JS

Jak przeglądarka ma określić, który z wielu przycisków przesyłania, jeśli w ogóle, ma być użyty jako naciśnięty?

Jest to istotne na dwóch poziomach:

  • wywołanie obsługi zdarzeniaonclick dołączonego do przycisku submit
  • dane wysyłane z powrotem do serwera www

Moje dotychczasowe eksperymenty wykazały że:

  • po naciśnięciu Enter , Firefox, Opera i Safari używają pierwszego przycisku submit w formularzu
  • po naciśnięciu Enter , IE używa albo pierwszego przycisku submit albo żadnego w ogóle w zależności od warunków, których nie udało mi się ustalić
  • wszystkie te przeglądarki używają none w ogóle dla JS submit

Co mówi norma?

Jeśli to pomoże, Oto Mój kod testowy (PHP dotyczy tylko mojej metody testowania, a nie mojego pytania itself)

<!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>
Author: Jawa, 2009-05-29

14 answers

Jeśli formularz zostanie przesłany przez Javascript (np. formElement.submit() lub cokolwiek równoważnego), to żaden z przycisków wyślij nie zostanie uznany za pomyślny i żadna z ich wartości nie zostanie uwzględniona w przesłanych danych. (Zauważ, że jeśli przesyłasz formularz za pomocą submitElement.click(), to submit, do którego miałeś odniesienie, jest uważany za aktywny; tak naprawdę nie wchodzi to w zakres twojego pytania, ponieważ tutaj przycisk submit jest jednoznaczny, ale pomyślałem, że dołączę go dla osób, które przeczytały pierwszą część i ciekawe jak zrobić przycisk submit z powodzeniem poprzez formularz js submission. Oczywiście, obsługa formularza nadal będzie strzelać w ten sposób, podczas gdy nie będzie przez form.submit(), więc to kolejny czajnik z rybami...)

Jeśli formularz zostanie przesłany przez naciśnięcie klawisza Enter w polu non-textarea,to w rzeczywistości to agent użytkownika decyduje, czego chce. Specyfikacja nie mówi nic o przesyłaniu formularza za pomocą klawisza enter w polu tekstowym (jeśli zakładka do przycisku i aktywować go za pomocą spacji lub cokolwiek, to nie ma problemu, ponieważ ten konkretny przycisk submit jest jednoznacznie używany). Wszystko, co mówi, to to, że formularz musi zostać przesłany, gdy przycisk submit jest aktywowany, nawet nie jest wymagane, aby naciśnięcie enter W np. wprowadzanie tekstu przesłało formularz.

Uważam, że Internet Explorer wybiera przycisk submit, który pojawia się jako pierwszy w źródle; mam wrażenie, że Firefox i Opera wybierają przycisk z NAJNIŻSZYM tabindexem, spadając z powrotem do najpierw zdefiniowany, jeśli nie zdefiniowano nic innego. Istnieją również pewne komplikacje dotyczące tego, czy zgłoszenia mają domyślny atrybut wartości IIRC.

Chodzi o to, że nie ma zdefiniowanego standardu dla tego, co się tutaj dzieje i jest to całkowicie z kaprysu przeglądarki - tak dalece, jak to możliwe w cokolwiek robisz, staraj się unikać polegania na jakimkolwiek konkretnym zachowaniu. Jeśli naprawdę musisz wiedzieć, prawdopodobnie możesz dowiedzieć się zachowania różnych wersji przeglądarki, ale kiedy zbadałem to jakiś czas temu pojawiły się dość zawiłe warunki (które oczywiście mogą ulec zmianie wraz z nowymi wersjami przeglądarki) i radzę ci tego unikać, jeśli to możliwe!

 101
Author: Andrzej Doyle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-29 10:41:13

Andrezj jest w porządku... ale oto łatwe rozwiązanie między przeglądarkami.

Przyjmij taką formę:

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

I refaktura do tego:

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

Ponieważ specyfikacja W3C wskazuje, że wiele przycisków submit jest poprawnych, ale pomija wskazówki, jak użytkownik-agent powinien je obsługiwać, producenci przeglądarek pozostają do zaimplementowania według własnego uznania. Stwierdziłem, że albo prześlą pierwszy przycisk Prześlij w formularzu, albo prześlij Następny przycisk Prześlij po formularzu pole, które obecnie ma fokus.

Niestety, po prostu dodanie stylu display: none; nie zadziała, ponieważ specyfikacja W3C wskazuje, że każdy ukryty element powinien być wykluczony z interakcji użytkownika. Więc Ukryj to na widoku!

Powyżej jest przykład rozwiązania, które wprowadziłem do produkcji. Naciśnięcie klawisza enter powoduje, że domyślne przesyłanie formularza jest zgodne z oczekiwaniami, nawet jeśli są obecne inne wartości inne niż domyślne i poprzedzają domyślne przesyłanie przycisk w DOM. Bonus za interakcję mysz / klawiatura z wyraźnymi wejściami użytkownika, unikając obsługi javascript.

Uwaga: zakładka przez formularz nie będzie wyświetlać ostrości dla żadnego elementu wizualnego, ale nadal spowoduje, że niewidoczny przycisk zostanie wybrany. Aby uniknąć tego problemu, wystarczy odpowiednio ustawić atrybuty tabindex i pominąć atrybut tabindex na niewidzialnym przycisku Wyślij. Chociaż może wydawać się nie na miejscu, aby promować te style !ważne, One powinny zapobiegać wszelkim framework lub istniejące style przycisków od ingerencji w tę poprawkę. Również te style inline są zdecydowanie słabą formą, ale udowadniamy tutaj koncepcje... nie pisanie kodu produkcyjnego.

 56
Author: James,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-24 17:40:59

HTML 4 nie mówi wprost. Aktualnie robocza wersja HTML5 Określa, że pierwszy przycisk submit musi być domyślnym :

A form domyślnym przyciskiem elementu jest pierwszy przycisk submit w kolejność drzewa której właściciel formularza jest taki, że form element.

Jeśli agent użytkownika umożliwia użytkownikowi przesłanie formularza domyślnie (na przykład na niektórych platformach naciśnięcie klawisza "enter" podczas gdy pole tekstowe jest skupione domyślnie przesyła formularz), następnie robi to dla formularza, którego domyślny przycisk mA zdefiniowaną zachowanie aktywacji musi spowodować, że agent użytkownika Uruchom syntetyczne kroki aktywacji kliknięć na tym domyślny przycisk .

 51
Author: Quentin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-07 17:33:22

Myślę, że ten post pomoże, jeśli ktoś chce to zrobić z jQuery:

Http://greatwebguy.com/programming/dom/default-html-button-submit-on-enter-with-jquery/

Podstawowym rozwiązaniem jest:

$(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;
    }
    });
});

I jeszcze jedno mi się spodobało:

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;
}
});
}); 
 16
Author: Rodrigo Caballero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-22 21:53:09

Miałem formularz z 11 przyciskami submit i zawsze używał pierwszego przycisku submit, gdy użytkownik nacisnął enter. Czytałem gdzie indziej, że nie jest dobrym pomysłem (zła praktyka), aby mieć więcej niż jeden przycisk submit w formularzu, a najlepszym sposobem na to jest mieć przycisk, który chcesz jako domyślny, jako jedyny przycisk submit w formularzu. Pozostałe przyciski powinny być wykonane w "TYPE = BUTTON" I dodane Zdarzenie onClick, które wywołuje własną procedurę submit w Javascript. Coś w tym stylu. :-

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

Tutaj, button3 jest wartością domyślną i chociaż programowo przesyłasz formularz za pomocą innych przycisków, procedura mjsubmit je sprawdza. HTH.

 6
Author: graphic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-17 13:11:53

Można to teraz rozwiązać za pomocą 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 */
}

Explaination
Używając flex box, możemy odwrócić kolejność elementów w kontenerze, który używa display: flex, używając również reguły CSS: flex-direction: row-reverse. Nie wymaga to CSS ani ukrytych elementów. W przypadku starszych przeglądarek, które nie obsługują flexbox, nadal mają wykonalne rozwiązanie, ale elementy nie będą odwrócony.

Demo
http://codepen.io/Godwin/pen/rLVKjm

 4
Author: Godwin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-04 19:01:29

Zmagałem się z tym samym pytaniem, ponieważ miałem przycisk submit w środku, z którego Przekierowano submit na inną stronę, jak tak:

<button type="submit" onclick="this.form.action = '#another_page'">More</button>

Gdy użytkownik nacisnął klawisz enter, ten przycisk został kliknięty zamiast innego przycisku Wyślij.

Więc zrobiłem kilka prymitywnych testów, tworząc od z wielu przycisków submit i różnych opcji widoczności i onclick zdarzenia alertowania, który przycisk został kliknięty: https://jsfiddle.net/aqfy51om/1/

Przeglądarki i OS ' Y używałem do testowania:

WINDOWS

  • Google Chrome 43 (c ' mon google: d)
  • Mozilla Firefox 38
  • Internet Explorer 11
  • Opera 30.0

OSX

  • Google Chrome 43
  • Safari 7.1.6

Większość z tych przeglądarek kliknęła pierwszy przycisk, pomimo zastosowanych opcji widoczności exept IE i Safari, które kliknęły trzeci przycisk, który jest "widoczny" wewnątrz " Ukryty" "Pojemnik": {]}

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

Więc moja sugestia, którą zamierzam wykorzystać sam, to:

Jeśli formularz ma wiele przycisków submit o różnym znaczeniu, Dodaj przycisk submit z domyślną akcją na początku formularza, która jest albo:

  1. w pełni widoczne
  2. owinięte w pojemnik z style="width: 0; height: 0; overflow: hidden;"

EDIT Inną opcją może być przesunięcie przycisku (jeszcze na początku from) style="position: absolute; left: -9999px; top: -9999px;", właśnie próbowałem w IE-działa, ale nie mam pomysł, co jeszcze może zepsuć, na przykład drukowanie..

 2
Author: Kristian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-16 12:15:33

Z twoich komentarzy:

Konsekwencją jest to, że jeśli masz wiele formularzy składających się do tego samego skrypt, nie możesz polegać na submit przyciski do ich rozróżniania.

Wrzucam <input type="hidden" value="form_name" /> do każdej formy.

Jeśli przesyłanie za pomocą javascript: dodaj prześlij zdarzenia do formularzy, a nie kliknij zdarzenia do ich przycisków. Użytkownicy Saavy nie dotykają zbyt często myszy.

 1
Author: Ryan Florence,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-29 14:15:09

Gdy w jednym formularzu znajduje się wiele przycisków Wyślij, a użytkownik naciska klawisz ENTER, aby wysłać formularz z pola tekstowego, ten kod nadpisuje domyślną funkcjonalność, wywołując Zdarzenie wyślij na formularzu z naciśnięcia klawisza. Oto ten kod:

$('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;

});
 1
Author: axiom82,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-24 21:22:59

Dziwne, że pierwszy przycisk Enter przechodzi zawsze do pierwszego przycisku niezależnie od tego czy jest widoczny czy nie, np. używając jquery show/hide(). Dodanie atrybutu .attr('disabled', 'disabled') uniemożliwia całkowite otrzymanie przycisku Enter submit. Jest to problem na przykład przy dostosowywaniu widoczności przycisku Wstaw/edytuj+usuń w oknach dialogowych rekordów. Znalazłem mniej hakerskie i proste umieszczenie Edit przed 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>

I użyj kodu javascript:

$("#formId button[type='submit'][name='action'][value!='insert']").hide().attr('disabled', 'disabled');
$("#formId button[type='submit'][name='action'][value='insert']").show().removeAttr('disabled');
 1
Author: TMa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-05 18:05:24

Mój przepis:

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

Wyśle domyślne ukryte pole, jeśli żaden z przycisków nie zostanie "kliknięty".

Jeśli zostaną kliknięte, mają preferencje i ich wartość jest przekazywana.

 0
Author: gcb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-07 08:29:08

Innym rozwiązaniem, którego użyłem, jest posiadanie tylko jednego przycisku w formularzu, a udawanie innych przycisków.

Oto przykład:

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

Następnie stylizuję elementy span tak, aby wyglądały jak przycisk. Słuchacz js obserwuje zakres i wykonuje żądaną operację po kliknięciu.

Niekoniecznie odpowiednie dla wszystkich sytuacji, ale przynajmniej jest to dość łatwe do zrobienia.

 0
Author: Johan Fredrik Varen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-28 14:31:55

From the HTML 4 spec :

Jeśli formularz zawiera więcej niż jeden przycisk submit, tylko aktywowany przycisk submit jest pomyślny.

Oznacza to, że biorąc pod uwagę więcej niż 1 przycisk submit i żaden nie aktywowany (kliknięty), żaden nie powinien się udać.

A ja bym argumentował, że to ma sens: Wyobraź sobie ogromny formularz z wieloma przyciskami przesyłania. Na górze znajduje się przycisk "Usuń ten rekord" , następnie następuje wiele wejść, a na dole znajduje się przycisk "update this rekord " - przycisk. Użytkownik, który naciśnie enter w polu na dole formularza, nigdy nie podejrzewałby, że domyślnie uderzy w "usuń ten rekord" z góry.

Dlatego uważam, że nie jest dobrym pomysłem użycie pierwszego lub innego przycisku, którego Użytkownik nie definiuje (klika). Niemniej jednak przeglądarki robią to oczywiście.

 0
Author: Christopher K.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-27 22:18:19

EDIT: Przepraszam, pisząc tę odpowiedź myślałem o przyciskach submit w sensie ogólnym. Odpowiedź poniżej nie dotyczy wielu type="submit" przycisków, ponieważ pozostawia tylko jeden type="submit" i zmienia drugi na type="button". Zostawiam tutaj odpowiedź jako odniesienie na wypadek, gdyby ktoś mógł zmienić type w swojej formie:

Aby określić, który przycisk zostanie naciśnięty podczas wciśnięcia enter, możesz oznaczyć go za pomocą type="submit", a pozostałe przyciski oznaczyć za pomocą type="button". Na przykład:

<input type="button" value="Cancel" />
<input type="submit" value="Submit" />
 -2
Author: Jesús Carrera,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-27 11:04:29