Why is InputHidden readonly attribute not in JSF documentation? - jsf

I have recently encountered a case where I wanted to set the index value from ui:repeat varStatus="v" using <h:inputHidden="#{v.index}/>. If you try this and execute the component using AJAX you will get an exception that the property is not writeable. While looking around I found that inputHidden supports a readonly="true" attribute that does just that making the error go away.
Is there a reason why this is not in documentation? (i.e. special, passthrough, other)
Is it safe to use?

After doing some digging Core JavaServer Faces 3e had this to say :
The h:inputHidden tag has the same attributes as the other input tags, except that it does not support the standard HTML and DHTML tags
So, the reason why readonly is not in the docs for inputHidden and also why it's not being rendered in your HTML is because inputHidden does not support it. This was also confirmed by Netbeans when I tried to add readonly as an attribute to inputHidden'(red squiggly lines with an error message). I was able to get that exception when I submitted a form with no setter defined for my bean property that was placed in inputHidden. Since inputHidden calls the setter when a form is submitted (for my case) and since none is defined in my code, it will of course throw that exception, namely:
javax.el.PropertyNotWritableException: /index.xhtml #14,56 value="#{bean.x}": The class 'Bean' does not have a writable property 'x'.
As for why it works when you do that I have no idea. Since you're worried about safety, I would suggest you do as BalusC says and simply use <input type="hidden"> or you define a setter for that property. Don't use it like that.

So long time since this question started, however just FYI, this works:
<h:inputHidden id="compId" readonly="#{true}" value="#{myBean.attribute}" />

Related

Property 'addListener' not found on type com.chat.viewbeans.ClientBean [duplicate]

While deploying GAE + primefaces application, I got following error:
com.sun.faces.application.view.FaceletViewHandlingStrategy handleRenderException: Error Rendering View[/CreateEmployee.xhtml]
javax.el.ELException: /CreateEmployee.xhtml: Could not find property saveEmployee in class com.fetchinglife.domain.data.dao.EmployeeRepositoryImpl
at com.sun.faces.facelets.compiler.AttributeInstruction.write(AttributeInstruction.java:94)
at com.sun.faces.facelets.compiler.UIInstructions.encodeBegin(UIInstructions.java:82)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:302)
at com.sun.faces.renderkit.html_basic.GridRenderer.renderRow(GridRenderer.java:185)
Even saveEmployee is already in EmployeeRepositoryImpl class. How is this caused and how can I solve it? Are there any annotations which I have to put extra?
Let's rephrase the exception in a general format in order to better understand the cause:
javax.el.ELException: Could not find property doSomething in class com.example.Bean
This exception is literally trying to tell you that the Bean class doesn't have the following method:
public SomeObject getDoSomething() {
return someObject;
}
(where SomeObject is the type of the doSomething property)
There are several causes for this.
Action method expression is incorrectly interpreted as property value expression
Given the fact that the property name is in your case actually a combination of a verb and noun, a resonable cause is you incorrectly bound an action method to an attribute of some JSF component which actually takes a value expression, not a method expression. E.g. when you accidentally do
<h:commandButton value="#{bean.doSomething}">Save</h:commandButton>
or even
<h:button value="Save" outcome="#{bean.doSomething}" />
instead of
<h:commandButton value="Save" action="#{bean.doSomething}" />
The latter would then expect the following method, which you probably actually have:
public String doSomething() {
// ...
return "nextpage";
}
(which can also be declared to return void by the way)
Component is not resolved at all
Another probable cause is that the component is not interpreted as a real component at all, but as "plain text". In other words, when you remove the action attribute and then try to open the JSF page in browser, it'll now load fine, but you will see the whole component unparsed in the generated HTML output (which you can see via rightclick, View Source in browser).
This can have several causes:
The XML namespace of the component is wrong or missing. E.g. in case of PrimeFaces you accidentally used the old PrimeFaces 2.x URI while you're actually using PrimeFaces 3+.
<html ... xmlns:p="http://primefaces.prime.com.tr/ui">
The XML namespace URI contains a typo.
<html ... xmlns:p="http://primefaecs.org/ui">
The XML namespace prefix does not match.
<html ... xmlns:pf="http://primefaces.org/ui">
The XML namespace is totally missing.
<html ...>
The component library is not installed at all. In other words, the JARs containing component library's tag definitions is missing in webapp's /WEB-INF/lib folder.
Either way, all <p:xxx> tag won't be parsed and be considered as template text. But, all EL expressions will still be evaluated (as if you're using <p>#{bean.text}</p>), and they will all behave as ValueExpressions instead of MethodExpressions.
An easy way to recognize the root cause is looking at stack trace. If you're seeing com.sun.faces.facelets.compiler.AttributeInstruction in the stack trace, then it means that the component is interpreted as "plain text". Otherwise you would have seen e.g. org.primefaces.component.commandbutton.CommandButton in the specific case of <p:commandButton>.

