RichFaces Sorting Icon - jsf-2

I am migrating a richfaces 3.x application to 4.x, on a datatable i need to add sorting functionality which is not built in, i have added the sorting functionality but i need to place icons for the sorting functionality, how do i pick icons from richfaces components ui jar? should i place new icons inside the project and then access it.
<rich:dataTable id="showsEventsTable">
<rich:column sortable="true" selfSorted="true"
sortBy="#{show.name}" sortorder="SortOrder.ascending" sortOrder="#{sortingBean.showNameOrder}">
<f:facet name="header">
<a4j:commandLink value="Show Name" render="showsEventsTable" action="#{sortingBean.sortByShowName()}"
styleClass="sortingColumn" status="waitStatus">
<span styleClass="#{sortingBean.sortOrder}"/>
<h:graphicImage value="??(what should go here if am accessing richfaces components jar)" library="org.richfaces"/>
</a4j:commandLink>
</f:facet>
<h:outputText value="#{show.name}" />
</rich:column>
</rich:dataTable>
In the css file
.ascending{
background-image: url("imgpath");
}
.descending{
background-image: url("imgpath");
}
.unsorted{
background-image: url("imgpath");
}

If your application was migrated to RichFaces 4.5, then you don't need accessing to sorting icons - its appear automatically, when sorting is added.
If application was migrated to previous version of RichFaces 4.x, then simple add 3 sorting icons (from RichFaces 3 or RichFaces 4 jar) in your application and use it.
UPDATE
Following is example have to use sorting icons:
<rich:column id="date" sortBy="#{rs.changeDate}" sortOrder="descending">
<f:facet name="header">
<h:commandLink value="#{msg.entryDate}" styleClass="tableColumnHeader">
<rich:componentControl target="noteTable" operation="sort">
<f:param name="column" value="date" />
<f:param value="" />
<f:param name="reset" value="true" />
</rich:componentControl>
<h:graphicImage value="/images/sort/sort_asc.gif"
style="border: 0px; vertical-align: middle;"
rendered="#{chNotesAction.list.order == 'changeDate ASC'}" />
<h:graphicImage value="/images/sort/sort_des.gif"
style="border: 0px; vertical-align: middle;"
rendered="#{chNotesAction.list.order == 'changeDate DESC'}" />
<h:graphicImage value="/images/sort/sort_uns.gif"
style="border: 0px; vertical-align: middle;"
rendered="#{chNotesAction.list.order != 'changeDate ASC'
and chNotesAction.list.order != 'changeDate DESC'}" />
</h:commandLink>
</f:facet>
<h:outputText value="#{rs.changeDate}">
<f:convertDateTime timeZone="#{referenceData.timezone}" pattern="MMM dd, yyyy HH:mm" />
</h:outputText>
</rich:column>
You can use 1 graphicImage with EL for value attribute like order eq 'ASC' ? sort_acs.gif : (order eq 'DESC' ? sort_desc.gif : sort_unc.gif)

Related

DataTable clearFilter() not working properly

