JSF skip Required-Validation без немедленного = true
У меня есть несколько форм, где у меня есть обязательные поля и необязательные поля.
Чтобы отправить такую форму, я требую проверки на требуемый атрибут, который будет выполняться, что отлично работает.
Чтобы отменить такую форму, я использую атрибут immediate="true"
в p:commandbutton
, что делает его действие происходить во время Заявлять значения запроса -Phase, как описано здесь: Как пропустить проверку при нажатии определенной кнопки?
Однако для больших форм я хочу предоставить пользователю кнопку Save-Button, поэтому он может продолжить позже.
Чтобы просто сохранить текущее состояние, я также хочу игнорировать проверку требуемого атрибута. Однако использование immediate="true"
не работает, потому что тогда мой метод сохранения просто ничего не сохраняет, потому что жизненный цикл JSF никогда не попадает в "UpdateModelValues" -Phase. (Согласно http://www.javacodegeeks.com/2012/01/jsf-and-immediate-attribute-command.html)
Итак, как обойти требуемую проверку, но не пропускать половину жизненного цикла?
Ответы
Ответ 1
Каждая кнопка создает запись внутри Param-List, если она является членом формы.
Поэтому я просто применил проверку наличия этой записи в "обязательном" параметре:
<h:form id="form" prependId="true">
...
<p:inputText id="someId"
required="#{param['form:save']==null}" ... />
...
<p:commandButton id="save" value="Save" />
<p:commandButton id="submit" value="Submit" />
<p:commandButton id="cancel" value="Cancel" immediate="true" />
</h:form>
Когда я нажимаю "Отправить", param['form:save']
есть NULL
, который затем превращает выражение в true
, поэтому выполняется проверка.
Когда я нажимаю "Сохранить", param['form:save']
есть NOT NULL
(но пустой!), который разрешает false
, поэтому проверка игнорируется. (Или предположим, что JSF считает, что это не обязательное поле из-за выражения, оцениваемого false
)
Ответ 2
если вы хотите пропустить проверку при нажатии кнопки, а затем просто добавить параметр к кнопке, где вы хотите пропустить ее. Пример:
<p:commandButton value="button1" action="#{bean.action()}" >
<f:param name="skipValidator" value="true"/>
</p:commandButton>
Затем в валидаторе вы можете прочитать этот параметр, и если это правда, то пропустите его:
@FacesValidator("com.validators.MyValidator")
public class MyValidator implements Validator{
public void validate(FacesContext ct, UIComponent co, Object obj) throws ValidatorException {
if(!continueValidation()){
return;
}
// validation process
}
protected boolean continueValidation() {
String skipValidator= FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("skipValidator");
if (skipValidator != null && skipValidator.equalsIgnoreCase("true")) {
return false;
}
return true;
}
}
Ответ 3
Это отличный вопрос и очень полезный ответ. Этот подход экономит массу хлопот с помощью immediate="true"
.
Я хотел бы добавить эту информацию (но мне еще не разрешено прокомментировать). Кажется, что для ваших примеров кода требуется JSF 2.0 или выше (исправьте меня). Если вы похожи на меня, я проклял использовать JSF 1.1/1.2, рассмотрите эти изменения/дополнения:
<h:form id="form">
...
<p:inputText id="someId" required="#{!empty param['save']}" ... />
...
<p:commandButton id="save" value="Save" />
</h:form>
- В JSF 1.1 нет атрибута prependId
- Поэтому в параметре [...] вы должны указать только идентификатор кнопки
- Вы используете синтаксис
="{true and ...}"
, который может быть ошибкой (нет #
)?
- Как вы можете видеть из своей собственной истории редактирования логика "null или not null" не очень интуитивно понятна:) Вот почему мне сразу понравилась версия
!empty ...
, когда я наткнулся на нее.
Ответ 4
В моем случае я не нашел clientId кнопки в параметрах, но я нашел это
param['javax.faces.source'] = buttonClientId
в запросе. Значение будет клиентом нажатой кнопки.
Ответ 5
Альтернативой тому, что предложили другие, является использование пользовательского BeanValidator
, который будет проверять форму, если, скажем, нажал кнопку с сохранением id. Любая другая кнопка, неявно определенная для выполнения проверки, не проверяет, а просто передает ваши данные. Найдите полный приятный и чистый пример здесь