primefaces update attribute not working on modal dialog opened from modal dialog [duplicate]

I have a question about the idea behind the fact, that only UIForm got the attribute prependId. Why is the attribute not specified in the NamingContainer interface? You will now probably say that's because of backward compability but I would preferre breaking the compability and let users which implement that interface, also implement methods for the prependId thing.
The main problem from my perspective about the prependId in the UIForm component is, that it will break findComponent()
I would expect that if I use prependId, then the NamingContainer behaviour would change, not only related to rendering but also when wanting to search for components in the component tree.
Here a simple example:
<h:form id="test" prependId="false">
<h:panelGroup id="group"/>
</h:form>
Now when i want to get the panelGroup component I would expect to pass the string "group" to the method findComponent(), but it won't find anything, I have to use "test:group" instead.
The concrete problem with that is, when using ajax with prependId="false". The ajax tag expects in the attributes update and process, that the values care of naming containers. It's a bit strange that when I use prependId="false" that I have to specify the full id or path, but okay.
<h:form id="test" prependId="false">
<h:panelGroup id="group"/>
</h:form>
<h:form id="test1" prependId="false">
<h:commandButton value="go">
<f:ajax render="test:group"/>
</h:commandButton>
</h:form>
Well this code will render without problems but it won't update the panelGroup because it cannot find it. The PartialViewContext will contain only the id "group" as element of the renderIds. I don't know if this is expected, probably it is but I don't know the code. Now we come to the point where the method findComponent() can not find the component because the expression passed as parameter is "group" where the method would expect "test:group" to find the component.
One solution is to write your own findComponent() which is the way I chose to deal with this problem. In this method i handle a component which is a NamingContainer and has the property prependId set to false like a normal UIComponent. I will have to do that for every UIComponent which offers a prependId attribute and that is bad. Reflection will help to get around the static definition of types but it's still not a really clean solution.
The other way would be introducing the prependId attribute in the NamingContainer interface and change the behaviour of findComponent() to work like described above.
The last proposed solution would be changing the behaviour of the ajax tag to pass the whole id, but this would only solve the ajax issue and not the programmatic issues behind the findComponent() implementation.
What do you think about that and why the hell is it implemented like that? I can't be the first having this problem, but I wasn't able to find related topics?!
Indeed, UIComponent#findComponent() as done by <f:ajax render> fails when using <h:form prependId="false">. This problem is known and is a "Won't fix": JSF spec issue 573.
In my humble opinion, they should never have added the prependId attribute to the UIForm during the JSF 1.2 ages. It was merely done to keep j_security_check users happy who would like to use a JSF form with JSF input components for that (j_security_check requires exact input field names j_username and j_password which couldn't be modified by configuration). But they didn't exactly realize that during JSF 1.2 another improvement was introduced which enables you to just keep using <form> for that instead of sticking to <h:form>. And then CSS/jQuery purists start abusing prependId="false" to avoid escaping the separator character : in their poorly chosen CSS selectors.
Just don't use prependId="false", ever.
For j_security_check, just use <form> or the new Servlet 3.0 HttpServletRequest#login(). See also Performing user authentication in Java EE / JSF using j_security_check.
For CSS selectors, in case you absolutely need an ID selector (and thus not a more reusable class selector), simply wrap the component of interest in a plain HTML <div> or <span>.
See also:
How to select JSF components using jQuery?
How to use JSF generated HTML element ID with colon ":" in CSS selectors?
By default, JSF generates unusable ids, which are incompatible with css part of web standards

UIComponent#getValue() obtained via binding is not available in validator of another component

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.
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.

javax.el.ELException: Could not find property actionMethod in class com.example.Bean

While deploying GAE + primefaces application, I got following error:
com.sun.faces.application.view.FaceletViewHandlingStrategy handleRenderException: Error Rendering View[/CreateEmployee.xhtml]
javax.el.ELException: /CreateEmployee.xhtml: Could not find property saveEmployee in class com.fetchinglife.domain.data.dao.EmployeeRepositoryImpl
at com.sun.faces.facelets.compiler.AttributeInstruction.write(AttributeInstruction.java:94)
at com.sun.faces.facelets.compiler.UIInstructions.encodeBegin(UIInstructions.java:82)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:302)
at com.sun.faces.renderkit.html_basic.GridRenderer.renderRow(GridRenderer.java:185)
Even saveEmployee is already in EmployeeRepositoryImpl class. How is this caused and how can I solve it? Are there any annotations which I have to put extra?
Let's rephrase the exception in a general format in order to better understand the cause:
javax.el.ELException: Could not find property doSomething in class com.example.Bean
This exception is literally trying to tell you that the Bean class doesn't have the following method:
public SomeObject getDoSomething() {
return someObject;
}
(where SomeObject is the type of the doSomething property)
There are several causes for this.
Action method expression is incorrectly interpreted as property value expression
Given the fact that the property name is in your case actually a combination of a verb and noun, a resonable cause is you incorrectly bound an action method to an attribute of some JSF component which actually takes a value expression, not a method expression. E.g. when you accidentally do
<h:commandButton value="#{bean.doSomething}">Save</h:commandButton>
or even
<h:button value="Save" outcome="#{bean.doSomething}" />
instead of
<h:commandButton value="Save" action="#{bean.doSomething}" />
The latter would then expect the following method, which you probably actually have:
public String doSomething() {
// ...
return "nextpage";
}
(which can also be declared to return void by the way)
Component is not resolved at all
Another probable cause is that the component is not interpreted as a real component at all, but as "plain text". In other words, when you remove the action attribute and then try to open the JSF page in browser, it'll now load fine, but you will see the whole component unparsed in the generated HTML output (which you can see via rightclick, View Source in browser).
This can have several causes:
The XML namespace of the component is wrong or missing. E.g. in case of PrimeFaces you accidentally used the old PrimeFaces 2.x URI while you're actually using PrimeFaces 3+.
<html ... xmlns:p="http://primefaces.prime.com.tr/ui">
The XML namespace URI contains a typo.
<html ... xmlns:p="http://primefaecs.org/ui">
The XML namespace prefix does not match.
<html ... xmlns:pf="http://primefaces.org/ui">
The XML namespace is totally missing.
<html ...>
The component library is not installed at all. In other words, the JARs containing component library's tag definitions is missing in webapp's /WEB-INF/lib folder.
Either way, all <p:xxx> tag won't be parsed and be considered as template text. But, all EL expressions will still be evaluated (as if you're using <p>#{bean.text}</p>), and they will all behave as ValueExpressions instead of MethodExpressions.
An easy way to recognize the root cause is looking at stack trace. If you're seeing com.sun.faces.facelets.compiler.AttributeInstruction in the stack trace, then it means that the component is interpreted as "plain text". Otherwise you would have seen e.g. org.primefaces.component.commandbutton.CommandButton in the specific case of <p:commandButton>.

