Действие по умолчанию для выполнения при нажатии ввода в форме
У меня есть форма jsf 1.2 с двумя кнопками и несколькими полями ввода. Первая кнопка отбрасывает введенные значения и повторно заполняет страницу значениями из db, вторая - сохраняет введенные значения. Проблема возникает, когда пользователь нажимает кнопку ввода, пока курсор находится в одном из полей ввода, форма отправляется и действие, связанное с первой кнопкой, выполняется.
Код выглядит следующим образом:
<h:commandButton action="#{bean.reset}" value="Reset" />
<h:commandButton action="#{bean.save}" value="Save" />
<!-- h:datatable with several h:inputText elements -->
Можно ли объявить конкретную кнопку как действие по умолчанию при нажатии enter? Это поведение действительно указано где-то?
Ответы
Ответ 1
Это не относится к JSF. Это характерно для HTML. Раздел спецификаций в формате HTML5 4.10.22.2 в основном указывает, что первый элемент <input type="submit">
в "древовидном порядке" в том же <form>
, что и текущий входной элемент в дереве HTML DOM будет вызываться при вводе.
В основном два метода обхода:
-
Используйте JavaScript для захвата нажатия клавиши ввода и вызова нужной кнопки.
<h:form onkeypress="if (event.keyCode == 13) { document.getElementById('formid:saveid').click(); return false; }">
Если у вас есть текстовые поля в форме, вы должны поместить JS во все элементы ввода, отличные от 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 в свой собственный файл .css
; использование style
является плохой практикой, приведенный выше пример для краткости.
Если вы используете 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>
, который, в свою очередь, проверяет, нажата ли клавиша ввода в элементе non-textarea/button/link, а затем вызывает click()
на целевом элементе. В основном то же, что и в упомянутом выше обходном пути в этом ответе.
Ответ 2
Я нашел способ, который менее взломан и работает хорошо. Идея - скрытая 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" />
Это приведет к появлению невидимой командной кнопки, которая в соответствии с правилом первой-следующей-кнопки отправки может быть активирована.
Ответ 3
Чтобы скрыть элементы, вы можете использовать css: style="visibility: hidden"
Чтобы изменить действие по умолчанию, если вы используете простые шрифты, вы можете использовать: <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>
Источник: Направляет новый компонент: DefaultCommand
Ответ 4
Следуя рекомендации 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
Ответ 5
Игнорировать клавишу 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>
Ответ 6
Вы можете использовать h:commandLink
для первой кнопки и h:commandButton
ее с помощью css, например, h:commandButton
.
Например, "btn btn-default"
загрузки "btn btn-default"
выглядят одинаково для commandLink и commandButton.
Ответ 7
Попробуйте этот атрибут в элементе:
onkeypress="if (event.keyCode == 13) { this.blur(); return false; }"