Unable to send parameter from JSF to Bean through datatable value attribute - jsf

I have a expansion datatable which is being populated by an Arraylist from the backend wich has an id as primary key. When row is expanded, that id specific rows has to be searched in an another table and all the rows has to be displayed. when i am trying to pass the id as parameter in the value attribute, it's giving class cast exception.
here's the XHTML Code
<h:form>
<p:dataTable var="data"
value="#{trackerList.trackerList}">
<f:facet name="header">Summary</f:facet>
<p:column style="width:16px">
<p:rowToggler />
</p:column>
<p:column headerText="ID">
<h:outputText value="#{data.id}" />
</p:column>
<p:column headerText="Status">
<h:outputText value="#{data.status}" />
</p:column>
<p:column headerText="Created Time">
<h:outputText value="#{data.createdTime}" />
</p:column>
<p:column headerText="Created By">
<h:outputText value="#{data.createdby}" />
</p:column>
<p:column headerText="Updated By">
<h:outputText value="#{data.updatedby}" />
</p:column>
<p:rowExpansion>
<p:dataTable var="metadata" value="#{statusList.getScenarioStatusList(data.id)}">
<p:column headerText="Requirements">
<h:outputText value="#{metadata.requirements}" />
</p:column>
<p:column headerText="Exam Name">
<h:outputText value="#{metadata.examName}" />
</p:column>
<p:column headerText="Status">
<h:outputText value="#{metadata.status}" />
</p:column>
</p:dataTable>
</p:rowExpansion>
</p:dataTable>
</h:form>
Please Help.

i think you need to define below line inside the p:datatable tag with passing id as parameter and instead of #{statusList.getScenarioStatusList(data.id)} in sub datatable you just do value= "#{yourBean.scenarioStatusList}". populate scenarioStatusList in loadLists(data.id) method.
<p:ajax event="rowToggle" listener="#{yourBean.loadLists(data.id)}" />

Related

p:rowExpansion looks like another row of main p:dataTable

Is there any simple way to unify look of dataTable inside rowExpansion and main dataTable? Or dou you have any ideas to make it nice?
I want it to looks like hidden rows of the same dataTable.
Here is how it looks by default:
And here is default xhtml code:
<p:dataTable id="cars" var="car" value="#{carBean.someList}">
<f:facet name="header">
List of Cars
</f:facet>
<p:column style="width:16px">
<p:rowToggler />
</p:column>
<p:column headerText="Name">
<h:outputText value="#{car.user.name}" />
</p:column>
<p:columns value="#{scoresBean.otherList}" var="score" columnIndexVar="colIndex">
<f:facet name="header">
<h:outputText value="#{colIndex+1}" />
</f:facet>
<h:outputText value="#{car.scores[colIndex]}" />
</p:columns>
<p:rowExpansion>
<p:dataTable id="cycs" var="cyc" value="#{car.semiScoresList}">
<p:column>
<h:outputText value="#{cyc.partName}" />
</p:column>
<p:columns value="#{scoresBean.otherList}" var="score" columnIndexVar="col">
<h:outputText value="#{cyc.partsScores[col]}" />
</p:columns>
</p:dataTable>
</p:rowExpansion>
</p:dataTable>
You can't, not without a lot of css javascript etc. Use a p:treetable for this

How to do the value binding in datatable when selection mode = multiple

I need explanation for the below value binding in the outputText inside p:dialog .I dont clear with that and is there any other way.
In my sample :
I have tried ,if i select the single or many check box the value get binded but when I click root check box which used for selecting all the check boxes, its getting selected but the values not get stored in the back end.
<p:dataTable id="checkboxDT"
var="car"
value="#{dtSelectionView.cars6}"
selection="#{dtSelectionView.selectedCars}"
rowKey="#{car.id}"
style="margin-bottom:0">
<f:facet name="header">
Checkbox
</f:facet>
<p:column selectionMode="multiple"
style="width:16px;text-align:center"/>
<p:column headerText="Id">
<h:outputText value="#{car.id}" />
</p:column>
<p:column headerText="Year">
<h:outputText value="#{car.year}" />
</p:column>
<p:column headerText="Brand">
<h:outputText value="#{car.brand}" />
</p:column>
<p:column headerText="Color">
<h:outputText value="#{car.color}" />
</p:column>
<f:facet name="footer">
<p:commandButton process="checkboxDT"
update=":form:multiCarDetail"
icon="ui-icon-search"
value="View"
oncomplete="PF('multiCarDialog').show()" />
</f:facet>
</p:dataTable>
<p:dialog header="Selected Cars"
widgetVar="multiCarDialog"
modal="true"
showEffect="fade"
hideEffect="fade"
resizable="false"
width="200">
<p:outputPanel id="multiCarDetail" style="text-align:center;">
<ui:repeat value="#{dtSelectionView.selectedCars}"
var="car">
<h:outputText value="#{car.id} - #{car.brand}"
style="display:block"/>
</ui:repeat>
</p:outputPanel>
</p:dialog>
You should update checkboxDT because update is used to determines id’s of components to be updated (refreshed with updated values from server). If you do not update checkboxDT, the selectedCars do not update too.
<p:commandButton process="checkboxDT"
update="checkboxDT,:form:multiCarDetail"
icon="ui-icon-search"
value="View"
oncomplete="PF('multiCarDialog').show()" />

JSF commandButton issue

