Come impedire ai pulsanti di inviare moduli


917

Nella pagina seguente, con Firefox il pulsante Rimuovi invia il modulo, ma il pulsante Aggiungi no. Come posso impedire al pulsante di rimozione di inviare il modulo?

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

quale risposta mi consiglia per favore?
sanepete,

Risposte:


1799

Stai utilizzando un elemento pulsante HTML5. Ricorda il motivo è che questo pulsante ha un comportamento predefinito di invio, come indicato nella specifica W3 come mostrato qui: Pulsante HTML5 W3C

Quindi è necessario specificare esplicitamente il suo tipo:

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

per sovrascrivere il tipo di invio predefinito. Voglio solo sottolineare il motivo per cui questo accade =)

=)


17
Vorrei anche sottolineare che un elemento HTML con un attributo type, uno dei quali è button , non dovrebbe avere un tipo di invio predefinito . È semplicemente un idiota e un grosso errore nelle specifiche. Uso sempre i pulsanti nei moduli e, anche se fosse un caso limite (cosa che non lo è), avrebbe comunque senso avere il tipo predefinito da inviare.
Dudewad,

3
🤯 Ho trascorso gran parte della settimana infastidito dal fatto che la mia app Electron si "aggiorna" quando apro un modale usando un pulsante all'interno di un modulo. Sarebbe successo una volta e poi l'app si sarebbe comportata come mi aspettavo. Non avevo assolutamente idea di cosa stesse succedendo. Era questo! Non ho problemi con l'invio del tipo predefinito. Sembra un po 'un gotcha, anche se dato che mi ci sono voluti cinque anni per conoscerlo.
Freethebees,

4
Grazie al tuo riferimento, ho appena appreso che esiste un tipo = reset per il modulo. Eccezionale!
Duong Nguyen,

602

Imposta il tipo sui pulsanti:

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

... che impedirà loro di attivare un'azione di invio quando si verifica un'eccezione nel gestore eventi. Quindi, correggi la tua removeItem()funzione in modo che non attivi un'eccezione:

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');
  }
}

Nota la modifica: il tuo codice originale ha estratto un elemento HTML dal set jQuery, e quindi ha provato a richiamare un metodo jQuery su di esso - questo ha generato un'eccezione, determinando il comportamento predefinito per il pulsante.

FWIW, c'è un altro modo in cui potresti procedere con questo ... Collega i gestori di eventi usando jQuery e usa il metodo preventDefault () sull'oggetto evento di jQuery per annullare il comportamento predefinito in anticipo:

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

Questa tecnica mantiene tutta la tua logica in un unico posto, facilitando il debug ... ti consente anche di implementare un fallback cambiando typei pulsanti di nuovo submite gestendo il lato server dell'evento - questo è noto come discreto JavaScript .


4
type = "button" non sempre funziona in Firefox per me. Se js è abbastanza complicato e c'è un errore, Firefox invierà comunque il modulo. Follia!
Matthew Lock,

1
@MatthewLock: Difficilmente - un errore nello script interrompe il blocco di codice e l'azione procede come al solito. Prova a richiamare i metodi dell'evento jQuery e.preventDefault () e / o e.stopPropgation () come prime righe del metodo. Vedi stackoverflow.com/questions/2017755/… per saperne di più
brichins

8
type = button non dovrebbe mai inviare il modulo, non importa quale
Matthew Lock,

