JSF 2.0;Валидатор тег «отключен» зависит от значения со страницы - PullRequest
2 голосов
/ 28 марта 2012

В моем приложении jsf я хочу проверить поле, которое должно проверяться только при проверке одного параметра в SelectOneRadio.

Я обнаружил, что <f:validator> имеет атрибут, который называется "отключен".

Могу ли я использовать это, чтобы проверить значение из другого поля?

Я пытался, но у меня нет доступа к значению из моего компонента.

<h:selectOneRadio value="#{myBean.checkedSelectOneRadioValue}">
    <f:selectItems value="#{myBean.valuesForSelectOneRadio}" />
</h:selectOneRadio>


<f:validator validatorId="myValidator" disabled="#{myBean.checkedSelectOneRadioValue == 'TEST'}" />

Есть ли способ достичь этого без написания собственного обработчика validator?

Спасибо!

Ответы [ 3 ]

9 голосов
/ 27 мая 2012

<f:validator> - это обработчик тегов, а не компонент пользовательского интерфейса.Все его атрибуты по определению оцениваются во время построения представления, а не во время визуализации представления.Время построения представления - это тот момент, когда файл XHTML анализируется в дереве компонентов JSF, как доступно context.getViewRoot().Одно и то же представление обычно повторно используется в постбэках к тому же представлению, возвращая действия null / void in (ajax).

Таким образом, вы не можете позволить атрибуту обработчика тега зависеть от атрибута времени визуализациикоторый может измениться во время запроса обратной передачи.Один из способов - выполнить эту проверку внутри самого пользовательского валидатора.

Например,

<h:inputText>
    <f:validator validatorId="myValidator" />
    <f:attribute name="radio" value="#{myBean.checkedSelectOneRadioValue}" />
</h:inputText>

с

@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {     
    if (!"TEST".equals(component.getAttributes().get("radio"))) {
        return;
    }

    // Perform actual validation here.
}

Вы также можете использовать OmniFaces <o:validator> вместо.Он расширяет стандарт <f:validator> с оценкой EL в атрибутах на основе запроса.

<h:inputText>
    <o:validator validatorId="myValidator" disabled="#{bean.checkedSelectOneRadioValue == 'TEST'}" />
</h:inputText>

См. Также пример демонстрации и исходный код , из которого выложен фрагмент релевантности:

@Override
public void apply(FaceletContext context, UIComponent parent) throws IOException {
    if (!ComponentHandler.isNew(parent)) {
        return;
    }

    final javax.faces.validator.Validator validator = createValidator(context);
    final RenderTimeAttributes attributes = collectRenderTimeAttributes(context, validator);
    final ValueExpression disabled = getValueExpression(context, "disabled", Boolean.class);
    ((EditableValueHolder) parent).addValidator(new javax.faces.validator.Validator() {

        @Override
        public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
            if (disabled == null || Boolean.FALSE.equals(disabled.getValue(context.getELContext()))) {
                attributes.invokeSetters(context.getELContext(), validator);
                validator.validate(context, component, value);
            }
        }
    });
}
0 голосов
/ 28 марта 2012

С JSF 2.0 вы можете использовать f:ajax для частичной отправки. Добавьте этот тег к вашему h:selectOneRadio:

<h:selectOneRadio value="#{myBean.checkedSelectOneRadioValue}">
    <f:ajax render="idOfInputText"/>
    <f:selectItems value="#{myBean.valuesForSelectOneRadio}" />
</h:selectOneRadio>
...
<h:inputText id="idOfInputText">
    <f:validator validatorId="myValidator" 
                 disabled="#{myBean.checkedSelectOneRadioValue eq 'TEST'}" />
</h:inputText>

Замените содержимое атрибута render реальным идентификатором поля ввода с помощью валидатора. Это предполагает, что selectOneRadio и inputText находятся внутри одного NamingContainer.

0 голосов
/ 28 марта 2012

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

Сначала это должно быть

disabled="#{myBean.checkedSelectOneRadioValue == 'TEST'}

или

disabled="#{myBean.checkedSelectOneRadioValue eq 'TEST'}

Дополнительно, по крайней мере, в ICEFaces (и MyFaces также должна иметь эту функцию), вы можете использовать:

<h:selectOneRadio value="#{myBean.checkedSelectOneRadioValue}" partialSubmit="true"> <f:selectItems value="#{myBean.valuesForSelectOneRadio}" /> </h:selectOneRadio>

Это должно вызвать ajax-запрос после изменения значения selectoneradio, и проверка с отключенным валидатором должна иметь возможность получить его от bean-компонента.

Если это не сработает, в MyFaces может быть автоматическая отправка или подобное ...

...