I am providing a search function using JSF. I get the list and display it correctly in a datatable :
<p:dataTable id="props" var="prop" value="#{propController.propSearch}" editable="true" style="margin-bottom:20px">
<p:column headerText="Id" width="20">
<h:outputText value="#{prop.id}" />
</p:column>
<p:column headerText="Name" width="300">
<h:outputText value="#{prop.name}"/>
</p:column>
<p:column headerText="Description">
<h:outputText value="#{prop.shortDescription}" />
</p:column>
<p:column headerText="Price" width="120">
<h:outputText value="#{prop.price}" />
</p:column>
<p:column width="120">
<h:commandButton value="View Prop" immediate="true" action="#{propController.viewSingleProp(prop)}" />
</p:column>
<p:column width="120">
<h:commandButton value="Delete" immediate="true" onclick="return confirm('Are you sure you want to delete this prop?')" actionListener="#{propController.deleteProp(prop)}" />
</p:column>
</p:dataTable>
</h:form>
However the commandButton to view each individual item does not get called. Instead the search page just refreshes with no data.
Why is this happening?
(I hope your opening tag of <h:form> is just missing in your code posted in your question, not in your actual code!)
You need to remove the attribute immediate="true" from the h:commandButton.
See:
Immediate=true VS immediate=false in JSF Component

IF statement does not work inside Primefaces DataTable

I want to show a row only if I have data for it. The code which i have is:
<p:dataTable id="comments" var="comment"
value="#{agencyBean.getCommentByAgency(agencyBean.tAgency)}"
paginator="true" >
<p:column>
#{comment.author.name}
</p:column>
<p:column>
<c:if test="${not empty comment.positiveComment}">
<p:row>
<p:column>
<p:graphicImage library="images" name="positive.png" />
</p:column>
<p:column> #{comment.positiveComment} </p:column>
</p:row>
<br />
</c:if>
</p:column>
</p:dataTable>
But nevertheless I have data, the row is not shown. How can i implement this logic? Thanks!
Try to place the condition expression in the <p:row>'s tag itself, by using its rendered attribute :
<p:column>
<p:row rendered="#{not empty comment.positiveComment}">
<p:column>
<p:graphicImage library="images" name="positive.png" />
</p:column>
<p:column> #{comment.positiveComment} </p:column>
</p:row>
<br />
</p:column>

JSF Primefaces datatable match mode for global filter (not individual column)

What is the filter match mode for global filter (not the individual column filter which defaults to 'startsWith') and how to change it?
The reason I ask is, when I use the global filter with match mode set to 'startsWith' in all my columns, still I get values with 'contains' filter mode. See screenshot below.
I shouldn't be getting the rows other than the first row as I specified 'startsWith' in all columns.
Here is my datatable,
<h:form id="countryTable">
<p:dataTable rowKey="" value="#{countryBean.countriesList}"
var="country" selection="#{countryBean.selectedCountries}"
styleClass="data-table-style" widgetVar="countryTableWVar"
filteredValue="#{countryBean.filteredCountries}">
<f:facet name="header">
<div class="align-left">
<p:outputPanel>
<h:outputText value="Search all fields:" />
<p:inputText id="globalFilter" onkeyup="countryTableWVar.filter();"
style="width:150px" />
</p:outputPanel>
</div>
</f:facet>
<p:column selectionMode="multiple" style="width:2%;" />
<p:column headerText="Numeric Code" filterMatchMode="startsWith"
filterStyle="display:none" filterBy="numericCode">
<h:outputText value="#{country.numericCode}"></h:outputText>
</p:column>
<p:column headerText="Alpha_2 Code" filterMatchMode="startsWith"
filterStyle="display:none" filterBy="alpha2">
<h:outputText value="#{country.alpha2}"></h:outputText>
</p:column>
<p:column headerText="Alpha_3 Code" filterMatchMode="startsWith"
filterStyle="display:none" filterBy="alpha3">
<h:outputText value="#{country.alpha3}"></h:outputText>
</p:column>
<p:column headerText="Name" filterMatchMode="startsWith"
filterStyle="display:none" filterBy="name">
<h:outputText value="#{country.name}"></h:outputText>
</p:column>
</p:dataTable>
</h:form>
How to change the datatable global filter match mode?
If you look at the source code of primefaces
org.primefaces.component.datatable.feature.FilterFeature.java
At line 133 you can see primefaces uses contains method of String
if(columnValue.toLowerCase(filterLocale).contains(globalFilter)){
globalMatch = true;
}
So for now there is no way other than changing code according to your needs and building your own primefaces jar.
From Primefaces 4.0 docs:
Filter located at header is a global one applying on all fields, this is implemented by calling client
side API method called filter(), important part is to specify the id of the input text as globalFilter
which is a reserved identifier for datatable.
The use case would be:
<p:dataTable var="car" value="#{carBean.cars}"
filteredValue="#{carBean.filteredCars}" widgetVar="carsTable">
<f:facet name="header">
<p:outputPanel>
<h:outputText value="Search all fields:" />
<h:inputText id="globalFilter" onkeyup="PF('carsTable').filter()" />
</p:outputPanel>
</f:facet>
<p:column filterBy="model" headerText="Model" filterMatchMode="contains">
<h:outputText value="#{car.model}" />
</p:column>
<p:column filterBy="year" headerText="Year" footerText="startsWith">
<h:outputText value="#{car.year}" />
</p:column>
<p:column filterBy="manufacturer" headerText="Manufacturer"
filterOptions="#{carBean.manufacturerOptions}" filterMatchMode="exact">
<h:outputText value="#{car.manufacturer}" />
</p:column>
<p:column filterBy="color" headerText="Color" filterMatchMode="endsWith">
<h:outputText value="#{car.color}" />
</p:column>
</p:dataTable>
It doesn't tell anything about startsWithor endsWith specific cases for global filter. It could be interesting to open a thread on the issue tracker.

Resources