JSF 2.0 Validator Wrapping

I ran into a problem when I tried to apply a custom validator to an input field:
I want to use a custom validator that is generated by a bean and bound to a f:validator tag:
<f:validator binding="#{bean.myValidator}">
The corresponding bean method looks like this:
public Validator getMyValidator(){
return new Validator(){...};
}
If I'm using the tag inside an input tag like this:
<h:input value="...">
<f:validator binding="#{bean.myValidator}" />
</h:input>
then everything works as expected.
However, if I'm using the tags the other way around like this:
<f:validator binding="#{bean.myValidator}">
<h:input value="...">
</f:validator>
then I get a ServletException ("validatorID is null").
What is the reason for this Exception?
Also, I don't understand the corresponding f:validator tag spec:
If this element is nested within a UIComponent tag that has other UIComponent children, the validator will be automatically added to all the child components as well as this one.
I guess my f:validator tag is nested within f:view, correct?
What does "to all the child components" mean? Whose child components?
What is the reason for this Exception?
I'm not sure. Both Mojarra 2.1.3 and MyFaces 2.1.1 exposes the same problem. It works when the validator is a standalone #FacesValidator("myValidator") class which is been specified by <f:validator validatorId="myValidator">. The spec nor the vdl describes this behaviour. You might want to post an issue report to the JSF spec guys to clarify this more in the spec or vdl.
Also, I don't understand the corresponding f:validator tag spec:
If this element is nested within a UIComponent tag that has other UIComponent children, the validator will be automatically added to all the child components as well as this one.
I guess my f:validator tag is nested within f:view, correct? What does "to all the child components" mean? Whose child components?
It's just a terrible wording of whatever you're trying to achieve is just supported: wrapping a common validator over a set of components. You might want to ask the JSF spec guys to clarify this more as well.

Resources