1
return falseè così importante. a volte anche usarlo per il pulsante di invio ( onclick
Jamie

7
Penso che html sia strano qui. Dovrebbe essere type = "button" per impostazione predefinita, non inoltrare. È sempre inaspettato per me vedere l'invio per impostazione predefinita. È l'eccezione.
httpete,

31

Qualche tempo fa avevo bisogno di qualcosa di molto simile ... e l'ho capito.

Quindi quello che ho messo qui è come faccio i trucchi per avere un modulo che può essere inviato da JavaScript senza alcuna convalida ed eseguo la convalida solo quando l'utente preme un pulsante (in genere un pulsante di invio).

Per l'esempio userò un modulo minimo, solo con due campi e un pulsante di invio.

Ricorda ciò che si desidera: da JavaScript deve poter essere inviato senza alcun controllo. Tuttavia, se l'utente preme tale pulsante, la convalida deve essere eseguita e il modulo deve essere inviato solo se supera la convalida.

Normalmente tutto dovrebbe iniziare da qualcosa vicino a questo (ho rimosso tutte le cose extra non importanti):

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

Guarda come il tag del modulo non ha onsubmit="..."(ricorda che era una condizione per non averlo).

Il problema è che il modulo viene sempre inviato, non importa se onclickrestituisce trueo false.

Se cambio type="submit"per type="button", sembra funzionare ma non funziona. Non invia mai il modulo, ma può essere fatto facilmente.

Quindi finalmente ho usato questo:

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

E su function Validator, dov'è return True;, aggiungo anche una frase di invio JavaScript, qualcosa di simile a questo:

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

Il id="" è solo per JavaScript getElementById, la name=""è solo che appaia sui dati POST.

In questo modo funziona come ho bisogno.

Lo metto solo per le persone che non hanno bisogno di onsubmit funzione nel modulo, ma eseguo una convalida quando un pulsante viene premuto dall'utente.

Perché non ho bisogno di onsubmit sul tag del modulo? Facile, su altre parti JavaScript devo effettuare un invio ma non voglio che ci sia alcuna convalida.

Il motivo: se l'utente è quello che esegue l'invio che desidero e necessita che venga effettuata la convalida, ma se è JavaScript a volte devo eseguire l'invio mentre tali convalide lo eviterebbero.

Può sembrare strano, ma non quando si pensa ad esempio: su un Login ... con alcune restrizioni ... come non consentire l'utilizzo di sessioni PHP e nessuno dei cookie è consentito!

Pertanto, qualsiasi collegamento deve essere convertito in tale modulo, quindi i dati di accesso non vanno persi. Quando non è ancora stato effettuato l'accesso, deve funzionare anche. Pertanto, non è necessario eseguire alcuna convalida sui collegamenti. Ma voglio presentare un messaggio all'utente se l'utente non ha inserito entrambi i campi, utente e pass. Quindi se ne manca uno, il modulo non deve essere inviato! c'è il problema.

Vedi il problema: il modulo non deve essere inviato quando un campo è vuoto solo se l'utente ha premuto un pulsante, se è un codice JavaScript deve poter essere inviato.

Se lavoro sul onsubmittag del modulo, dovrei sapere se è l'utente o altro JavaScript. Poiché non è possibile passare parametri, non è possibile direttamente, quindi alcune persone aggiungono una variabile per dire se la convalida deve essere eseguita o meno. La prima cosa sulla funzione di validazione è quella di verificare quel valore variabile, ecc ... Troppo complicato e il codice non dice ciò che è veramente desiderato.

Quindi la soluzione non è avere onsubmit sul tag del modulo. Insead mettilo dove è veramente necessario, sul pulsante.

Per l'altro lato, perché mettere il codice onsubmit poiché concettualmente non voglio la validazione onsubmit. Voglio davvero la convalida dei pulsanti.

Non solo il codice è più chiaro, è dove deve essere. Ricorda questo: - Non voglio che JavaScript convalidi il modulo (che deve essere sempre eseguito da PHP sul lato server) - Voglio mostrare all'utente un messaggio che dice che tutti i campi non devono essere vuoti, che ha bisogno di JavaScript (client lato)

Quindi, perché alcune persone (pensa o dimmelo) deve essere fatto su una validazione onsumbit? No, concettualmente non sto facendo una convalida onsumbit sul lato client. Sto solo facendo qualcosa su un pulsante, quindi perché non lasciarlo implementare?

Bene, quel codice e lo stile fanno perfettamente il trucco. Su qualsiasi JavaScript che devo inviare il modulo che ho appena inserito:

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

E questo salta la convalida quando non ne ho bisogno. Invia semplicemente il modulo e carica una pagina diversa, ecc.

Ma se l'utente fa clic sul pulsante di invio (ovvero type="button"non type="submit"), la convalida viene eseguita prima di consentire l'invio del modulo e, se non valido, non inviato.

Spero che questo aiuti gli altri a non provare un codice lungo e complicato. Basta non usare onsubmitse non necessario, e usare onclick. Ma ricordati di passare type="submit"a type="button"e, per favore, non dimenticare di farlo submit()con JavaScript.


28

Sono d'accordo con Shog9, anche se potrei invece usare:

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

Secondo w3schools , il <button>tag ha un comportamento diverso su diversi browser.


18

Supponiamo che il tuo modulo HTML abbia id="form_id"

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

Aggiungi questo snippet jQuery al codice per vedere il risultato,

$("#form_id").submit(function(){
  return false;
});

18

Puoi semplicemente ottenere il riferimento dei tuoi pulsanti usando jQuery e prevenirne la propagazione come di seguito:

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

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

            return false;
    });});

