I have a breadcrumb and datatable
Number of columns is dynamic. (ie: On clicking "Header7" in breadcrumb, 7 header column plus one "More-Info" column is to be rendered).
I created data-table using primefaces-datatable-columns
My xhtml file is :
<p:dataTable id="dataMain" var="car" value="#{orgUnitBean.rows}">
<p:columns value="#{orgUnitBean.columns}" var="column"
columnIndexVar="colIndex" sortBy="#{car[column.property]}" filterBy="#{car[column.property]}">
<f:facet name="header">
<h:outputText value="#{column.header}" />
</f:facet>
<h:outputText value="#{car[column.property]}" />
</p:columns>
</p:dataTable>
Question:
how to add commandLink in "More-Info" column. (currently I am just displaying "id" of last "Header" entity in it. In image attached: 3 is id of unitL3 and 13 is id of Lnitu3. I want to replace it with commandLink which will invoke bean method and pass these id as parameter to it).
Thanks
Use the rendered attribute of a commandLink in combination with the colIndex. Put this in the column like this
<p:commandLink rendered="#{colIndex == 5}" ... />
Where 5 is the index of the more-info column. You can also do a string compare on the colum header if you want.
(This is a very basic jsf pattern btw)
Related
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
I have 2 pages.
Add Page for add a new item
List Page for show all items
When I click on Edit icon on List Page, I want to show selected data on Add Page for editing and update its data if I click on save button. How to do this?
Pass the row identifier as a parameter to the button. For example, assuming that #{item} is the currently iterated item and has some Long id property which uniquely identifies the item.
<p:button icon="ui-icon-pencil" outcome="edit.xhtml">
<f:param name="id" value="#{item.id}" />
</p:button>
In the target page, edit.xhtml, you can use <f:viewParam> to convert, validate and set it as a bean property.
<f:metadata>
<f:viewParam name="id" value="#{bean.item}" required="true" converter="itemConverter" />
</f:metadata>
...
<p:inputText value="#{bean.item.name}" />
<p:inputText value="#{bean.item.shortName}" />
See also:
What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?
Communication in JSF 2.0 - Processing GET request parameters
I have upgraded my project from Primefaces 2.2 to 3.0
I am facing problems in Datatable. I have a Datatable whose values i am populating through a list and selected rows are kept in array
<p:dataTable id="datavalues" value="#{bean.list}"
var="o" paginator="true" rows="10"
selection="#{bean.selected1}"
rowKey="#{o.property1}" >
now i want the selected rows to be used in another Datatable and on that Datatable i have used values as "#{bean.selected1}" and selection as #{bean.selected2} as i also need the selected values from this Table.
<p:dataTable id="table4" var="o" value="#{bean.selected1}"
rows="10"
selection="#{bean.selected2}"
rowKey="#{o.property2}"
>
The Exception I got is :
[Lcom.packagedirectory.beans.beanHelper; cannot be cast to java.util.Collection
list, selected1, selected2 are all properties of beanHelper Class.
This code was perfectly working on 2.2 Has it something to do with That value is also an array and selection is also an array.
In Primefaces 2.2 the selection would have updated its bean value automatically, however this was probably not desirable for every situation, so in 3.0 they changed it so that for an ajax postback to occur you need to place a <p:ajax> tag with a rowSelect event within the dataTable.
<p:dataTable id="table1" ... >
<p:ajax event="rowSelect" update="formid:table1 formid:table2" oncomplete="dlg.show()" />
...
</p:dataTable>
<p:dataTable id="table2" ... >
...
</p:dataTable>
Selections of the first dataTable should trigger the server postback and partial page update of your second dataTable.
I think you should try to add selectionMode="multiple" in your 1st <p:dataTable> and selectionMode="single" in your 2nd <p:dataTable>.
I have a query about PrimeFaces. Is it possible to implement a RowSelectionListener component that is similar to
<h:commandLink value ="selection"
action="#{usuariosGruposBean.selectionOfGroupObject}">
<f:setPropertyActionListener target="#{usuariosGruposBean.grps}"
value="#{groups}"/> </h:commandLink>
within a datatable?
You mean for a datatable right ?
if so yes it's possible to do that, you just need to create a method like this
public void onEditRow(RowEditEvent event) {
enter code here
}
and register it in the JSF using something like this inside the DataTable tag
<p:ajax event="rowEdit" update="#this" listener="#{userController.onEditRow}" />
here it will update the whole Datatable because of the #this, if you want to update just a few column you could change that to the name of those columns separated by a space
which would look something like this
<p:dataTable var="user" value="#{userController.allUsers}" id="userTable">
<p:ajax event="rowEdit" update="#this" listener="#{userController.onEditRow}" />
things inside the table
</p:datatable>
I don't know exactly what you're trying to do, but have you looked at the primefaces showcase yet? They have a lot of examples how to build a row selection listener.
Hi All
I have list of module object. I want to show it to user and user can edit it and can save it also. In module object three members are there 1 String moduleName 2.boolean readFlag
3. writFlag.
The bean i am using is in Request Scop i don't want to use any other scop.
My problem is setterOfThatList is not called when update button is clicked.
Where as on the same page i used another inputText, setter of the variable which is connected to this inputText is called.
<h:dataTable value="#{roleBean.listMatrixDo}" var="list">
<h:column>
<f:facet name="header">
<h:outputText value="Module Name"></h:outputText>
</f:facet>
<h:outputText value="#{list.moduleDo.moduleName}"></h:outputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Read Access"></h:outputText>
</f:facet>
<h:selectBooleanCheckbox value="#{list.readFlag}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Write Access"></h:outputText>
</f:facet>
<h:selectBooleanCheckbox value="#{list.writeFlag}" />
</h:column>
</h:dataTable>
My problem is setterOfThatList is not called when update button is clicked
The setter is never called for collection and nested properties. JSF does basically as follows:
((RowObject) bean.getList().get(rowIndex)).setSomeProperty(submittedValue);
It gets the list and then gets the row object by current index and then sets the property on it. As you see, it's important that the very same list is already prepared in the subsequent request (i.e. you need to do it in constructor/postconstruct of the bean).
This is regardless of the scope. In view and session scope, however, you don't need to prepare the list in subsequent requests. I'd recommend to use the view scope when data loading from the DB is been involved.
If your intent is to process/save the submitted data, then you should just do the job in the bean's action method which you attached to the commandbutton.
public void submit() {
someService.save(list);
}