Действие по умолчанию для выполнения при нажатии enter в форме
У меня есть форма jsf 1.2 с двумя кнопками и несколькими полями ввода. Первая кнопка отбрасывает введенные значения и повторно заполняет страницу значениями из БД, вторая кнопка сохраняет введенные значения. Проблема возникает, когда пользователь нажимает enter, когда курсор находится в одном из полей ввода, форма отправляется и выполняется действие, связанное с первой кнопкой.
код выглядит так:
<h:commandButton action="#{bean.reset}" value="Reset" />
<h:commandButton action="#{bean.save}" value="Save" />
<!-- h:datatable with several h:inputText elements -->
можно ли объявить конкретная кнопка в качестве действия по умолчанию при нажатии enter? Это поведение действительно где-то указано?
6 ответов
это не относится к JSF. Это специфично для HTML. The HTML5 формирует раздел спецификации 4.10.22.2 в основном указывает, что первое происходит <input type="submit">
в элементе "дерево" в том же <form>
в качестве текущего элемента ввода в дереве HTML DOM будет вызываться при нажатии enter.
есть в основном два способа решения:
-
используйте JavaScript для захвата клавиши enter нажмите и вызовите нужный кнопка.
<h:form onkeypress="if (event.keyCode == 13) { document.getElementById('formid:saveid').click(); return false; }">
если у вас есть textareas в форме, вы хотели бы поместить JS на все элементы ввода non-textarea вместо формы. См. также запретить пользователям отправлять форму, нажав Enter.
-
поменять кнопки в HTML и использовать CSS поплавки, чтобы поменять их обратно.
<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>
для этого может потребоваться только некоторая пиксельная настройка. Конечно, поместите CSS в свой собственный ; через
style
плохая практика, приведенный выше пример для краткости.
если вы используете PrimeFaces, так как 3.2 вы можете использовать <p:defaultCommand>
чтобы декларативно определить кнопку, которая должна вызываться при нажатии клавиши enter в форме.
<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>
который в свою очередь проверяет, нажата ли клавиша enter в элементе non-textarea/button/link, а затем вызывает click()
на целевом элементе. В основном то же самое, что и 1-й упомянутый обходной путь в этом ответе.
Я нашел способ, который менее хакерский и работает хорошо. Идея скрытая 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" />
это приведет к невидимой командной кнопке, которая в соответствии с правилом first-next-submit-button может быть активирована.
чтобы скрыть элементы, вы можете использовать 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>
следуя рекомендации BalusC по решению проблемы с помощью JavaScript, я написал код jQuery для выполнения этой работы:
$(function(){
$('form').on('keypress', function(event){
if(event.which === 13 && $(event.target).is(':input')){
event.preventDefault();
$('#save').trigger('click');
}
});
});
игнорировать клавишу ENTER только в текстовых полях ввода (источник):
<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>
можно использовать h:commandLink
для первой кнопки и стиль его с помощью CSS, как h:commandButton
.
например bootstraps "btn btn-default"
выглядят одинаково на commandLink и commandButton.