retrive value from collection and show in datatable - jsf-2

I want to show language in view_lang.xhtml using datatable,Below are my classes
CountryBean.java
private ArrayList<Country> existingCountryList;
public ArrayList<Country> getExistingCountryList() {
System.out.println("CountryBean.getExistingCountryList::Enter");
existingCountryList = new ArrayList<Country>();
existingCountryList.addAll(getCountryService().getExistingCountry());
System.out.println("existingCountryList in countryBean"+existingCountryList);
System.out.println("CountryBean.getExistingCountryList:::Exit");
return existingCountryList;
}
country.java
private Set<CountryLanguage> countryLanguage = new HashSet<CountryLanguage>(0);
CountryLanguage.java
private CountryLanguageID countryLangPK = new CountryLanguageID();
CountryLanguageID.java
private Country country;
private Language language;
view_lang.xhtml
<h:dataTable id="existingCountry" var="countryLang" value="#{countryBean.existingCountryList}"
style="width: 100%" cellpadding="0" cellspacing="1" border="0" class="role_detail_section" rowClasses="activity_white, activity_blue">
<h:column>
<f:facet name="header">
<h:outputText value="Language(Code)" styleClass="heading_pm_det_white"/>
</f:facet>
<h:outputText value="#{countryLang.languageName}(#{countryLang.languageCode})" styleClass="heading_pm_det_white" />
</h:column>
</h:dataTable>
I am able to get country object with language but not able to print in datatabel.
what will be syntex do I have to use forEach, if yes then how.
thnx

You can use <ui:repeat> for this, but this doesn't support Set (because it's not ordered by an index). You need to convert it to a List or an array. If you're using EL 2.2, then you could use the Set#toArray() call directly in EL:
<ui:repeat value="#{countryLang.countryLanguage.toArray()}" var="countryLanguage">
...
</ui:repeat>
Update, as per the comments, you'd like ot print it comma separated, here's how you could do it:
<ui:repeat value="#{countryLanguage.language.languageName}" var="languageName" varStatus="loop">
#{languageName}#{loop.last ? '' : ', '}
</ui:repeat>
Note: if languageName is actually a Set instead of List, obviously use toArray() there.

Related

To get the row number of the selected primefaces datatable row

I have a primefaces datatable i need to display (selected row number) of (total number of rows) in the JSF page.I could get the row numbers displayed in one of the columns using rowIndexVar attribute but i am not getting any idea to display the same numbers separately in the input text on row select.
What should i need to do in JSF page or managed bean to get selected row number.
Please help me in this regard.
Below is my JSF page
<p:dataTable id="workSpaceList" var="data"
value="#{workSpaceBean.lpInfoList}" widgetVar="multiSelection"
selection="#{workSpaceBean.selectedRows}" resizableColumns="true"
liveScroll="true" scrollRows="55" scrollWidth="85%"
scrollHeight="81%" styleClass="datatable"
scrollable="true" rowIndexVar="rowIndex"
filteredValue="#{workSpaceBean.filteredWorkSpaceItems}">
<p:column selectionMode="multiple" style="width:3%" />
<p:column headerText="#" style="width:3%">
#{rowIndex+1}
</p:column>
<p:column headerText="Insured" filterBy="#{data.insuredName}"
sortBy="#{data.insuredName}" style="width:24%">
<h:outputText value="#{data.insuredName}" />
<!-- style="width:250px" -->
</p:column>
<p:column headerText="City" filterBy="#{data.custAddress_City}"
sortBy="#{data.custAddress_City}" style="width:12%">
<h:outputText value="#{data.custAddress_City}" />
</p:column>
.
.
.
.
</p:dataTable>
I believe that there's not a straight forward way to do so. Although using two ajax requests is not pretty, you can at least achieve the result you expect when using plain PrimeFaces. You can reduce this to one call if you replace the p:ajax with the PrimeFaces extensions pe:javascript which does not do a roundtrip to the server
Every row (tr) rendered by your datatable has a attribute called data-rk with your rowKey and another attribute called data-ri with your rowIndexVar value.
You can get the data-rk attribute through dtWidgetVar.selection (dtWidgetVar is the name of the widgetVar in your datatable).
You can now send the indexRow to your model using a remoteCommand
Here is the code I used to test it:
The View
<p:remoteCommand name="displayIndex" process="#this" update="index" actionListener="#{viewMBean.displayRowIndex}"/>
<p:dataTable id="dt" var="data"
value="#{viewMBean.dataModel}"
selection="#{viewMBean.selectedRow}"
selectionMode="single"
widgetVar="dtVar"
rowIndexVar="index">
<p:ajax event="rowSelect"
oncomplete="displayIndex([{name:'index', value:jQuery('tr[data-rk=' + dtVar.selection + ']').attr('data-ri')}])" process="#this" />
<p:column headerText="#">
#{index + 1}
</p:column>
<p:column headerText="Dados">
#{data.name}
</p:column>
</p:dataTable>
<br />
Row Index: <p:inputText id="index" value="#{viewMBean.index}" />
Managed Bean
public void displayRowIndex() {
FacesContext context = FacesContext.getCurrentInstance();
Map map = context.getExternalContext().getRequestParameterMap();
String pIndex = (String) map.get("index");
index = Integer.parseInt(pIndex);
}
In case you are using checkbox selection, you can retrieve the selected indexes like this:
function beforeDisplayingIndexes(){
var indexes = "";
jQuery("tbody .ui-chkbox-box").each(function(){
if (jQuery(this).hasClass("ui-state-active")){
indexes = indexes + (indexes === "" ? "" : ",") + jQuery(this).closest("tr").attr("data-ri");
}
});
//for debuging only
console.log(indexes);
displayIndex([{name:'index', value:indexes}])
}
You should now be able to make the proper modification to your code to make use of that.
I'm surprised by the complex solution in the other answer. Assuming you you have the #{workSpaceBean.lpInfoList} serverside when doing the 'select', you can easily do (code according to the PrimeFaces showcase, adapt according to your needs)
<p:ajax event="rowSelect" listener="#{dtSelectionView.onRowSelect}" update="..." />
public void onRowSelect(SelectEvent event) {
int rownum = cars.indexOf((Car)event.getObject());
}