2
e.preventDefault(); e.stopPropagation();è abbastanza per far funzionare le cose. e.stopImmediatePropagation()questo genera un errore del metodo indefinito in Chrome.
Subroto,

14

$("form").submit(function () { return false; }); ciò impedirà l'invio del pulsante o puoi semplicemente cambiare il tipo di pulsante in "pulsante" <input type="button"/>invece di <input type="submit"/> Quale funzionerà solo se questo pulsante non è l'unico pulsante in questo modulo.


2
Questo è per jQuery, un equivalente in Javascript è: myform.onsubmit = function () {return false} ... inoltre, anche se si rimuove il pulsante di invio, è possibile inviare il modulo anche premendo invio da un altro campo del modulo.
Synexis,

10

Questo è un errore html5 come è stato detto, puoi comunque avere il pulsante come invio (se vuoi coprire sia utenti javascript che non javascript) usandolo come:

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

In questo modo annullerai l'invio ma continuerai a fare qualsiasi cosa tu stia facendo nelle funzioni jquery o javascript e invii gli utenti che non hanno javascript.


8

Sono sicuro che su FF il

removeItem 

la funzione incontra un errore JavaScript, questo non accade su IE

Quando viene visualizzato l'errore javascript, il codice "return false" non verrà eseguito, rendendo la pagina di postback


8

Il ritorno false impedisce il comportamento predefinito. ma il ritorno false interrompe il gorgoglio di ulteriori eventi di clic. Ciò significa che se ci sono altri collegamenti a clic dopo che questa funzione viene chiamata, gli altri non lo considerano.

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

O semplicemente puoi mettere così

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

7

Basta aggiungere il e.preventDefault();tuo metodo per impedire alla tua pagina di inviare moduli.

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

Secondo il documento Web MDN

Il metodo preventDefault () dell'interfaccia Event dice all'agente utente che se l'evento non viene esplicitamente elaborato, la sua azione predefinita non dovrebbe essere presa in considerazione come sarebbe normalmente. L'evento continua a propagarsi come al solito, a meno che uno dei suoi ascoltatori non chiami stopPropagation ()o stopImmediatePropagation (), uno dei due termini la propagazione.


6

Imposta il pulsante in modo normale e usa event.preventDefault come ..

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

   In function...

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

4
return false;

È possibile restituire false alla fine della funzione o dopo la chiamata della funzione.

Finché è l'ultima cosa che accade, il modulo non verrà inviato.


2

Ecco un approccio semplice:

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

});

1

Il seguente codice di esempio mostra come impedire che il clic sul pulsante invii il modulo.

Puoi provare il mio codice di esempio:

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


0

La funzione removeItem contiene effettivamente un errore, che fa sì che il pulsante del modulo esegua il comportamento predefinito (inviando il modulo). La console degli errori javascript in genere fornisce un puntatore in questo caso.

Dai un'occhiata alla funzione removeItem nella parte javascript:

La linea:

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

non funziona Prova questo invece:

rows.eq(rows.length-1).html('');
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.