2

I'm trying to figure out why an f:attribute tag's value isn't passed when attached to h:inputSecret tag. I'm quite new to jsf, but as far as I know attributes can be attached to any kind of component. Here is the code:

    <h:inputSecret id="passw" value="#{advertAdder.userPass}" 
                   required="true" validator="#{advertAdder.validatePasswords}">
        <f:attribute name="confirmedPass" value="#{advertAdder.passConfirmator.value}"/>
    </h:inputSecret>

    <h:inputSecret id="passwConfirm" required="true" 
                   binding="#{advertAdder.passConfirmator}"/>

and the method that wants to acces this attribute:

public void validatePasswords(FacesContext context, UIComponent component, Object value)
    {
        if (!value.equals(component.getAttributes().get("confirmedPass")))
        {
            FacesMessage mess = new FacesMessage("Password and it's confirmation are not the same!");
            context.addMessage(component.getClientId(context), mess);
            ((UIInput) component).setValid(false);
        }

    }

In above code component.getAttributes() always returns map with only two attributes: javax.faces.component.VIEW_LOCATION_KEY and com.sun.faces.facelets.MARK_ID.

I've added attribute tag to a h:commandButton to check it, and then everything was fine. Am I missing something or it's not possible to add an attribute to non-action tag? I'm using Mojarra 2.0.2 and Glassfish 3.0.1.

Thanks in advance.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
GrzesiekC
  • 37
  • 6

1 Answers1

4

Input components are processed in the order as they appear in the component tree. The UIInput#getValue() is only available when the component is already been processed. Otherwise you need to use UIInput#getSubmittedValue() instead.

<f:attribute name="confirmedPass" value="#{advertAdder.passConfirmator.submittedValue}"/>

Note that this gives you the unconverted and unvalidated value back. It would make somewhat more sense to put the validator on the confirm password field instead and pass the value of the first password field along. See also JSF Validator compare to Strings for Equality and JSF doesn't support cross-field validation, is there a workaround?

Alternatively, you can also try out the OmniFaces <o:validateEqual> component. You can find a concrete example in this article.


Unrelated to the concrete problem, it's unnecessary to bind the component to the bean this way. Replace all occurrences of #{advertAdder.passConfirmator} by #{passConfirmator}. Keep the controller free of properties which are never internally used.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thx for quick answer. I used second solution (I also tried the first one and it also worked). But there are two things that confuse me a bit. – GrzesiekC Mar 15 '12 at 20:45
  • (Sorry for multiposting I couldn't edit the prev. comment) 1. In both cases component.getAttributes() returns map with only two keys and none of them is "confirmedPass". Somehow component.getAttributes().get("confirmedPass") returns expected value. I assume that it's obtained from the value under MARK_ID key, but how is that working? 2. What do you mean by "Replace all occurrences of (...)"? I tried just replacing, making it managedProperty or even managedBean but then in each case the value of the component's attribute was null. – GrzesiekC Mar 15 '12 at 21:02
  • 1) It's a dynamic map. The value expressions (`#{}`) are not visible by keys. 2) Just exactly as I said, remove `advertAdder` part before `passConfirmator` in the `#{}`s in the view side and then remove the `private SomeUIComponent passConfirmator` property and its getter/setter from your backing bean. They are completely unnecessary. This is also outlined in the example behind the "See also" link. – BalusC Mar 15 '12 at 21:06
  • Well, I did it before, and now I did it again, just to be sure. When I remove `advertAdder` part and the setter and getter methods in my backing bean, the `component.getAttributes().get("confirmedPass")` returns null. I suppose I'm missing smth obvious or my majorra doesn't support that syntax. I don't know if the second one is possible. – GrzesiekC Mar 15 '12 at 21:45
  • Check the example in the "See also" link to see if you get everything right. – BalusC Mar 15 '12 at 21:59