sorting in p:datatable behave unusual

I am using sorting in p:datatable, and last column is edit .
its working fine till sorting is pressed. as soon as I do sorting it behave unusual.
On editing it giving wrong object.
belwo is my datatable.
<h:form>
<h:inputHidden value="#{countryBean.initList}" />
<p:dataTable id="existingCountry1" var="countryLang" value="#{countryBean.myexistingCountryList}" style="width: 100%" styleClass="role_detail_section"
rowStyleClass="activity_white, activity_blue" cellspacing="0" cellpadding="0" border="0" rows="6" paginator="true">
<p:column width="30%" headerText="Country " sortBy="countryName">
<h:outputLabel value="${countryLang.countryName}" />
</p:column>
<p:column width="30%" headerText="Country Code " >
<h:outputLabel value="${countryLang.countryCode}" />
</p:column>
<p:column headerText="Edit" >
<p:commandLink id="editCommandLinkId"
action="#{countryBean.editCountryByCountryCode(countryLang.countryCode,true)}" title="Edit" styleClass="edit_icon" onstart="statusDialog.show();" onsuccess="statusDialog.hide();"/>
</p:column>
</p:dataTable>
suppose I edited for US, then it will show data for AU like that.
for sorting I am using belwo technique
private ArrayList<Country> myexistingCountryList;
public String getInitList() {
myexistingCountryList= getExistingCountryList();
return null;
}
public ArrayList<Country> getExistingCountryList() {
try {
existingCountryList = new ArrayList<Country>();
existingCountryList.addAll(getCountryService().getExistingCountry());
} catch (ServiceException e) {
e.printStackTrace();
errorLogger.error("Error while getExistingCountryList in service layer", e);
}
There are to many mistakes in your code.
Instead of $ use #
Instead of sortBy="countryName" write sortBy="#{countryLang.countryName}"
So basicly
change this
<p:column width="30%" headerText="Country " sortBy="countryName">
<h:outputLabel value="${countryLang.countryName}" />
</p:column>
to this
<p:column width="30%" headerText="Country " sortBy="#{countryLang.countryName}">
<h:outputLabel value="#{countryLang.countryName}" />
</p:column>

Primefaces p:fileDownload inside p:treeTable doesn't work?

I have such structure:
<p:treeTable value="#{cmpDocumentTree.root}" var="v" id="#{tableId}" selectionMode="single"
selection="#{cmpDocumentTree.selectedNode}">
<p:ajax event="expand" listener="#{cmpDocumentTree.onNodeExpand}" />
<p:ajax event="collapse" listener="#{cmpDocumentTree.onNodeCollapse}" />
<p:ajax event="select" listener="#{crudBean.edit(cmpDocumentTree.selectedNode.data)}"
update=":#{formDialogUpdate}" oncomplete="#{formDialog}.show()" />
<p:column headerText="Nazwa" sortBy="#{v.name}" style="min-width: 200px;">
<h:outputText value="#{v.name}" />
</p:column>
<p:column headerText="Pliki" width="300">
<ui:repeat var="_file1" value="#{v.files}">
<h:commandLink value="#{_file1.originalFilename}">
<p:fileDownload
value="#{fileDownloadController.getFile(_file1.originalFilename, _file1.storedFilename, _file1.contentType)}" />
</h:commandLink>
<br />
</ui:repeat>
</p:column>
</p:treeTable>
But - p:fileDownload doesn't work. The fileDownloadController.getFile(...) method is not fired at all.
When I put the same method inside p:dataTable, then it works perfectly.
EDIT:
v.files comes from ComDocument entity - it is relation one-to-many document-to-files.
#Entity
#Table(name = "com_documents", schema = "public")
#SequenceGenerator(name = "COM_DOCUMENTS_SEQ", sequenceName = "COM_DOCUMENTS_SEQ", allocationSize = 1)
public class ComDocument implements EntityInt, java.io.Serializable {
(...)
#OneToMany(fetch = FetchType.EAGER, mappedBy = "document", cascade = CascadeType.ALL, orphanRemoval = true)
private List<ComDocumentFile> files;
public void setFiles(List<ComDocumentFile> files) {
this.files = files;
}
public List<ComDocumentFile> getFiles() {
return files;
}
Could you help me? Thanks.
I've never had any luck with the FileDownload working inside an ajax request. I have not bothered to dig into the source as it is never a show stopper (and it really doesn't make sense to use it as an ajax request--you're getting a complete file, not updating a page).
The simple solution here is to make sure that your command button has "ajax=false"
<p:commandLink value="#{_file1.originalFilename}" ajax="false">
<p:fileDownload
value="#{fileDownloadController.getFile(_file1.originalFilename, file1.storedFilename, _file1.contentType)}" />
</p:commandLink>
http://www.primefaces.org/showcase/ui/fileDownload.jsf
You'll notice all the examples have the ajax functionality disabled. If you're using h:commandButton for style I suggest using p:commandLink and styling it to be a button.
Best of luck, I'm pretty sure this will fix it. Also--make sure your "download objects" are final. You need to make sure that the data-source is referring to the same reference and not creating a new instance on each request.

Image separator for rows in jsf data table

I want to display an line/image as separator ( as shown here - image attached) between rows conditionally, and I have no idea on how to achieve this, please suggest, this is my sample that I have written to replicate the actual scenario,
<h:panelGrid columns="1" >
<h:dataTable value="#{testBean.myBeanList}" var="myBean">
<h:column>
<f:facet name="header">
<h:outputText value="EMPLOYEE NAME" />
</f:facet>
<h:outputText value="#{myBean.empName}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="EMPLOYEE DEPARTMENT" />
</f:facet>
<h:outputText value="#{myBean.empDept}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="EMPLOYEE HR NAME" />
</f:facet>
<h:outputText value="#{myBean.empHRName}"/>
</h:column>
</h:dataTable>
</h:panelGrid>
public TestBean() {
myBeanList = new ArrayList<MyBean>();
for(int i =0;i<8;i++){
MyBean mb = new MyBean();
if(i == 2 || i == 4){
mb.setEmpName("NAME"+i);
}else{
mb.setEmpName("EMPLOYEE NAME"+i);
mb.setEmpDept("EMPLOYEE DEPT"+i);
mb.setEmpHRName("EMPLOYEE HR NAME"+i);
}
myBeanList.add(mb);
}
}
Use the rowClasses attribute of the <h:dataTable>. It takes a commaseparated string of CSS class names which are applied on the subsequent generated <tr> elements. You can then use CSS to put a top border in every cell (<td>) of the <tr> in question (those with "NAME2" and "NAME4" in your example).
<h:dataTable ... rowClasses="#{bean.rowClasses}">
At the same time of populating the data model, you should also populate the row classes. It should for the particular exapmle in the screenshot return something like this:
none,none,separator,none,separator,none,none,none
Then you just have to provide the necessary CSS:
tr.separator td {
border-top: 1px solid gray;
}
No need for an ugly and old fashioned separator image.

dataTable, inputText and value saving of a "not direct" bean variable

I have a dataTable with a list of inputTexts:
<h2>
Attributes
</h2>
<h:dataTable
value="#{detailModel.getAfterObjectAttributeSpecifications()}"
var="specification"
styleClass="waiFormTable" >
<h:column>
#{specification.name}:
</h:column>
<h:column>
<h:inputText id="attribute" value="#{detailModel.getAfterObjectAttribute(specification.name)}" disabled="#{detailModel.mode == detailModel.viewMode}"/>
</h:column>
</h:dataTable>
The value of the inputText is not a direct bean field (detailModel.getAfterObjectAttribute(specification.name)).
If I change the value and want it save, how should I do?
Thank you for any help
Francesco
You can't. It has to be a real property or at least a Map value. E.g.
<h:dataTable
value="#{detailModel.afterObjectAttributeSpecifications}"
var="specification"
styleClass="waiFormTable" >
<h:column>
#{specification.name}:
</h:column>
<h:column>
<h:inputText id="attribute" value="#{detailModel.afterObjectAttributes[specification.name]}" disabled="#{detailModel.mode == detailModel.viewMode}"/>
</h:column>
</h:dataTable>
with
public Map<String, String> getAfterObjectAttributes() {
return afterObjectAttributes;
}

Resources