JSF2 CommandButton Action request params - jsf-2

<h:commandButton value="Add Order" action="#{orderBasket.addItems(param['orderItemId'])}"/>
I can't get the above to work...when you click on the button the param seems to get set to null. Is there a way around this?
Is there another way of passing the URL params into the action method? I'm using Spring EL resolver which limits my ability to pass in the parameters into beans as I'm not using faces-config.

First, I think you could use JSF better, a lot of problems would be much simpler. It looks that you are using JSF as a request/response framework, like Struts. JSF is an object oriented component framework, you should use it this way to get the best of it.
I'll try to solve your problem, but I'm missing some information on what you are doing.
If you have a list of books that you can order, let's say they are displayed in a datatable (you could use ui:repeat instead) :
<h:dataTable value="#{bookController.books}" var="book">
<h:column>
<h:outputText value="#{book.title}" />
</h:column>
<h:column>
<h:commandButton value="Add Order" action="#{orderBasket.addItems(book)}" />
</h:column>
</h:dataTable>
In orderBasket backing bean, you simply take a Book (or whatever) as parameter. You don't need to handle the request/response cycle, certainly not in your views.
You can use f:ajax tag if you need to display that in your shopping cart immediately.
Let me know if you need more explanation (backing beans source or else).

Related

Any way to bypass form validation on p:commandButton without using o:ignoreValidationFailed or immediate=true

I create page forms with a parameter that tells them where to return when done. The backing bean is #ReqeuestScoped and includes this:
<f:metadata>
<f:viewParam name="return" value="#{createGroup.paramReturn}" />
</f:metadata>
The form has fields with validators, so the cancel button has to skip validation. So, the cancel button looks like this:
<p:commandButton value="Cancel"
action="#{createGroup.doCancel}"
immediate="true"
/>
The purpose of the doCancel() method is to go into Flash scope and return the value set with setParamReturn method.
The problem is with the immediate="true" attribute is that the Flash storage that has the paramReturn variable in it is no longer available. If someone could tell me how to fix that this would be my preferred solution.
Of course without the immediate="true" attribute the action is never invoked because the form cannot pass validation. Another solution would be to cause validation to be ignored some other way.
I have looked at the OmniFaces <o:ignoreValidationFailed> tag and it seems to do what I want, but I don't want to import a whole library for just this tag. However, that is what I will do if there is no other simple way to fix this.

How to hide components by selecting a new value on h:selectOneMenu?

I have a page with a h:selectOneMenu, and I want to hide a dataTable when I choose a new value on the h:selectOneMenu while some bean attribute values update. I'm trying diferent things, and I'm able to hide the dataTable by reloading the page. I have tried this using some JavaScript code, on onsomething attributes. In that case, those bean attribute values disapear although I use t:saveState (and I also need the view scope for the bean).
Here is a little example to clarify this:
<h:selectOneMenu id="list" value="#{Bean.id}">
<f:selectItems value="#{Bean.List}" var="element" itemLabel="#{element.name}" itemValue="#{element.id}"/>
<t:saveState value="#{Bean.id}"/>
<f:ajax listener="#{Bean.populateBean}" render=":form:period" event="change"/>
</h:selectOneMenu>
<h:selectOneMenu id="period" value="#{Bean.period}">
<f:selectItems value="#{Bean.listaPeriod}" var="period" itemLabel="#{period[1]}" itemValue="#{period[0]}"/>
<t:saveState value="#{Bean.period}"/>
</h:selectOneMenu>
<h:commandButton id="search" action="#{Bean.doSearch}"></h:commandButton>
<t:dataTable id="data" value="#{Bean.configList}" rendered="#{Bean.search}"
<t:column>
...
</t:dataTable>
And Bean.doSearch changes Bean.search to true. How can I hide the dataTable when I choose a new value on h:selectOneMenu id="list"?
EDIT:
In short, the search button renders the table, and I would want to hide that table when I just choose a new value on the "list" dropdown without reloading the page. Now, the <f:ajax> is used only to rerender the "period" dropdown value.
Thanks in advance!
Your question is hardly understandable, but if you want to kick the datatable out of your view on ajax request triggered by your dropdown, you need to enclose it in a component that's always present in the view so that HSF would know what to rerender when ajax call successfully finishes:
<h:panelGroup id="rerender">
<t:dataTable rendered="#{bean.condition}" ...>
....
</t:dataTable>
<h:panelGroup>
Of course, to get it working you should specify id of the component to be rerendered:
<h:selectOneMenu ...>
...
<f:ajax listener="#{bean.populate}" render="rerender" />
</h:selectOneMenu>
Note that if both dropdown and datatable components belong to the same form, it's not necessary to specify absolute id of the latter's parent. Also note that specifying event is redundant, as it already defaults to the right one. Finally, as you're on JSF 2.x, using save state is not necessary, just bind the values of your form data to a view scoped bean.
The last thing to note is the fact that you fail to conform to the Java Naming Conventions, the thing you should correct as soon as possible.

Dynamic columns with richfaces 4