I have a complicate JSF that contain dataTable with filter in each one of the columns.
In order to make sure that the generate button will fetch all the data first I need to clear all the filters when the user press the button.
I try to do use onclick but then I couldn’t see the blockUI I also try on complete (ajax) but again it was not working properly with all the other items (blockUI ,message).
I decided to try to clear the filters via server side but only dataTable.reset() is working.
I have no more ideas how to clean the filters ???
Is this API working ?
Appreciate your help
Thanks
<h:panelGrid columns="1" style="width: 100%">
<p:panel id="vt-panel">
<h:panelGrid columns="5" cellpadding="2" >
<h:outputText value="Start Date" />
<p:calendar id="vt-start" value="#{vtRepBean.startDate}" binding="#{startDateComponent}" maxlength="9" size="9" pattern="dd-MMM-yy" title="dd-MMM-yy" required="true" maxdate="#{vtRepBean.endDate}">
<p:ajax event="dateSelect" listener="#{vtRepBean.handleStartDateSelect}" update=":mainForm:vt-end"/>
</p:calendar>
<h:outputText value="End Date" />
<p:calendar id="vt-end" value="#{vtRepBean.endDate}" maxlength="9" size="9" pattern="dd-MMM-yy" title="dd-MMM-yy" required="true" mindate="#{vtRepBean.startDate}">
<p:ajax event="dateSelect" listener="#{vtRepBean.handleEndDateSelect}" update=":mainForm:vt-start"/>
</p:calendar>
<p:commandButton
id="genVtBtn"
value="Generate"
actionListener="#{vtRepBean.handleVTGenerateButton}"
update=":mainForm:vt-panel,:mainForm:vt-panel-table">
</p:commandButton>
</h:panelGrid>
</p:panel>
</h:panelGrid>
<p:growl id="vt_message" showDetail="true" autoUpdate="true"/>
<h:panelGroup id="vt-panel-table">
<p:dataTable id="vtDataTable"
widgetVar="vtWidget"
var="reportObject"
value="#{vtRepBean.reportObjectsList}"
rendered="#{vtRepBean.renderVTReport}"
filteredValue="#{vtRepBean.filteredVTList}"
paginator="true"
paginatorPosition="bottom"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
rowsPerPageTemplate="50,100,200"
rows="50"
style="width: 100%">
<p:columnGroup type="header">
<p:row>
<p:column colspan="5" headerText="VT request"/>
<p:column colspan="1" headerText="Dis" />
</p:row>
<p:row>
<p:column headerText="CREATE DATE" sortBy="#{reportObject.log.createDate}" filterBy="#{reportObject.log.createDate}" filterMatchMode="contains"/>
<p:column headerText="IP" sortBy="#{reportObject.log.ip}" filterBy="#{reportObject.log.ip}" filterMatchMode="contains"/>
</p:row>
</p:columnGroup>
<p:column >
<h:outputText value="#{reportObject.log.createDate}"/>
</p:column>
<p:column >
<h:outputText value="#{reportObject.log.ip}"/>
</p:column>
</p:dataTable>
<p:commandLink rendered="#{vtRepBean.renderVTReport}" ajax="false" onclick="PrimeFaces.monitorDownload(showStatus, hideStatus)">
<p:graphicImage value="resources/images/excel.png" title="excel" style="border-color: white"/>
<p:dataExporter id="xlsReport"
type="xls"
target="vtDataTable"
fileName="VTReport"
postProcessor="#{vtRepBean.postProcessXLS}"/>
</p:commandLink>
</h:panelGroup>
<p:blockUI widgetVar="blockVTPanel" trigger="genvtBtn" block="vt-panel">
<div class="disable-scroll">
<p:graphicImage value="resources/images/ajax-loader.gif"/>
</div>
</p:blockUI>
DataTable dataTable = (DataTable) FacesContext.getCurrentInstance().getViewRoot().findComponent("mainForm:vtDecomDataTable");
if (!dataTable.getFilters().isEmpty()) {
logger.info("dataTable.getFilters().isEmpty() :" + dataTable.getFilters().isEmpty());
dataTable.getFilters().clear();// not working
dataTable.getFilteredValue().clear();// not working
dataTable.setFilteredValue(null);// not working
dataTable.setFilters(null);// not working
dataTable.setFilterMetadata(null);// not working
dataTable.reset();// working
RequestContext requestContext = RequestContext.getCurrentInstance();
requestContext.update("mainForm:vtDecomDataTable");
}
To clear all the inputs of the filters you can do it by javascript:
<p:commandButton onclick="PF('vtWidget').clearFilters()" />
vtWidget is the widgetVar of the datatable.
Basically clearFilters() will clear the fields for you and call filter(), and the filter function would update your datatable, which in turns will empty the filtered list.
Note: This would work only if the filters were inputText. If you have custom components then you should implement your own clear based on the components that you have.
Sometimes if you have custom components, you need to empty the filtered list manually, as you did in the comments!
This is how i solved my problem.
RequestContext requestContext = RequestContext.getCurrentInstance();
requestContext.execute("PF('widget_orderDataTable').clearFilters()");
Hope its help.
For clearing custom filters you can use primefaces resetInput, along with clearFilters() discussed in other answers, and a custom actionListener method. See code snippets below:
<p:dataTable id="dataTable" widgetVar="dataTable"
value="#{bean.listOfObjects}" var="object">
<p:commandButton value="Clear All Filters"
onclick="PF('dataTable').clearFilters()"
actionListener="#{controller.clearAllFilters}"
update="dataTable">
<p:resetInput target="dataTable" />
</p:commandButton>
Controller.java
public void clearAllFilters() {
DataTable dataTable = (DataTable) FacesContext.getCurrentInstance().getViewRoot().findComponent("form:dataTable");
if (!dataTable.getFilters().isEmpty()) {
dataTable.reset();
RequestContext requestContext = RequestContext.getCurrentInstance();
requestContext.update("form:dataTable");
}
}
I hope this helps anyone looking to clear custom filters.
For Primefaces 7 and above, use the following:
public void clearAllFilters() {
DataTable dataTable = (DataTable) FacesContext.getCurrentInstance().getViewRoot().findComponent("form:dataTable");
if (!dataTable.getFilters().isEmpty()) {
dataTable.reset();
PrimeFaces.current().ajax().update("form:dataTable");
}
}

