Jak uniemożliwić przyciskom przesyłanie formularzy

917

Na następnej stronie w przeglądarce Firefox przycisk usuwania przesyła formularz, ale przycisk dodawania nie. Jak zapobiec przesyłaniu formularza przez przycisk usuwania?

<html>

<head>
    <script type="text/javascript" src="jquery-1.3.2.min.js"></script>
    <script type="text/javascript">
        function addItem() {
            var v = $('form :hidden:last').attr('name');
            var n = /(.*)input/.exec(v);

            var newPrefix;
            if (n[1].length == 0) {
                newPrefix = '1';
            } else {
                newPrefix = parseInt(n[1]) + 1;
            }

            var oldElem = $('form tr:last');
            var newElem = oldElem.clone(true);
            var lastHidden = $('form :hidden:last');

            lastHidden.val(newPrefix);

            var pat = '=\"' + n[1] + 'input';

            newElem.html(newElem.html().replace(new RegExp(pat, 'g'), '=\"' + newPrefix + 'input'));
            newElem.appendTo('table');
            $('form :hidden:last').val('');
        }

        function removeItem() {
            var rows = $('form tr');
            if (rows.length > 2) {
                rows[rows.length - 1].html('');
                $('form :hidden:last').val('');
            } else {
                alert('Cannot remove any more rows');
            }
        }
    </script>
</head>

<body>
    <form autocomplete="off" method="post" action="">
        <p>Title:<input type="text" /></p>
        <button onclick="addItem(); return false;">Add Item</button>
        <button onclick="removeItem(); return false;">Remove Last Item</button>
        <table>
            <th>Name</th>

            <tr>
                <td><input type="text" id="input1" name="input1" /></td>
                <td><input type="hidden" id="input2" name="input2" /></td>
            </tr>
        </table>
        <input id="submit" type="submit" name="submit" value="Submit">
    </form>
</body>

</html>
Khanpo
źródło
Którą odpowiedź polecacie?
sanepete

Odpowiedzi:

1795

Używasz elementu przycisku HTML5. Pamiętaj, że ten przycisk ma domyślne zachowanie przesyłania, zgodnie ze specyfikacją W3, jak widać tutaj: W3C HTML5 Button

Musisz więc wyraźnie określić jego typ:

<button type="button">Button</button>

w celu zastąpienia domyślnego typu przesyłania. Chcę tylko wskazać powód, dla którego tak się dzieje =)

=)

Metafaniel
źródło
17
Chciałbym również zauważyć, że element HTML posiadający atrybut typu, którego jednym z typów jest przycisk , nie powinien mieć domyślnego typu przesyłania . To po prostu idiotyczny i ogromny błąd w specyfikacji. Cały czas używam przycisków w formularzach, a nawet jeśli byłby to przypadek na krawędzi (który nie jest), nadal warto mieć domyślny typ przesłania.
dudewad
3
Most Spędziłem większość tego tygodnia zirytowany, że moja aplikacja Electron „odświeżyła się”, kiedy otwieram modal za pomocą przycisku w formularzu. Stało się to raz, a potem aplikacja zachowywała się tak, jak się spodziewałem. Nie miałem absolutnie pojęcia, co się dzieje. To było to! Nie mam problemu z przesłaniem domyślnego typu. Wydaje się to trochę męczące, biorąc pod uwagę, że zajęło mi to pięć lat, aby się o tym dowiedzieć.
freethebees
4
Dzięki twojej referencji właśnie dowiedziałem się, że istnieje typ = reset dla formularza. Niesamowite!
Duong Nguyen
602

Ustaw typ na przyciskach:

<button type="button" onclick="addItem(); return false;">Add Item</button>
<button type="button" onclick="removeItem(); return false;">Remove Last Item</button>

... to powstrzyma je przed wywołaniem akcji przesyłania, gdy wystąpi wyjątek w procedurze obsługi zdarzeń. Następnie napraw swoją removeItem()funkcję, aby nie wyzwalała wyjątku:

