Действие по умолчанию, выполняемое при нажатии ввода в форме

У меня есть форма jsf 1.2 с двумя кнопками и несколькими полями ввода. Первая кнопка отбрасывает введенные значения и повторно заполняет страницу значениями из базы данных, вторая кнопка сохраняет введенные значения. Проблема возникает, когда пользователь нажимает клавишу ввода, когда курсор находится в одном из полей ввода, форма отправляется и выполняется действие, связанное с первой кнопкой.

Код выглядит так:

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

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

Можно ли объявить конкретную кнопку действием по умолчанию при нажатии клавиши ввода? Это поведение где-то действительно указано?


person Jörn Horstmann    schedule 30.03.2011    source источник
comment
Тринидад предоставляет такую ​​функциональность в своем теге формы. ссылка   -  person lkdg    schedule 30.03.2011
comment
Привет, Йорн, я бы отключил автоматическую отправку для форм с одним полем ввода. Я думаю, вы не хотите, чтобы форма отправлялась нажатием клавиши возврата в поле. - Кстати: увидимся на JAX в этом году?   -  person Thomas    schedule 30.03.2011
comment
Томас: Есть ли простой способ отключить отправку при входе (возможно, без javascript, как в ответе BalusCs)? И да, я буду в Jax в Майнце.   -  person Jörn Horstmann    schedule 30.03.2011
comment
Primefaces также будет включать компонент DefaultCommand, о котором только что было объявлено в блоге primefaces (blog.primefaces.org/ ? p = 1787).   -  person Jörn Horstmann    schedule 29.02.2012


Ответы (6)


Это не относится к JSF. Это характерно для HTML. В разделе 4.10.22.2 спецификации форм HTML5 в основном указывается, что первый встречающийся <input type="submit"> элемент в "древовидной структуре" в том же <form>, что и текущий элемент ввода в дереве HTML DOM, будет вызываться при нажатии клавиши ввода.

В основном есть два обходных пути:

Если вы используете PrimeFaces, начиная с версии 3.2, вы можете использовать <p:defaultCommand>, чтобы декларативно определить кнопку, которая должна быть вызвана при нажатии клавиши ввода в форме.

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

Это скрыто с использованием JavaScript для того, что присоединяет keydown слушателя к родительскому <h:form>, который, в свою очередь, проверяет, нажата ли клавиша ввода в элементе, не являющемся текстовым полем / кнопкой / ссылкой, а затем вызывает click() в целевом элементе. В основном то же самое, что и первое упомянутое обходное решение в этом ответе.

person BalusC    schedule 30.03.2011
comment
Спасибо, я немного изменил javascript, чтобы он выполнялся только в полях ввода текста, иначе нажатие клавиши ввода, когда любая кнопка имеет фокус, также приведет к выполнению действия сохранения. Модифицированный обработчик выглядит так: if (event.keyCode == 13 && event.target.nodeName == 'INPUT' && event.target.getAttribute('type') == 'text') { document.getElementById('form:saveButton').click(); return false; } - person Jörn Horstmann; 30.03.2011
comment
Я отмечаю, что defaultCommand выполняется при нажатии клавиши - есть ли способ изменить ее на нажатие клавиши? У нас возникает проблема, когда наша форма отправляется много раз, если клавиша ввода удерживается иногда - не всегда. - person BigMac66; 26.02.2018

Я нашел способ, который менее хакерский и хорошо работает. Идея скрытая commandButton.

К сожалению, стиль display:none использовать нельзя, потому что тогда commandButton будет проигнорирован. visibility:hidden не годится, потому что он сохраняет пространство для компонента зарезервированным.

Но мы можем настроить стиль так, чтобы его внешний вид был равен нулю с помощью следующего CSS:

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

И теперь все, что вам нужно, это:

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

В результате появится невидимая командная кнопка, которая может быть активирована в соответствии с правилом первой следующей кнопки отправки.

person icza    schedule 12.05.2014
comment
Разве это не фокусируется, когда вы используете кнопку табуляции? - person Jasper de Vries; 10.03.2015
comment
@JasperdeVries Нет, это не так, потому что не видно (visibility:hidden;). - person icza; 10.03.2015
comment
Это решение IMO лучше, чем утвержденное, поскольку оно решает именно ту проблему, о которой идет речь, с меньшими усилиями. - person foo; 28.03.2018

Чтобы скрыть элементы, вы можете использовать css: style="visibility: hidden"

Чтобы изменить действие по умолчанию, если вы используете Primefaces, вы можете использовать: <p:defaultCommand target="yourButtonDefault" /> Например:

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

Источник: новый компонент Primefaces: DefaultCommand

person Cristian Arteaga    schedule 01.03.2015
comment
Используйте это в сочетании с ‹p: focus›, и вы будете потрясены! - person Dimitri Dewaele; 12.03.2015
comment
Обратите внимание: если вы хотите предотвратить отправку форм, обязательно удалите все p:defaultCommand вхождения. - person Jasper de Vries; 26.04.2017
comment
Я отмечаю, что defaultCommand выполняется при нажатии клавиши - есть ли способ изменить ее на нажатие клавиши? У нас возникает проблема, когда наша форма отправляется много раз, если клавиша ввода удерживается иногда - не всегда. - person BigMac66; 26.02.2018

Следуя рекомендациям BalusC по решению проблемы с помощью JavaScript, я написал код jQuery для выполнения этой работы:

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

person Tim Büthe    schedule 20.01.2014

Игнорируйте клавишу ENTER только в полях ввода текста (source):

<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>
person Sergey Chepurnov    schedule 29.04.2015

Вы можете использовать h:commandLink для первой кнопки и стилизовать ее с помощью css, например h:commandButton.

Например, начальные страницы "btn btn-default" выглядят одинаково для commandLink и commandButton.

person Stefan    schedule 02.03.2018