JSF "rendered" - strange behavior

I can't explaine this well - it's need to see:
Video screencast
Please explain me what happens?
next code work and return true or false but when I put this to rendered="" this not work.
#{!empty detailsBean.goods.pictures}
rendered="true" rendered="false" rendered="#{true}" - work
<p:commandButton id="btn_details" value="#{msg.btn_details}" oncomplete="PF('dlg-detailed').show()" update=":dlg-detailed-id">
<f:setPropertyActionListener target="#{detailsBean.goods}" value="#{goods}" />
<f:param name="id" value="#{goods.id}"/>
</p:commandButton>
Dialog - where I try render text with condition.
<p:dialog id="dlg-detailed-id" widgetVar="dlg-detailed" header="#{msg.btn_details}" dynamic="true" modal="true" draggable="false" width="800" height="600">
<h:outputText value="Some Text For Rendering" rendered="#{!empty detailsBean.goods.pictures}" />
</p:dialog>
Mojarra 2.1.7-jbossorg-1
JBoss AS 7.1.1
I apologize for my mistakes in English
in this case, solution is: add < h:form> tag and then rendered="#{!empty detailsBean.goods.pictures}" work
<h:form id="form-detailed" >
<p:dialog id="dlg-detailed-id" widgetVar="dlg-detailed" header="#{msg.btn_details}" dynamic="true" modal="true" draggable="false" width="800" height="600">
<h:outputText value="Some Text For Rendering" rendered="#{!empty detailsBean.goods.pictures}" />
</p:dialog>
</h:form>

JSF 2 display List values in 2 columns