function removeItem() {
  var rows = $('form tr');
  if ( rows.length > 2 ) {
    // change: work on filtered jQuery object
    rows.filter(":last").html('');
    $('form :hidden:last').val('');
  } else {
    alert('Cannot remove any more rows');
  }
}

Zwróć uwagę na zmianę: twój oryginalny kod wyodrębnił element HTML z zestawu jQuery, a następnie próbował wywołać na nim metodę jQuery - zgłosił to wyjątek, co spowodowało domyślne zachowanie przycisku.

FWIW, istnieje inny sposób, w jaki możesz to zrobić ... Połącz swoje procedury obsługi zdarzeń za pomocą jQuery i użyj metody preventDefault () na obiekcie zdarzenia jQuery, aby anulować domyślne zachowanie z góry:

$(function() // execute once the DOM has loaded
{

  // wire up Add Item button click event
  $("#AddItem").click(function(event)
  {
    event.preventDefault(); // cancel default behavior

    //... rest of add logic
  });

  // wire up Remove Last Item button click event
  $("RemoveLastItem").click(function(event)
  {
    event.preventDefault(); // cancel default behavior

    //... rest of remove last logic
  });

});

...

<button type="button" id="AddItem" name="AddItem">Add Item</button>
<button type="button" id="RemoveLastItem" name="RemoveLastItem">Remove Last Item</button>

Ta technika utrzymuje całą logikę w jednym miejscu, ułatwiając debugowanie ... pozwala także na wdrożenie wycofania przez zmianę typeprzycisków na powrót submiti obsługę zdarzenia po stronie serwera - jest to znane jako dyskretne JavaScript .

