Acción predeterminada a ejecutar al pulsar intro en un formulario


Tengo un formulario jsf 1.2 con dos botones y varios campos de entrada. El primer botón descarta los valores introducidos y repobla la página con valores de una bd, el segundo botón guarda los valores introducidos. El problema ocurre cuando el usuario presiona enter mientras el cursor está en uno de los campos de entrada, el formulario se envía y la acción asociada con el primer botón se ejecuta.

El código se ve así:

<h:commandButton action="#{bean.reset}" value="Reset" />
<h:commandButton action="#{bean.save}" value="Save" />

<!-- h:datatable with several h:inputText elements -->

Es posible declarar un botón específico como ¿la acción predeterminada al pulsar intro? ¿Es este comportamiento realmente especificado en alguna parte?

Author: BalusC, 2011-03-30

6 answers

Esto no es específico de JSF. Esto es específico de HTML. La especificación de formularios HTML5 sección 4.10.22.2 básicamente especifica que el primer elemento <input type="submit"> en el "orden de árbol" en el mismo <form> que el elemento de entrada actual en el árbol DOM HTML se invocará en la prensa enter.

Básicamente, Hay dos soluciones:

  • Utilice JavaScript para capturar la tecla enter e invocar el botón deseado.

    <h:form onkeypress="if (event.keyCode == 13) { document.getElementById('formid:saveid').click(); return false; }">
    

    Si tiene áreas de texto en el formulario, te gustaría poner el JS en todos los elementos de entrada no textarea en lugar de en el formulario. Ver también Evitar que los usuarios envíen un formulario pulsando Enter.


  • Intercambia los botones en HTML y usa flotadores CSS para volver a intercambiarlos.

    <div style="width: 100px; clear: both;">
        <h:commandButton action="#{bean.save}" value="Save" style="float: right;" />
        <h:commandButton action="#{bean.reset}" value="Reset" style="float: left;" />
    </div>
    

    Puede que solo requiera un poco de ajuste de píxeles. Por supuesto, poner CSS en su propio archivo .css; usar style es una mala práctica, el ejemplo anterior es por brevedad.


Si usted usa PrimeFaces, desde 3.2 puede utilizar <p:defaultCommand> para identificar declarativamente el botón que debe ser invocado al presionar la tecla enter dentro del formulario.

<h:form>
    <p:defaultCommand target="save" />
    ...
    <h:commandButton id="reset" action="#{bean.reset}" value="Reset" />
    <h:commandButton id="save" action="#{bean.save}" value="Save" />
</h:form>

Está debajo de las portadas usando JavaScript para aquello que une un receptor keydown al padre <h:form> que a su vez comprueba si la tecla enter se presiona en un elemento no textarea/button/link, y luego invoca click() en el elemento de destino. Básicamente lo mismo que 1st mencionó solución alternativa en esta respuesta.

 100
Author: BalusC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:25:57

Encontré una manera que es menos hacky y funciona bien. La idea es un commandButton oculto.

Desafortunadamente el estilo display:none no se puede usar porque entonces el commandButton será ignorado. visibility:hidden no es bueno porque mantiene reservado el espacio del componente.

Pero podemos afinar el estilo para que el tamaño de su apariencia visual sea cero con el siguiente CSS:

.zeroSize {
    visibility: hidden;
    padding: 0px;
    margin: 0px;
    border: 0px;
    width: 0px;
    height: 0px;
}

Y ahora todo lo que se necesita es:

<h:commandButton value="" action="#{bean.save}" class="zeroSize" />

Esto dará lugar a un botón de comando invisible que de acuerdo con la regla del botón primero-siguiente-enviar-se puede activar.

 9
Author: icza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-12 12:11:53

Para ocultar elementos puede usar css: style="visibility: hidden"

Para cambiar la acción predeterminada si usa primefaces, puede usar: <p:defaultCommand target="yourButtonDefault" /> Por ejemplo:

<h:form id="form">

    <h:panelGrid columns="3" cellpadding="5">
        <h:outputLabel for="name" value="Name:" style="font-weight:bold"/>
        <p:inputText id="name" value="#{defaultCommandBean.text}" />
        <h:outputText value="#{defaultCommandBean.text}" id="display" />
    </h:panelGrid>

    <p:commandButton value="Button1" id="btn1" actionListener="#{defaultCommandBean.btn1Submit}" ajax="false"/>
    <p:commandButton value="Button2" id="btn2" actionListener="#{defaultCommandBean.btn2Submit}" />
    <h:commandButton value="Button3" id="btn3" actionListener="#{defaultCommandBean.btn3Submit}" />

    <p:defaultCommand target="btn3" />

</h:form>

Fuente: Primefaces nuevo componente: DefaultCommand

 4
Author: Cristian Arteaga,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-01 06:58:19

Siguiendo la recomendación de BalusC de resolver el problema usando JavaScript, escribí un código jQuery para hacer el trabajo:

$(function(){
  $('form').on('keypress', function(event){
    if(event.which === 13 && $(event.target).is(':input')){
        event.preventDefault();
        $('#save').trigger('click');
    }
  });
});

CodePen: http://codepen.io/timbuethe/pen/AoKJj

 3
Author: Tim Büthe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-20 13:22:41

Ignore la tecla ENTER solo en los campos de entrada de texto (fuente):

<script type="text/javascript"> 

  function stopRKey(evt) { 
     var evt = (evt) ? evt : ((event) ? event : null); 
     var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null); 
     if ((evt.keyCode == 13) && (node.type=="text"))  {return false;} 
  } 

  document.onkeypress = stopRKey; 

</script>
 3
Author: Sergey Chepurnov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-29 12:45:42

Puedes usar un h:commandLink para el primer botón y darle estilo con css como el h:commandButton.

Por ejemplo, los bootstraps "btn btn-default" tienen el mismo aspecto en commandLink y commandButton.

 0
Author: Stefan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-03 15:53:11