I am a newbie in JSF. I am using JSF 2 and there is a list being populated by my bean file. In my .xhtml file, I want to display this information as 2 columns.
In bean class
List modules;(Contains module.enable module.name)
The list has say 30 modules. I want to display all these modules information in 2 columns. For eg: I want to display first module information(module.enable module.name) in one column and the second in second column. Or it can be first 15 modules in first column and the remaining 15 in second column. Tried with both h:dataTable and h:panelGrid but couldn't get it working.
Any help would be highly appreciated.
Thanks
Shyju
This is my code to resolve the issue using the varStatus property of ui:repeat
<h:panelGrid id="moduleList" columns="2" border="1" >
<f:facet name="header">
<h:outputText value="Modules"/>
</f:facet>
<ui:repeat value="#{EnableCodeBean.modules}" var="modules" varStatus="status">
<h:panelGroup>
<h:selectBooleanCheckbox value="#{modules.enable}"/>
<h:outputText value="#{modules.name}"/>
</h:panelGroup>
<f:verbatim rendered="#{status.index mod 2 == 1}">
</td></tr><tr><td>
</f:verbatim>
<f:verbatim rendered="#{status.index mod 2 == 0}">
</td><td>
</f:verbatim>
</ui:repeat>
</h:panelGrid>
By playing with some <h:dataTable>'s attributes' values, we can make something like that:
The attribute first, idicates to the first index of the list to start displaying from, and the rows's one, indicates to the rows' number to be diplayed starting from the begining index designed if explicited, else, it displays from the 1st row and so on.
Here's a kickoff example of this, relying on 2 <h:dataTalbe> tags included in one <h:panelGrid coulmns="2">, and relying only on 4 modules for simplification's purpose, 2 per every column. Every <h:dataTable> tag must have different value of its first attribute :
The Backing-bean:
#ManagedBean
#RequestScoped
public class ModuleBacking{
private List<Module> modules = new ArrayList<Module>();
public ModuleBacking() {
}
#PostConstruct
public void insertion() {
Module m1 = new Module("math",true);
Module m2 = new Module("english",false);
Module m3 = new Module("physics",false);
Module m4 = new Module("chimics",true);
modules.add(m1);
modules.add(m2);
modules.add(m3);
modules.add(m4);
}
public List<Module> getModule() {
return modules;
}
public List<Module> displayModules(){
return modules;
}
}
The view :
<h:body>
<h:panelGrid columns="2" cellspacing="3" cellpadding="3" style="border-style: solid" rules="all" >
<f:facet name="header">
<h:outputText value="First 2 modules" style="padding-right:80px "/>
<h:outputText value="Second 2 modules"/>
</f:facet>
<h:dataTable value="#{moduleBacking.displayModules()}" var="m" rules="all" first="0" rows="2">
<h:column>
<f:facet name="header" ><h:outputText value="Module's name" /></f:facet>
<h:outputText value="#{m.name}" />
</h:column>
<h:column>
<f:facet name="header" ><h:outputText value="Module's enabling" /></f:facet>
<h:outputText value="#{m.enable}" />
</h:column>
</h:dataTable>
<h:dataTable value="#{moduleBacking.displayModules() }" var="m" rules="all" first="2" rows="2">
<h:column>
<f:facet name="header" ><h:outputText value="Module's name" /></f:facet>
<h:outputText value="#{m.name}" />
</h:column>
<h:column>
<f:facet name="header" ><h:outputText value="Module's enable" /></f:facet>
<h:outputText value="#{m.enable}" />
</h:column>
</h:dataTable>
</h:panelGrid>
</h:body>
In your case, the two <h:dataTable> seem to be like these :
<h:dataTable value="#{moduleBacking.displayModules()}" var="m" rules="all" first="0" rows="15">
<h:dataTable value="#{moduleBacking.displayModules()}" var="m" rules="all" first="15" rows="15">

Render multiple forms using a4j:jsFunction

