JSF как временно отключить валидаторы для сохранения черновика - PullRequest
12 голосов
/ 06 мая 2010

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

Я считаю, что эта проблема является общей для многих веб-приложений, но не могу найти какой-либо общепризнанной схемы, как это должно быть реализовано. Можете ли вы посоветовать, как этого добиться?

Пока я вижу следующие опции:

  1. Использование немедленного = true для кнопки «Сохранить черновик» не работает, поскольку данные пользовательского интерфейса не будут храниться в бине, поэтому я не смогу получить к ним доступ. Технически я мог бы найти данные в дереве компонентов пользовательского интерфейса, но обходить это, кажется, не очень хорошая идея.
  2. удалить все поля проверки со страницы и программно проверить данные в обработчике действий, определенном для формы. Опять же, не очень хорошая идея, форма действительно сложная, есть много полей, поэтому проверка, реализованная таким образом, будет очень грязной.
  3. реализовать мои собственные валидаторы, которые будут управляться некоторым атрибутом запроса, который будет установлен для стандартной отправки формы (с ожидаемой полной валидацией) и будет отключен для отправки «сохранить как черновик» (когда валидация должна быть пропущена). Опять же, не очень хорошее решение, мне нужно будет предоставить свои собственные оболочки для всех валидаторов, которые я использую.

Но, как вы видите, никто не может быть разумным. Неужели нет простого решения проблемы?

Ответы [ 2 ]

8 голосов
/ 06 мая 2010

Это действительно не так просто. Валидация довольно тесно связана в жизненном цикле JSF.

Я бы лично выбрал вариант 1. Правда, грязная работа, но вы можете просто спрятать это в служебном классе или около того. Просто возьмите рассматриваемый <h:form> из корня просмотра, рекурсивно итерируйте его дочерние элементы, проверяя, если component instanceof EditableValueHolder верно, сохраните найденную пару id-значение в виде Map и, наконец, сохраните ее.

В качестве четвертой альтернативы вы можете сохранять все данные независимо, используя аксиальные полномочия. jQuery помогает в этом.

$.post('/savedraft', $('#formid').serialize());

Требуется только поддержка Javascript на стороне клиента.


Обновление : служебная библиотека JSF OmniFaces имеет обработчик тегов <o:ignoreValidationFailed> для точных целей. Это действительно было не простое решение, так как для него также требовался пользовательский <h:form>. Он выполняет свою работу, предоставляя пользовательский экземпляр FacesContext на этапах проверки и обновления значений модели, который выполняет NOOP в методах validationFailed() и renderResponse(). Таким образом, компоненты по-прежнему считаются недействительными, а сообщения по-прежнему прикреплены, но все равно они переходят к обновлению значений модели и вызывают фазы приложения.

1 голос
/ 28 октября 2014

У меня была та же проблема, и мне не нравилась идея пропустить все проверки.После долгих раздумий я в итоге захотел только пропустить проверку обязательных полей.Логика этого заключается в том, что пользователь либо заполняет поле правильно , либо не заполняет его вообще.Это очень важно для меня, потому что все заканчивается в базе данных и, конечно, я не хочу переполнять поле базы данных или в конечном итоге сохранить значение String в поле базы данных INT, например.

По моему опыту, пропуск обязательных полей позволяет достаточно запаса маневра, чтобы сохранить черновик.Чтобы добиться этого, я написал requiredWarnValidator, который показывает одно предупреждающее сообщение.

public void validate(FacesContext context, UIComponent component, Object value)
    throws ValidatorException {

  if (value == null) {
    FacesMessage message = new FacesMessage();
    message.setSeverity(FacesMessage.SEVERITY_WARN);
    message.setSummary("This field is required.");
    context.addMessage(component.getClientId(), message);
    context.validationFailed();
  }
}

В этом валидаторе я не выбрасываю ValidatorException(), потому что хочу пройти фазу валидации, но я вызываюvalidationFailed() потому что я хочу знать, не заполнено ли обязательное поле.

У меня есть флаг (completed) в сущности, которую я использую для сохранения своей формы.При сохранении формы я проверяю isValidationFailed().

  • , если true хотя бы одно обязательное поле не заполнено: я снимаю флажок completed.(это черновик)
  • если false заполнена вся форма: я проверяю флаг completed.(это не черновик)

Это также позволяет мне иметь одну кнопку «Сохранить» вместо двух кнопок («Сохранить» и «Сохранить как черновик»).

Примечания и известные подводные камни:

  • Если вы сохраняете свой черновик в базе данных, вы должны убедиться, что нет никаких ограничений NOT NULL.
  • При использовании преобразователей и валидаторов вы должны убедиться, что они могут обрабатывать значения NULL.
  • Вы потеряете звездочку обязательного поля в outputLabel для своих полей.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...