Shog9
źródło
4
type = „button” nie zawsze działa w przeglądarce Firefox. Jeśli plik js jest wystarczająco skomplikowany i wystąpi błąd, Firefox i tak prześle formularz. Niepoczytalność!
Matthew Lock
1
@MatthewLock: Raczej nie - błąd w skrypcie tylko zamyka ten blok kodu, a akcja przebiega jak zwykle. Spróbuj wywołać metody zdarzeń jQuery e.preventDefault () i / lub e.stopPropgation () jako pierwsze wiersze metody. Zobacz stackoverflow.com/questions/2017755/..., aby dowiedzieć się więcej
brichins,
8
Przycisk type = nigdy nie powinien przesyłać formularza, bez względu na wszystko
Matthew Lock
1
return falsejest bardzo ważne. czasami nawet użyć go do przycisku przesyłania ( onclick
Jamie
7
Myślę, że HTML jest tutaj dziwny. Powinno to być domyślnie type = "button", nie przesyłanie. Zawsze domyślam się, że przesyłanie to jest domyślne. To wyjątek.
httpete
31

Jakiś czas temu potrzebowałem czegoś bardzo podobnego ... i dostałem to.

Wstawiam więc sposób, w jaki wykonuję sztuczki, aby formularz mógł zostać przesłany przez JavaScript bez sprawdzania poprawności i sprawdzania poprawności tylko wtedy, gdy użytkownik naciśnie przycisk (zwykle przycisk wysyłania).

Na przykład użyję minimalnego formularza, tylko z dwoma polami i przyciskiem wysyłania.

Pamiętaj, co jest potrzebne: z JavaScript musi być możliwe przesłanie go bez sprawdzania. Jeśli jednak użytkownik naciśnie taki przycisk, weryfikacja musi zostać wykonana, a formularz wysłany tylko po pozytywnym przejściu weryfikacji.

Normalnie wszystko zaczynałoby się od czegoś w pobliżu (usunąłem wszystkie dodatkowe rzeczy, które nie są ważne):

<form method="post" id="theFormID" name="theFormID" action="">
   <input type="text" id="Field1" name="Field1" />
   <input type="text" id="Field2" name="Field2" />
   <input type="submit" value="Send" onclick="JavaScript:return Validator();" />
</form>

Zobacz, jak tag formularza nie ma onsubmit="..."(pamiętaj, że warunkiem było nie mieć go).

Problem polega na tym, że formularz jest zawsze przesyłany, bez względu na to, czy onclickzwrot truelub false.

Jeśli zmienię type="submit"dla type="button"wydaje się działać, ale nie. Nigdy nie wysyła formularza, ale można to łatwo zrobić.

Więc w końcu użyłem tego:

<form method="post" id="theFormID" name="theFormID" action="">
   <input type="text" id="Field1" name="Field1" />
   <input type="text" id="Field2" name="Field2" />
   <input type="button" value="Send" onclick="JavaScript:return Validator();" />
</form>

I function Validatortam, gdzie return True;jest, dodaję także zdanie przesyłania JavaScript, coś podobnego do tego:

function Validator(){
   //  ...bla bla bla... the checks
   if(                              ){
      document.getElementById('theFormID').submit();
      return(true);
   }else{
      return(false);
   }
}

Dotyczy id=""tylko JavaScript getElementById, name=""tylko po to, aby pojawił się na danych POST.

W ten sposób działa tak, jak potrzebuję.

Umieszczam to tylko dla osób, które nie potrzebują żadnej onsubmitfunkcji w formularzu, ale dokonuję pewnej weryfikacji po naciśnięciu przycisku przez użytkownika.

Dlaczego nie potrzebuję onsubmit na znaczniku formularza? Łatwo, w innych częściach JavaScript muszę wykonać przesłanie, ale nie chcę, aby była jakakolwiek weryfikacja.

Powód: jeśli użytkownik jest tym, który wykonuje przesyłanie, chcę i chcę przeprowadzić weryfikację, ale jeśli jest to JavaScript, czasami muszę wykonać przesyłanie, podczas gdy takie weryfikacje by tego uniknąć.

Może to zabrzmieć dziwnie, ale nie podczas myślenia na przykład: przy logowaniu ... z pewnymi ograniczeniami ... np. Nie zezwalaj na używanie sesji PHP i żadne ciasteczka nie są dozwolone!

Tak więc każdy link musi zostać przekonwertowany na taki formularz, aby dane logowania nie zostały utracone. Jeśli logowanie nie jest jeszcze wykonane, musi również działać. Dlatego nie można przeprowadzać sprawdzania poprawności linków. Ale chcę przedstawić użytkownikowi wiadomość, jeśli użytkownik nie wprowadził obu pól, użytkownika i hasła. Jeśli więc brakuje jednego, formularza nie można wysłać! jest problem.

Zobacz problem: formularza nie można wysłać, gdy jedno pole jest puste, tylko jeśli użytkownik nacisnął przycisk, jeśli jest to kod JavaScript, musi być możliwe wysłanie.

Jeśli będę pracować nad onsubmitznacznikiem formularza, będę musiał wiedzieć, czy to użytkownik, czy inny JavaScript. Ponieważ nie można przekazać żadnych parametrów, nie jest to możliwe bezpośrednio, więc niektóre osoby dodają zmienną, aby powiedzieć, czy należy przeprowadzić weryfikację, czy nie. Pierwszą rzeczą w funkcji sprawdzania poprawności jest sprawdzenie tej wartości zmiennej itp. Zbyt skomplikowane i kod nie mówi, co jest naprawdę potrzebne.

Tak więc rozwiązaniem nie jest onsubmit na znaczniku formularza. Insead umieść go tam, gdzie jest naprawdę potrzebny, na przycisku.

Z drugiej strony, po co umieszczać kod onsubmit, ponieważ koncepcyjnie nie chcę sprawdzania poprawności onsubmit. Naprawdę chcę zatwierdzenia przycisku.

Kod jest nie tylko bardziej przejrzysty, ale także tam, gdzie musi być. Pamiętaj tylko: - Nie chcę, aby JavaScript weryfikował formularz (musi to zawsze robić PHP po stronie serwera) - Chcę pokazać użytkownikowi komunikat informujący, że wszystkie pola nie mogą być puste, wymaga JavaScript (klient bok)

Dlaczego więc niektórzy ludzie (pomyślcie lub powiedzcie mi), że trzeba to zrobić po jednorazowej weryfikacji? Nie, koncepcyjnie nie robię onsumbit sprawdzania poprawności po stronie klienta. Po prostu robię coś na naciśnięciu przycisku, więc dlaczego nie pozwolić, aby to zostało zaimplementowane?

Cóż, ten kod i styl doskonale sobie radzą. Na każdym JavaScript, który muszę wysłać, właśnie wstawiłem formularz:

document.getElementById('theFormID').action='./GoToThisPage.php'; // Where to go
document.getElementById('theFormID').submit(); // Send POST data and go there

I to pomija walidację, gdy jej nie potrzebuję. Po prostu wysyła formularz i ładuje inną stronę itp.

Ale jeśli użytkownik kliknie przycisk przesyłania (inaczej type="button"nie type="submit"), sprawdzanie poprawności zostanie wykonane przed zezwoleniem na przesłanie formularza i, jeśli nie jest poprawne, nie zostanie wysłane.

Mam nadzieję, że pomoże to innym osobom nie wypróbować długiego i skomplikowanego kodu. Po prostu nie używaj, onsubmitjeśli nie jest potrzebny, i używaj onclick. Ale należy pamiętać, aby zmieniać type="submit"się type="button"i proszę nie zapomnieć zrobić to submit()przez JavaScript.

z666zz666z
źródło
28

Zgadzam się z Shog9, chociaż zamiast tego mogę użyć:

<input type = "button" onClick="addItem(); return false;" value="Add Item" />

Według w3schools The <button>tag ma różne zachowanie w różnych przeglądarkach.

poundifdef
źródło
18

Załóżmy, że Twój formularz HTML ma id="form_id"

<form id="form_id">
<!--your HTML code-->
</form>

Dodaj ten fragment jQuery do swojego kodu, aby zobaczyć wynik,

$("#form_id").submit(function(){
  return false;
});
Prateek Joshi
źródło
18

Możesz po prostu uzyskać odwołanie do przycisków za pomocą jQuery i zapobiec jego propagacji, jak poniżej:

 $(document).ready(function () {
    $('#BUTTON_ID').click(function(e) {

            e.preventDefault();
            e.stopPropagation();
            e.stopImmediatePropagation();

            return false;
    });});
Ata Iravani
źródło
2
e.preventDefault(); e.stopPropagation();wystarczy, żeby wszystko działało. e.stopImmediatePropagation()powoduje to błąd niezdefiniowanej metody w Chrome.
Subroto
14

$("form").submit(function () { return false; }); uniemożliwi to przesłanie przycisku lub możesz po prostu zmienić typ przycisku na „przycisk” <input type="button"/>zamiast <input type="submit"/> Który zadziała tylko wtedy, gdy ten przycisk nie jest jedynym przyciskiem w tym formularzu.

Shiala
źródło
2
Dotyczy to jQuery, odpowiednikiem w JavaScript jest: myform.onsubmit = function () {return false} ... również, nawet jeśli usuniesz przycisk przesyłania, formularz można również przesłać, naciskając enter z innego pola formularza.
Synexis,
10

Jest to błąd HTML5, jak już powiedziano, nadal możesz mieć przycisk jako przesłany (jeśli chcesz objąć zarówno javascript, jak i nie javascript), używając go w następujący sposób:

     <button type="submit" onclick="return false"> Register </button>

W ten sposób anulujesz wysyłanie, ale nadal będziesz robił wszystko, co robisz w funkcji jquery lub javascript, i wykonasz to dla użytkowników, którzy nie mają javascript.

sagits
źródło
8

Jestem pewien, że na FF

removeItem 

wystąpił błąd JavaScript, nie dzieje się tak w IE

Gdy pojawi się błąd javascript, kod „return false” nie będzie działał, co spowoduje odesłanie strony

Alin Vasile
źródło
8

Zwracane false uniemożliwia zachowanie domyślne. ale false zwraca, że ​​dodatkowe zdarzenia związane z kliknięciem są przerywane. Oznacza to, że po wywołaniu tej funkcji istnieją inne powiązania kliknięcia, te inne nie biorą pod uwagę.

 <button id="btnSubmit" type="button">PostData</button>
 <Script> $("#btnSubmit").click(function(){
   // do stuff
   return false;
}); </Script>

Lub po prostu możesz to tak ułożyć

 <button type="submit" onclick="return false"> PostData</button>
Sunil Dhappadhule
źródło
7

Wystarczy dodać e.preventDefault();metodę, aby zapobiec przesyłaniu formularzy przez stronę.

function myFunc(e){
       e.preventDefault();
}

Według dokumentów MDN Web Docs

Metoda preventDefault () interfejsu zdarzenia informuje agenta użytkownika, że ​​jeśli zdarzenie nie zostanie jawnie przetworzone, jego domyślne działanie nie powinno być brane pod uwagę, jak zwykle. Zdarzenie kontynuuje propagację w zwykły sposób, chyba że jeden z jego słuchaczy wywoła stopPropagation ()lub stopImmediatePropagation ()którykolwiek z nich zakończy propagację.

Mselmi Ali
źródło
6

Ustaw swój przycisk w normalny sposób i użyj event.preventDefault jak ..

   <button onclick="myFunc(e)"> Remove </button>  
   ...
   ...

   In function...

   function myFunc(e){
       e.preventDefault();
   }
Vishal
źródło
4
return false;

Możesz zwrócić false na końcu funkcji lub po wywołaniu funkcji.

Tak długo, jak będzie to ostatnia rzecz, która się stanie, formularz nie zostanie przesłany.

WonderWorker
źródło
2

Oto proste podejście:

$('.mybutton').click(function(){

    /* Perform some button action ... */
    alert("I don't like it when you press my button!");

    /* Then, the most important part ... */
    return false;

});
axiom82
źródło
1

Poniższy przykładowy kod pokazuje, jak uniemożliwić przesłanie formularza przyciskiem kliknięcia.

Możesz wypróbować mój przykładowy kod:

 <form autocomplete="off" method="post" action="">
   <p>Title:
     <input type="text" />
   </p>
   <input type="button" onclick="addItem()" value="Add Item">
   <input type="button" onclick="removeItem()" value="Remove Last Item">
   <table>
     <th>Name</th>

     <tr>
       <td>
         <input type="text" id="input1" name="input1" />
       </td>
       <td>
         <input type="hidden" id="input2" name="input2" />
       </td>
     </tr>
   </table>
   <input id="submit" type="submit" name="submit" value="Submit">
 </form>
<script language="javascript">
function addItem() {
return false;
}

function removeItem() {
return false;
}
</script>
KNVB
źródło
0

Nie jestem w stanie tego teraz przetestować, ale wydaje mi się, że możesz użyć metody preventDefault w jQuery .

Tyler Rash
źródło
0

Funkcja removeItem faktycznie zawiera błąd, który powoduje, że przycisk formularza wykonuje swoje domyślne zachowanie (przesłanie formularza). W tym przypadku konsola błędów javascript zwykle podaje wskaźnik.

Sprawdź funkcję removeItem w części javascript:

Linia:

rows[rows.length-1].html('');

nie działa Spróbuj zamiast tego:

rows.eq(rows.length-1).html('');
Ylebre
źródło