I'm trying to render a different <h:form> using <a4j:jsFunction> in some other form. However its not working. The code I've implemented is as follows:
<t:div style="display:table-row; ">
<a4j:region>
<t:div style="display:table-cell; border:1px solid #608AA9;">
<h:form id="accordForm">
<rich:accordion id="accordId" switchType="client" activeItem="#{projectCreation.activeTab}">
<c:forEach var="proj" items="#{projectCreation.projects}">
<rich:accordionItem name="#{proj.description}">
<f:facet name="header">#{proj.description}</f:facet>
<h:form id="moduleAccord" rendered="#{proj.childCount>0}">
<rich:accordion id="moduleAccordId" switchType="client" activeItem="#{projectCreation.activeModuleTab}" onitemchange="moduleAccordionChange();">
<a4j:jsFunction name="moduleAccordionChange" execute="#all" render="#all" action="#{projectCreation.accordionItemChange}" />
<c:forEach var="mdle" items="#{proj.modules}">
<rich:accordionItem id="module#{mdle.id}" name="#{mdle.description}">
<f:facet name="header">#{mdle.description}</f:facet>
<h:form id="formodule#{mdle.id}" rendered="#{mdle.childCount>0}">
<t:dataList id="subModuleList" var="subMdle" value="#{mdle.subModules}" layout="unorderedList">
<a4j:commandButton id="subModuleCmd" value="#{subMdle.description}" action="#{projectCreation.fetchSubModuleDetails}">
<f:param name="subModuleId" value="#{subMdle.id}" />
</a4j:commandButton>
</t:dataList>
</h:form>
</rich:accordionItem>
</c:forEach>
</rich:accordion>
</h:form>
</rich:accordionItem>
</c:forEach>
</rich:accordion>
</h:form>
</t:div>
</a4j:region>
<h:form id="rightContent">
<t:div id="rightContentDiv">
<h:outputText id="selectedPage" value="#{projectCreation.creationModel.selectedPage}" />
<t:div id="projectDiv" style="display:table-cell;" rendered="#{projectCreation.creationModel.selectedPage=='Project'}">
<a4j:outputPanel ajaxRendered="true">
<ui:include src="/WEB-INF/facelets/project/editProject.xhtml"/>
</a4j:outputPanel>
</t:div>
<t:div id="moduleDiv" style="display:table-cell;" rendered="#{projectCreation.creationModel.selectedPage=='Module'}">
<a4j:outputPanel ajaxRendered="true">
<ui:include src="/WEB-INF/facelets/project/addModule.xhtml"/>
</a4j:outputPanel>
</t:div>
</t:div>
</h:form>
</t:div>
I'm trying to change the rendered page on selection of nested accordion module. I've checked in log that its working fine in controller but its not working as expected on facelet. Its working when I use switchType="server" however it reloads the page completely and I just want to render the rightContent form.
Have a look at this showcase example:
http://showcase.richfaces.org/richfaces/component-sample.jsf?demo=accordion&sample=dynamic&skin=blueSky
Do not nest forms, HTML does not support this !
How to use <h:form> in JSF page? Single form? Multiple forms? Nested forms?

menupopup event listener not get called?

I'm using ice:menuPopup to create menus on tree nodes. In jspx page I've something like this
<ice:tree id="tree" value="#{tree.model}" var="item" imageDir="./xmlhttp/css/xp
/css-images/">
<ice:treeNode>
<f:facet name="icon">
<ice:panelGroup style="display: inline">
<h:graphicImage value="#{item.userObject.icon}"/>
</ice:panelGroup>
</f:facet>
<f:facet name="content">
<ice:panelGroup style="display: inline" menuPopup="menuPopupEffects">
<ice:commandLink actionListener="#{tree.Url}" value="#
{item.userObject.text}"/>
</ice:panelGroup>
</f:facet>
<ice:menuPopup id="menuPopupEffects">
<ice:menuItem value="Open" actionListener="#{tree.NodeValue}">
<f:param name="effectType" value="Open"/>
</ice:menuItem>
<ice:menuItem value="Close">
<f:param name="effectType" value="Close"/>
</ice:menuItem>
<ice:menuItem value="Send">
<f:param name="effectType" value="Send"/>
</ice:menuItem>
</ice:menuPopup>
</ice:treeNode>
The problem is that the actionListener="#{tree.NodeValue}" never gets called. Can any one tell me Where I'm wrong?
Try to move ice:menuPopup..../ice:menuPopup that block up, insert that block into the line just below:
ice:commandLink actionListener="#{tree.Url}" value="#
{item.userObject.text}"
Thus they in the same panelGroup. It works for me this way, but I am still use icefaces 1.8.

Resources