File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes JSF and the fly likes Problem with f:validator & f:attribute - EL does not evalute in f:attribute Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of EJB 3 in Action this week in the EJB and other Java EE Technologies forum!
JavaRanch » Java Forums » Java » JSF
Bookmark "Problem with f:validator & f:attribute - EL does not evalute in f:attribute " Watch "Problem with f:validator & f:attribute - EL does not evalute in f:attribute " New topic
Author

Problem with f:validator & f:attribute - EL does not evalute in f:attribute

ved gunjan
Ranch Hand

Joined: May 17, 2003
Posts: 86
Hi Experts,
I'm to using custom validator in my application.
<h:dataTable value="#{requirementBean.questionList}"
var="questions"
id="questionTable"
columnClasses="none,tableRowOdd"
rowClasses="tableRowEven,tableRowOdd"
cellpadding="1"
cellspacing="1"
width="100%">

...................
.......................
<h:inputText rendered="#{questions.displayType eq 'TextBox'}" id="inputTextid" value="#{questions.defaultAnswerString}">
<f:validator validatorId="dataTypeValidatorId" />
<f:attribute name="dataType" value="#{questions.dataType}"/></h:inputText>


"dataTypeValidatorId" is a custom validator which im using in my application.
The problem is that the f:attribute tag is not working in case of EL expressions, the way i have used above ( <f:attribute name="dataType" value="#{questions.dataType}"/>).
I get value as null in my validator code.
Here's my validator code.

public void validate(FacesContext arg0, UIComponent component, Object value) throws ValidatorException {
Map map = component.getAttributes();
String str = (String) map.get("dataType");
if(str != null && "String".equalsIgnoreCase("str")){
.........
..................
}


But when i put static value in the value attribute of the f:attribute tag , every thing works fine...some thing like this
<f:attribute name="dataType" value="Integer"/>, then i get proper vlaue in the validator code.

Even though the specifications says that f:attribute can take static values as well as EL expressions.

Any ideas? Whats the reason and how to solve it.? It's very important please provide me with some help.

Thanks.
Ved
Bauke Scholtz
Ranch Hand

Joined: Oct 08, 2006
Posts: 2458
Nasty stuff .. I've debugged it and it turns out that the f:attribute is called only once per initialisation. And always the first value is retrieved and stored. So all f:attribute elements contains the same value.

I suggest you to use the UIViewRoot in the datatypeValidator class, retrieve the parent datatable from it and finally get the row object from it. Quick example:


[ November 05, 2006: Message edited by: Bauke Scholtz ]
Abel Dofino
Greenhorn

Joined: Sep 03, 2008
Posts: 1
Hi.

Because of lack of examples a lot of people got into the same issue: they add attribute to UIComponent with some EL expression but in the Validator they couldn't get the value by callng component.getAttributes().get("attributeName"). Last one always returned null. But for some reason if the add attribute with plain text value it worked fine.

Today I decided to digg into it and after re-reading specification for JSF 1.2 I got the answer: there are 2 places for attribute values! Here is the quote of the description for section "9.4.2 <f:attribute> (page 9-17)":

"If the associated component already has a component attribute with that name, take no action.
Otherwise, call the isLiteralText() method on the argument value. If it returns
true, store the value in the component�s attribute Map under the name derived above.
If it returns false, store the ValueExpression in the component�s ValueExpression
Map under the name derived above."

In other words we looked for value in wrong place. If value of f:attribute is EL expression we should use component.getValueExpression("attributeName") to get ValueExpression instance and call getValue(elContext) to get theValue.

Here is 2 examples.

Example 1. Value of attribute is plain text.

Page code:

<h:inputText id="userName" value="#{mybean.userName}">
<f:attribute name="payCode" value="regular"/>
<f:validator id="userNameValidator"/>
</h:inputText>
...
faces-context.xml

<validator>
<validator-id>userNameValidator</validator-id>
<validator-class>your.package.UserNameValidator</validator-class>
</validator>
...
Validator code

public class UserNameValidator implements Validator {

public void validate(FacesContext context, UIComponent component, Object value) {
String paycode = component.getAttributes().get("payCode");
...

}

Example 2. Value of attribute is EL (expression language).

Page code:

<h:inputText id="userName" value="#{mybean.userName}">
<f:attribute name="payCode" value="#{otherBean.payCode}"/>
<f:validator id="userNameValidator"/>
</h:inputText>
...
faces-context.xml

<validator>
<validator-id>userNameValidator</validator-id>
<validator-class>your.package.UserNameValidator</validator-class>
</validator>
...
<managed-bean>
<description>Some other bean we get value from. Scope "request" just for example. It could be session or application too or even no scope</description>
<managed-bean-name>otherBean</managed-bean-name>
<managed-bean-class>your.package.OtherBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<managed-bean>

OtherBean code:

public class OtherBean {

private PayCode payCode;
...

public PayCode getPayCode() {
return this.payCode;
}

public void setPayCode(PayCode payCode) {
this.payCode = payCode;
}
}


...
Validator code

public class UserNameValidator implements Validator {

public void validate(FacesContext context, UIComponent component, Object value) {
ValueExpression ve = component.getValueExpression().get("payCode");
PayCode paycode = (ve != null) ? (PayCode)ve.getValue(context.getELContext()) : null;

...

}



I beleive that you could extend my examples for JSF Converters, ValueChangeListeners and ActionListeners. Now you know where look for attribute value!
[ September 03, 2008: Message edited by: Viacheslav Garmash ]
Hala AA
Greenhorn

Joined: Feb 13, 2008
Posts: 6
Greetings,

I have the same problem with the <f:attribute> and i need to submit an EL value inside a commandButton, because i tried <f:param> and it doesn't work with the commandButton.
Then i found your solution but unfortunately the function getValueExpression is undefined for UIComponent , so i think i missed something in your solution can you please explain how to get the expression value of the attribute using only the event object inside the actionlistener of a commandButton?

Thanks in advance
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Problem with f:validator & f:attribute - EL does not evalute in f:attribute
 
Similar Threads
unalbe to pass attribute values to validator
problem with findComponent()
Passing parameters/ attributes to a custom validator
retrieve UIComponent value in custom validator with EL expressions
JSF validation not validating