risposta-alla-domanda-sullo-sviluppo-web-bd.com

Impedisci agli utenti di inviare un modulo premendo Invio

Ho un sondaggio su un sito web e sembra che ci siano alcuni problemi con gli utenti che accedono a invio (non so perché) e inviando accidentalmente il sondaggio (modulo) senza fare clic sul pulsante di invio. C'è un modo per impedirlo?

Sto usando HTML, PHP 5.2.9 e jQuery sul sondaggio.

675
DForck42

È possibile utilizzare un metodo come

$(document).ready(function() {
  $(window).keydown(function(event){
    if(event.keyCode == 13) {
      event.preventDefault();
      return false;
    }
  });
});

Nel leggere i commenti sul post originale, per renderlo più utilizzabile e consentire alle persone di premere Enter se hanno completato tutti i campi:

function validationFunction() {
  $('input').each(function() {
    ...

  }
  if(good) {
    return true;
  }
  return false;
}

$(document).ready(function() {
  $(window).keydown(function(event){
    if( (event.keyCode == 13) && (validationFunction() == false) ) {
      event.preventDefault();
      return false;
    }
  });
});
796
user83632

Non consentire l'immissione della chiave ovunque

Se non hai un <textarea> nel tuo modulo, aggiungi semplicemente quanto segue al tuo <form>:

<form ... onkeydown="return event.key != 'Enter';">

O con jQuery:

$(document).on("keydown", "form", function(event) { 
    return event.key != "Enter";
});

Ciò farà sì che ogni tasto premuto all'interno del modulo venga controllato su key. Se non è Enter, restituirà true e qualsiasi cosa continui come al solito. Se è Enter, restituirà false e tutto si fermerà immediatamente, quindi il modulo non verrà inviato.

Il keydown event è preferito su keyup poiché keyup è troppo tardi per bloccare il modulo submit. Storicamente esisteva anche keypress , ma questo è deprecato, così come lo è KeyboardEvent.keyCode . Dovresti usare KeyboardEvent.key che restituisce il nome del tasto premuto. Quando Enter è spuntato, questo dovrebbe essere 13 (inserimento normale) e 108 (inserimento numpad).

Nota che $(window) come suggerito in alcune altre risposte invece di $(document) non funziona per keydown/keyup in IE <= 8, quindi non è una buona scelta se vuoi coprire anche quei poveri utenti.

Consentire l'immissione della chiave solo su textareas

Se hai un <textarea> nel tuo modulo (che ovviamente dovrebbe accetta il tasto Invio), quindi aggiungi il gestore di keydown a ogni singolo elemento di input che non è un <textarea>.

<input ... onkeydown="return event.key != 'Enter';">
<select ... onkeydown="return event.key != 'Enter';">
...

Per ridurre il boilerplate, è meglio farlo con jQuery:

$(document).on("keydown", ":input:not(textarea)", function(event) {
    return event.key != "Enter";
});

Se sono associate altre funzioni del gestore di eventi su quegli elementi di input, che vorresti invocare per la chiave di invio per qualche motivo, previeni solo il comportamento predefinito dell'evento invece di restituire false, in modo che possa propagarsi correttamente agli altri gestori.

$(document).on("keydown", ":input:not(textarea)", function(event) {
    if (event.key == "Enter") {
        event.preventDefault();
    }
});

Consentire l'immissione della chiave su textareas e inviare solo i pulsanti

Se desideri consentire la chiave di invio anche sui pulsanti di invio <input|button type="submit">, puoi sempre perfezionare il selettore come di seguito.

$(document).on("keydown", ":input:not(textarea):not(:submit)", function(event) {
    // ...
});

Nota che input[type=text] come suggerito in alcune altre risposte non copre quegli input non testuali HTML5, quindi non è un buon selettore.

536
BalusC

Ho dovuto prendere tutti e tre gli eventi relativi alla pressione dei tasti per impedire che il modulo venisse presentato:

    var preventSubmit = function(event) {
        if(event.keyCode == 13) {
            console.log("caught ya!");
            event.preventDefault();
            //event.stopPropagation();
            return false;
        }
    }
    $("#search").keypress(preventSubmit);
    $("#search").keydown(preventSubmit);
    $("#search").keyup(preventSubmit);

Puoi combinare tutto quanto sopra in una bella versione compatta:

    $('#search').bind('keypress keydown keyup', function(e){
       if(e.keyCode == 13) { e.preventDefault(); }
    });
64
Upgradingdave

Se si utilizza uno script per eseguire l'invio effettivo, è possibile aggiungere la riga "return false" al gestore onsubmit in questo modo:

<form onsubmit="return false;">

Chiamare submit () sul modulo da JavaScript non attiverà l'evento.

44
Tom Hubbard

Sezione 4.10.22.2 L'invio implicito delle specifiche HTML5 del W3C dice:

A form element's default button è il primo pulsante submit in tree order di cui form owner è l'elemento form .

Se l'agente utente supporta l'invio implicito all'utente di un modulo (ad esempio, su alcune piattaforme che digitano il tasto "invio" mentre un campo di testo è focalizzato implicitamente invia il modulo), quindi lo fa per un modulo il cui pulsante predefinito ha un comportamento di attivazione definito deve indurre l'agente utente a eseguire i passi di attivazione dei clic sintetici su quel pulsante predefinito .

Nota: Di conseguenza, se il pulsante default è disabilitato, il modulo non viene inviato quando viene utilizzato un tale meccanismo di invio implicito. (Un pulsante non ha comportamento di attivazione quando disabilitato.)

Pertanto, un modo conforme agli standard per disabilitare qualsiasi invio implicito del modulo è inserire un pulsante di invio disabilitato come primo pulsante di invio nel modulo:

<form action="...">
  <!-- Prevent implicit submission of the form -->
  <button type="submit" disabled style="display: none" aria-hidden="true"></button>

  <!-- ... -->

  <button type="submit">Submit</button>
</form>

Una caratteristica interessante di questo approccio è che funziona senza JavaScript; indipendentemente dal fatto che JavaScript sia abilitato o meno, è necessario un browser web conforme agli standard per impedire l'invio di moduli impliciti.

39
Daniel Trebbien

Uso:

$(document).on('keyup keypress', 'form input[type="text"]', function(e) {
  if(e.keyCode == 13) {
    e.preventDefault();
    return false;
  }
});

Questa soluzione funziona su tutti i moduli su un sito Web (anche su moduli inseriti con Ajax), impedendo solo Enters nei testi di input. Mettilo in una funzione pronta per il documento e dimentica questo problema per tutta la vita.

22
Buzogany Laszlo

Invece di impedire agli utenti di premere Enter, che può sembrare innaturale, puoi lasciare il modulo così com'è e aggiungere qualche ulteriore validazione lato client: quando il sondaggio non è terminato, il risultato non viene inviato al server e l'utente riceve un messaggio Simpatico che dice cosa deve essere finito per completa la forma. Se stai usando jQuery, prova il plugin Validation:

http://docs.jquery.com/Plugins/Validation

Ciò richiederà più lavoro che intercettare il Enter pulsante, ma sicuramente fornirà un'esperienza utente più ricca.

20
bbmud

Non posso ancora commentare, quindi posterò una nuova risposta

La risposta accettata è ok-ish, ma non è stato necessario interrompere l'invio su numpad. Almeno nella versione corrente di Chrome. Ho dovuto modificare la condizione del codice chiave, quindi funziona.

if(event.keyCode == 13 || event.keyCode == 169) {...}
18
sparklos

Una bella soluzione jQuery semplice e semplice:

$("form").bind("keypress", function (e) {
    if (e.keyCode == 13) {
        return false;
    }
});
17
Eonasdan

È la mia soluzione per raggiungere l'obiettivo, è pulito ed efficace.

$('form').submit(function () {
  if ($(document.activeElement).attr('type') == 'submit')
     return true;
  else return false;
});
12
Developer

Un approccio completamente diverso:

  1. Il primo <button type="submit"> nel modulo verrà attivato alla pressione Enter.
  2. Questo è vero anche se il pulsante è nascosto con style="display:none;
  3. Lo script per quel pulsante può restituire false, che interrompe il processo di invio.
  4. Puoi ancora avere un altro <button type=submit> per inviare il modulo. Basta restituire true per mettere in cascata l'invio.
  5. Urgente Enter mentre il pulsante di invio reale è focalizzato attiverà il pulsante di invio reale.
  6. Urgente Enter all'interno di <textarea> o altri controlli del modulo si comportano normalmente.
  7. Urgente Enter all'interno dei controlli del modulo <input> verrà attivato il primo <button type=submit>, che restituisce false, e quindi non accade nulla.

Così:

<form action="...">
  <!-- insert this next line immediately after the <form> opening tag -->
  <button type=submit onclick="return false;" style="display:none;"></button>

  <!-- everything else follows as normal -->
  <!-- ... -->
  <button type=submit>Submit</button>
</form>
9
Erics

Dando al modulo un'azione di 'javascript: void (0);' sembra fare il trucco

<form action="javascript:void(0);">
<input type="text" />
</form>
<script>
$(document).ready(function() {
    $(window).keydown(function(event){
        if(event.keyCode == 13) {
    alert('Hello');
        }
    });
});
</script>
8
sidarcy
  1. Non utilizzare type = "submit" per input o pulsanti.
  2. Usa type = "button" e usa js [Jquery/angular/etc] per inviare il modulo al server.
6
Irfan Ashraf

Avevo bisogno di impedire solo input specifici dall'invio, quindi ho usato un selettore di classe, per far sì che fosse una funzionalità "globale" ovunque ne avessi bisogno.

<input id="txtEmail" name="txtEmail" class="idNoEnter" .... />

E questo codice jQuery:

$('.idNoEnter').keydown(function (e) {
  if (e.keyCode == 13) {
    e.preventDefault();
  }
});

In alternativa, se il keydown non è sufficiente:

$('.idNoEnter').on('keypress keydown keyup', function (e) {
   if (e.keyCode == 13) {
     e.preventDefault();
   }
});

Alcune note:

Modificando varie buone risposte qui, il Enter la chiave sembra funzionare per keydown su tutti i browser. In alternativa, ho aggiornato bind() al metodo on().

Sono un grande fan dei selettori di classe, soppesa tutti i pro e contro e le discussioni sul rendimento. La mia convenzione sui nomi è 'idSomething' per indicare che jQuery lo sta usando come ID, per separarlo dallo stile CSS.

6
goodeye

Potresti fare un metodo JavaScript per verificare se il file Enter la chiave è stata colpita e, in tal caso, per interrompere la presentazione.

<script type="text/javascript">
  function noenter() {
  return !(window.event && window.event.keyCode == 13); }
</script>

Basta chiamarlo sul metodo submit.

5
Brandon

Non si può fare un pulsante di invio. Basta inserire uno script per l'input (tipo = pulsante) o aggiungere eventListener se si desidera che invii i dati nel modulo.

Piuttosto usa questo

<input type="button">

di usare questo

<input type="submit">
4
Jimwel Anobong

Penso che sia ben coperto da tutte le risposte, ma se si utilizza un pulsante con un codice di convalida JavaScript, è sufficiente impostare onkeypress del modulo per Invio per chiamare l'invio come previsto:

<form method="POST" action="..." onkeypress="if(event.keyCode == 13) mySubmitFunction(this); return false;">

Il onkeypress JS potrebbe essere qualsiasi cosa tu debba fare. Non è necessario un cambiamento globale più ampio. Questo è particolarmente vero se non sei quello che codifica l'app da zero, e sei stato portato a riparare il sito di qualcun altro senza dividerlo e ricontrollarlo.

2
garlicman

Ho avuto un problema simile, in cui avevo una griglia con "campi di testo ajax" (Yii CGridView) e un solo pulsante di invio. Ogni volta che ho fatto una ricerca su un campo di testo e premuto invio il modulo inviato. Ho dovuto fare qualcosa con il pulsante perché era l'unico pulsante comune tra le viste (pattern MVC). Tutto quello che dovevo fare era rimuovere type="submit" e mettere onclick="document.forms[0].submit()

2
StackUnder

Ci sono già molte buone risposte, voglio solo contribuire con una prospettiva UX. I controlli della tastiera nei moduli sono molto importanti.

La domanda è come disabilitare l'invio su keypress Enter. Non come ignorare Enter in un'intera applicazione. Quindi considera di associare il gestore a un elemento del modulo, non alla finestra.

La disabilitazione di Enter per l'invio di moduli dovrebbe comunque consentire quanto segue:

  1. Modulo di invio tramite Enter quando il pulsante di invio è focalizzato.
  2. Modulo di invio quando tutti i campi sono popolati.
  3. Interazione con pulsanti di non invio tramite Enter.

Questo è solo il boilerplate ma segue tutte e tre le condizioni.

$('form').on('keypress', function(e) {
  // Register keypress on buttons.
  $attr = $(e.target).attr('type);
  if ($attr === 'button' || $attr === 'submit') {
    return true;
  }

  // Ignore keypress if all fields are not populated.
  if (e.which === 13 && !fieldsArePopulated(this)) {
    return false;
  }
});
1
Solvitieg

INVIO SOLO BLOCCO ma non altre importanti funzionalità del tasto Invio, come la creazione di un nuovo paragrafo in un <textarea>:

window.addEventListener('keydown', function(event) {
  //set default value for variable that will hold the status of keypress
  pressedEnter = false;

  //if user pressed enter, set the variable to true
  if (event.keyCode == 13)
    pressedEnter = true;

  //we want forms to disable submit for a tenth of a second only
  setTimeout(function() {
    pressedEnter = false;
  }, 100)

})

//find all forms
var forms = document.getElementsByTagName('form')

//loop through forms
for (i = 0; i < forms.length; i++) {
  //listen to submit event
  forms[i].addEventListener('submit', function(e) {
    //if user just pressed enter, stop the submit event
    if (pressedEnter == true) {
      updateLog('Form prevented from submit.')
      e.preventDefault();
      return false;
    }

    updateLog('Form submitted.')
  })
}

var log = document.getElementById('log')
updateLog = function(msg) {
  log.innerText = msg
}
input,
textarea {
  display: inline-block;
  margin-bottom: 1em;
  border: 1px solid #6f6f6f;
  padding: 5px;
  border-radius: 2px;
  width: 90%;
  font-size: 14px;
}

input[type=submit] {
  background: lightblue;
  color: #fff;
}
<form>
  <p>Sample textarea (try enter key):</p>
  <textarea rows="4">Hit enter, a new line will be added. But the form won't submit</textarea><br/>
  <p>Sample textfield (try enter key):</p>
  <input type="text" placeholder="" />
  <br/>
  <input type="submit" value="Save" />
  <h3 id="log"></h3>
</form>
1
mate.gwozdz

Questo funziona per me

jQuery.each($("#your_form_id").find('input'), function(){
    $(this).bind('keypress keydown keyup', function(e){
       if(e.keyCode == 13) { e.preventDefault(); }
    });
});
0
Pjl

Mi piacerebbe aggiungere un piccolo codice CoffeeScript (non testato sul campo):

$ ->
    $(window).bind 'keypress', (event) ->
        if event.keyCode == 13
            unless {'TEXTAREA', 'SELECT'}[event.originalEvent.srcElement.tagName]
                event.preventDefault()

(Spero ti piaccia il trucco di Nizza nella clausola a meno.)

0
edx

Qualcosa a cui non ho visto risposta qui: quando si passa attraverso gli elementi sulla pagina, premendo Enter quando si arriva al pulsante di invio si attiverà il gestore onsubmit nel modulo, ma verrà registrato l'evento come MouseEvent. Ecco la mia soluzione breve per coprire la maggior parte delle basi:

Questa non è una risposta relativa a jQuery

HTML

<form onsubmit="return false;" method=post>
  <input type="text" /><br />
  <input type="button" onclick="this.form.submit()" value="submit via mouse or keyboard" />
  <input type="button" onclick="submitMouseOnly(event)" value="submit via mouse only" />
</form>

JavaScript

window.submitMouseOnly=function(evt){
    let allow=(evt instanceof MouseEvent) && evt.x>0 && evt.y>0 && evt.screenX > 0 && evt.screenY > 0;
    if(allow)(evt.tagName=='FORM'?evt.target:evt.target.form).submit();
}

Per trovare un esempio funzionante: https://jsfiddle.net/nemesarial/6rhogva2/

0
Nemesarial

Nel mio caso specifico ho dovuto interrompere INVIO dall'invio del modulo e anche simulare il clic del pulsante di invio. Questo perché il pulsante di invio aveva un gestore di clic su di esso perché eravamo all'interno di una finestra modale (codice vecchio ereditato). In ogni caso ecco le mie soluzioni combo per questo caso.

    $('input,select').keypress(function(event) {
        // detect ENTER key
        if (event.keyCode == 13) {
            // simulate submit button click
            $("#btn-submit").click();
            // stop form from submitting via ENTER key press
            event.preventDefault ? event.preventDefault() : event.returnValue = false;
        }
    });

Questo caso d'uso è particolarmente utile per le persone che lavorano con IE8.

0
Stone