I need dynamic number of columns. Richfaces supplies it with <rich:columns> in richfaces 3.3.3-final but for Richfaces 4 they seem to recommend <c:forEach>.
c:forEach
I can't get it to work properly.Since I can't depend on the var from the datatable I can't figure out how to feed <c:forEach> with the correct list of columns. (Each row has their own values but headers are the same)
Basically the data I want to display is a list with rows of x size, each row has a list of column values with y size. But how can have <c:forEach> tell the backing bean what row it's at so I can feed the correct columns?
ui/a4j:repeat
I dont want to reinvent the wheel because I need frozen columns and many other features. Creating the table html this way and use jQuery for other features have been considered. However this would be hopeless to maintain and to much work.
I also looked at constructing it from the backing bean creating children dynamically but I don't like that at all. This would have to be the last resort.
Using: Tomcat 7, servlet 3.0, JSF 2.1x - Mojarra, Richfaces 4.x
Update
Okay so I'm getting some results finally. However my headers don't show. The values show perfectly but not the headers. Some problem doing them with iteration or something perhaps?
<rich:dataTable value="#{controller.rows}"
var="row">
<c:forEach items="#{controller.columns}" var="column">
<rd:column id="name" width="250">
<f:facet name="header">
<h:outputText value="#{row.myArrayList[column].header}" />
</f:facet>
<h:inputText value="#{row.myArrayList[column].value}" disabled="#{row.myArrayList[column].open}"/>
</rd:column>
</c:forEach>
</rich:dataTable>
The <c:forEach> is indeed best what you can get. The <ui/a4j:repeat> won't work as that runs during view render time while the UIData component really needs UIColumn children, not UIRepeat children.
In order to get the <c:forEach> to work, you need to supply it a list/map of all property names (and in case of a map maybe also header labels). Here's a concrete kickoff example assuming that Item has properties id, name and value and that #{bean.itemPropertyNames} returns a List<String> with exactly those property names.
<rich:dataTable value="#{bean.items}" var="item">
<c:forEach items="#{bean.itemPropertyNames}" var="itemPropertyName">
<rich:column>
#{item[itemPropertyName]}
</rich:column>
</c:forEach>
</rich:dataTable>
If you need to show column headers as well, then best is to have a Map<String, String> where the key represents the property name and the value represents the header value.
<rich:dataTable value="#{bean.items}" var="item">
<c:forEach items="#{bean.itemProperties}" var="itemProperty">
<rich:column>
<f:facet name="header">#{itemProperty.value}</f:facet>
#{item[itemProperty.key]}
</rich:column>
</c:forEach>
</rich:dataTable>
Either way, the only disadvantage is that the #{bean} of <c:forEach items> can in this construct not be a view scoped one. It would be recreated on every request, unless you turn off partial state saving. It needs to be a request scoped one (or session or application). Note that it does not necessarily need to be the same bean as the one in <rich:dataTable value>.
See also:
Dynamically generate h:column based on list of hashmaps

Keep get parameters when submitting a form

I'm trying to do something simple in JSF but I can't get it working for some reason.
What I want is to post information with a form from a page reached with a GET parameter and keep this GET parameter whenever I submit the form.
<f:metadata>
<f:viewParam name="someId" value="#{someController.something}" converter="#{someConverter}" />
</f:metadata>
This is the way I choose to bind the GET parameter, this is working fine when I'm doing the GET request.
On the very same page I have a
<h:form>
<!-- (... various input ...) -->
<h:commandLink action="#{someController.create}" value="Create" />
</h:form>
When I submit it, even if data are right, I never get my "something" not to be null.
The use case is easy, I have a one to many relation and I want to access the "one" with the id as a GET parameter and list the "many" on the page and below the listing the form allows me to add a new element in the "many" list.
I'd like to make it work (of course) and be the cleaner possible,
Could someone tell me what's the best way to achieve this?
Thanks!
Either make the SomeController bean #ViewScoped so that the bean lives as long as you're interacting with the same view,
#ManagedBean
#ViewScoped
public class SomeController {
// ...
}
or use <f:param> in UICommand components to pass GET parameters through
<h:commandLink>
<f:param name="someId" value="#{param.someId}" />
</h:commandLink>

Icefaces rowselector

Could someone give me a nice and clean example of how to use the Icefaces 2.0 rowselector? My plan is to use it as a component, so I can reuse it for all kinds of lists.
<ice:dataTable id="table" value="#{cc.attrs.list}" var="record">
<ice:column>
<ice:rowSelector rendered="#{cc.attrs.select == 1}" value="#{cc.attrs.selectMethod}"
selectedClass="tableRowSelected" mouseOverClass="tableRowMouseOver"
immediate="false" selectionListener="#{cc.attrs.selectMethod}" />
<f:facet name="header">
<ice:outputText value="#{record.idDesc}"></ice:outputText>
</f:facet>
<ice:outputText value="#{record.id}"></ice:outputText>
</ice:column>
..
</ice:dataTable>
As you may see, I'm not sure how Im going to handle the value="???" and the selectionListener="???". I'm not sure how to implement it in the bean.
It would be great if I can separate the bean and the component methods into two differnet classes. Whenever I need a rowSelector, for some List object in some Bean, I simply add the Component object to present bean.
Maybe to many things at 1 time, if so, sorry for that =)
B.R
Problem solved! =)
Made a list and a listener.

Resources