I am using PrimeFaces and JSF - I need to be able to set a component on the page as mandatory in response to an AJAX event. Is the best way to accomplish this using the following code or is there also a way to accomplish it using JQuery ?
Thanks
UIInput componentToChange = (UIInput) facesContext.getViewRoot().findComponent("ComponentId");
componentToChange.setRequired(true);
Thanks
Just set the component's required attribute with the desired EL expression.
E.g.
<h:inputText ... required="#{bean.required}" />
There are even EL ways without needing an additional bean property, but it's impossible to propose one based on the sparse information provided so far.
Use findComponent() with care. Think twice if it really can't be done just in the view (XHTML) side.
Related
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
I am new to JSF and getting very confused doing something trivial. I am making up this example here to elaborate what I am want to do:
I have a xhtml fragment, say, stockQuoteFragment.xhtml, which is backed by a ManagedBean, say, StockQuoteService.java. StockQuoteService.java has property stockID and a method getStockQuote() which has all the logic to get the stockQuote for the value set on stockID property. stockQuoteFragment.xhtml displays #stockQuoteService.stockQuote.
Now I have another page Home.xhtml page with backing bean HomeBackingBean.java with a method getUserFavoriteStockID(). I want to include content of stockQuoteFragment.xhtml in Home.xhtml passing in the value of #homeBackingBean.userFavoriteStockID to StockQuoteService.setStockID().
I am not sure how to do this in JSF/Facelets. With simple JSPs I could do this easily with a JSP include and include parameters
No.
...According to TLD or attribute directive in tag file, attribute var does not accept any expressions.
I have just tried it.
But if you use pure XML based JSF with tags, you can easily use <ui:param> as discussed here. I use JSF in JSP and for me there is no help (<c:set> is mostly useless).
Can I just do this in Home.xhtml before I ui:include stockQuoteFragment.xhtml into it:
<c:set var="#{StockQuoteService.stockID}" value="#homeBackingBean.userFavoriteStockID"/>
will that work?
Simple question:
Is there any way of rendering a html <button>-element using JSF or any other framework (RichFaces, Tomahawk etc.)? Or would I have resort to writing a custom component for this?
No, there isn't. Since a <button> is usually only used in GET requests, you can also just put it plain vanilla in the JSF template. You don't need to bind any action to a JSF managed bean anyway.
In JSF 2.0, there's by the way the <h:button> which renders a GET button and offers the option to include view parameters and/or to perform implicit navigation. Both features aren't available in JSF 1.2, so there's not really a point of having similar component in JSF 1.2 anyway.
On the other hand, if you actually intend to use a <button> to invoke a POST managed bean action method, then you should really be using a <h:commandButton> instead. If you're having a specific problem with it for which you thought that using <button> was the solution, then you'd need to reframe your question to elaborate in more detail about that specific problem so that we can answer how to achieve the same with <h:commandButton>.
I searched everywhere but could not find a solution to this. I am trying to used
required=yes to validate whether a value is present or not. I am using it inside inputtext.
The problem is it does not work inside a datatable. If I put the text box outside the datatable it works. I am using JSF 1.7 so I don't have the validateRequired tag from JSF 2.0.
I even used a validator class but it is still not working. Does anyone know why does required=yes or validator='validationClass' inside a inputtext inside a datatable is not working.
I appreciate the help.
Thanks.
First of all, the proper attribute values of the required attribute are the boolean values true or false, not a string value of Yes. It's an attribute which accepts a boolean expression.
The following are proper usage examples:
<h:inputText required="true" />
<h:inputText required="#{bean.booleanValue}" />
<h:inputText required="#{bean.stringValue == 'Yes'}" />
As to the problem that it doesn't work inside a <h:dataTable>, that can happen when the datamodel is not been preserved properly (the datamodel is whatever the table retrieves in its value attribute). That can in turn happen when the managed bean is request scoped and doesn't prepare the datamodel during its (post)construction which causes that the datamodel is null or empty while JSF is about to gather, convert and validate the submitted values.
You need to ensure that the datamodel is exactly the same during the apply request values phase of the form submit request as it was during the render response phase of the initial request to display the form with the table. An easy quick test is to put the bean in the session scope. If that fixes the problem, then you definitely need to rewrite the datamodel preserving logic. You could also use Tomahawk's <t:saveState> or <t:dataTable preserveDataModel="true"> to store the datamodel in the view scope (like as JSF2's new view scope is doing).
Finally, JSF 1.7 doesn't exist. Perhaps you mean JSF 1.2?
What is or could be a best practice?
Using standard JSF components and combine them by PrimeFaces components when needed (for example when DHTML or AJAX components are needed)
Forget all JSF Components and try to use all PrimeFaces components as much as possible
Please explain it and tell me about your experiences.
Thanks in advance...
PrimeFaces is your AJAX framework, so if you need to send ajaxical request, then use PrimeFaces components.
Even though, you dont need to send ajax request, but you can still use PF component, if u need to provide a consistency look for your web page. For example, h:commandButton and p:commandButton. Use p:commandButton if u need to send ajax request, but u can also do this
<p:commandButton ajax="false" action="Your Action here"/>
This will provide the same result as:
<h:commandButton action="Your Action here"/>
but this way, you can provide the same consistent look for your button throughout the page.
PrimeFaces does not have replacements for h:panelGrid, h:panelGroup, h:inputText, h:outputText ...
Depends on the sole functional requirement. If you're already using PrimeFaces and whatever you want to achieve can better/easier be achieved using a PrimeFaces component, use it.
Option 1 comes close, but option 2 goes overboard. PrimeFaces for example doesn't have a <p:form>, <p:panelGroup>, <p:outputText> or something.
With Primefaces it's very easy to get a consistent look for your application since it comes with Themeroller CSS framework. And you can easily switch designs. Although it is not difficult to let plain jsf components look like primefaces components if you apply the right css classes.
I think primefaces is a great component library. However some components are still buggy (e.g. date picker). So if you get some unexpected behavior with a primefaces component, it is alway good to have a jsf fallback (or an alternative from another component library or from jquery).
I have no experience with mixing different component libraries. Would be interesting to know, how they interact. But that would be subject of another question ...