Considering the following code, it displays a table with one column and a filter to display the active/inactive records.
How can I disable the menuitem 'Inactive' based on the value selected in the filter? In other words if the the filter value is 'inactive', the 'Inactivate' menu should be disabled.
<p:contextMenu for="ratingScaleTable" id="RsContextMenuId">
<p:menuitem value="Edit" update=":templateForm:tabView, :templateForm:dirtyFlag" icon="ui-icon-search" action="#{ratingScaleBK.edit}" />
<p:menuitem id="inactivate" value="Inactivate" icon="ui-icon-close" action="#{ratingScaleBK.inactivate}" disabled="#{ratingScaleBK.selectedRatingScale.active==0}" />
<p:menuitem value="Activate" update=":templateForm:tabView" icon="ui-icon-close" action="#{ratingScaleBK.activate}"/>
<p:menuitem value="View Archive" update=":templateForm:tabView" icon="ui-icon-close"/>
</p:contextMenu>
<p:dataTable id="ratingScaleTable" widgetVar="tableWidget"
value="#{ratingScaleBK.ratingScaleList}" var="item1"
selectionMode="single"
selection="#{ratingScaleBK.selectedRatingScale}"
rowKey="#{item1.name}"
rendered="#{not empty ratingScaleBK.ratingScaleList}"
filteredValue="#{ratingScaleBK.filteredRatingscale}">
<p:ajax event="rowSelect" process="ratingScaleTable" listener="#{ratingScaleBK.edit}" update=":templateForm:tabView, :templateForm:dirtyFlag, :templateForm:tabView:RsContextMenuId " />
<p:column id="activeCol" filterBy="#{item1.active}"
filterOptions="#{ratingScaleBK.activeOptions}"
filterMatchMode="exact" width="30">
<h:outputText value="#{item1.active}" />
</p:column>
</p:dataTable>
Right now this code doesn't work, the contextMenu is never updated on rowSelect (the menu item 'Inactive' is always enabled). I guess the right click event on a specific row to display the menu doesn't really trigger the rowSelect event even if the row gets highlighted.
What is the proper way to do that?
I ended up using this solution from PF forum:
<p:contextMenu for="ratingScaleTable" id="RsContextMenuId" widgetVar="ctxMenu" beforeShow="return true;">
<p:dataTable id="ratingScaleTable" widgetVar="tableWidget"
...
<p:ajax event="rowSelect" process="ratingScaleTable" listener="#{ratingScaleBK.edit}" update=":templateForm:tabView, :templateForm:dirtyFlag, :templateForm:tabView:RsContextMenuId" />
<p:ajax event="contextMenu" update=":templateForm:tabView:RsContextMenuId" oncomplete="ctxMenu.show(currentEvent);"/>
and the associated JavaScript:
<script type="text/javascript">
var currentEvent;
$(document).ready(function() {
PrimeFaces.widget.ContextMenu.prototype.show = function(e) {
//hide other contextmenus if any
$(document.body).children('.ui-contextmenu:visible').hide();
if(e) {
currentEvent = e;
}
var win = $(window),
left = e.pageX,
top = e.pageY,
width = this.jq.outerWidth(),
height = this.jq.outerHeight();
//collision detection for window boundaries
if((left + width) > (win.width())+ win.scrollLeft()) {
left = left - width;
}
if((top + height ) > (win.height() + win.scrollTop())) {
top = top - height;
}
if(this.cfg.beforeShow) {
this.cfg.beforeShow.call(this);
}
this.jq.css({
'left': left,
'top': top,
'z-index': ++PrimeFaces.zindex
}).show();
e.preventDefault();
};
});
</script>
Try it with the contextMenu event:
<p:contextMenu for="ratingScaleTable" id="RsContextMenuId" widgetVar="ctxMenu">
...
</p:contextMenu>
<p:dataTable ... >
...
<p:ajax event="contextMenu" process="ratingScaleTable" listener="#{ratingScaleBK.edit}" update=":templateForm:tabView, :templateForm:dirtyFlag, :templateForm:tabView:RsContextMenuId" oncomplete="PF('ctxMenu').show();" />
...
</p:dataTable>
Related
I have a data table displying some application parameters having 3 columns:
name (outputext),
value (p:cellEditor) and
edit (p:rowEditor used)
On clicking edit button in any row value field converts into input field and is having validator attached. After changing and accepting( clicking check icon) values an 'update button' is provided at the bottom of page to save all changes.
My problem is if a validation error comes and we press 'update button' then call goes to save function in managed bean with old value. So to stop this I want to disable 'update button' when any row is having edit mode opened. Can I check the mode of all cell editors in column 2 , so I will use that in disabled attribute of update button.
Please do suggest any other better way is also possible ?
Using a jsf 2.1 and primefaces 3.5
XHTML snippet
<!-- Body panel for display of individual configuration mode -->
<p:panel id="mainConfigPanel" >
<!-- status message section -->
<p:messages id="msg" autoUpdate="true" closable="true"/>
<!-- Parameter configuration mode -->
<p:panel
rendered="#{configMBean.configUtility.configParamModeOn}"
styleClass="panelNoBorder">
<p:dataTable id="configParamTable" var="configParamVar"
value="#{configMBean.configParamList}" editable="true">
<p:ajax event="rowEdit" listener="#{configMBean.onRowEdit}" update=":mainForm:msg" />
<p:ajax event="rowEditCancel" listener="#{configMBean.onRowCancel}" update=":mainForm:msg" />
<p:column headerText="Parameter Name" sortBy="#{configParamVar.paramConfigName}">
<h:outputText id="paramNameId" value="#{configParamVar.paramConfigName}" />
</p:column>
<p:column headerText="Param Value" sortBy="#{configParamVar.paramConfigValue}">
<p:cellEditor>
<f:facet name="output" > <h:outputText value="#{configParamVar.paramConfigValue}" /> </f:facet>
<f:facet name="input">
<p:inputText id="paramValueId" value="#{configParamVar.paramConfigValue}" required="true"
validator="#{configMBean.validateParam}" >
<f:validateLength maximum="2000" />
<f:attribute name="input" value="#{configParamVar}" />
</p:inputText>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Edit" style="text-align:center;vertical-align:top;width:20px">
<p:rowEditor />
</p:column>
</p:dataTable>
<h:panelGrid columns="2" >
<p:commandButton value="Update Parameters" actionListener="#{configMBean.saveParamUpdate}" update=":mainForm" />
<p:commandButton value="Cancel" actionListener="#{configMBean.cancelParamUpdate}" immediate="true" update=":mainForm">
</p:commandButton>
</h:panelGrid>
</p:panel>
<!-- End of Parameter configuration mode panel -->
</p:panel>
<!-- End of body panel for individual configuration mode -->
</p:panelGrid>
<!-- end of main panel -->
Functions in Managed Bean
public void onRowEdit(RowEditEvent event) {
System.out.println(" In Row Edit");
}
public void onRowCancel(RowEditEvent event) {
System.out.println("In Row Canel of Parameter Config");
}
public void validateParam(FacesContext facesContext, UIComponent component,
Object value) throws ValidatorException, Exception {
if (value != null) {
//Getting parameter Name and Value for validation
String paramName = ((RowEntity) component.getAttributes().get("input")).getParamConfigName();
String paramValue = (String) value;
FacesMessage msg = null;
//Validation Cases
if (paramName.equalsIgnoreCase(ResourceBundle.getMsg("Param_Enable_FTP"))) {
if (!paramValue.equalsIgnoreCase("true") || !paramValue.equalsIgnoreCase("false")) {
msg = new FacesMessage(FacesMessage.SEVERITY_WARN, ResourceBundle.getMsg("Param_True_False_Validation")+ paramName, "");
throw new ValidatorException(msg);
}
} else if (paramName.equalsIgnoreCase(ResourceBundle.getMsg("Param_Contingency_Reserve"))) {
if (!Pattern.matches("-?\\d*\\.?\\d*", paramValue)) {
msg = new FacesMessage(FacesMessage.SEVERITY_WARN, ResourceBundle.getMsg("Param_Number_Validation") + paramName, "");
throw new ValidatorException(msg);
}
}// end if else if
}
}
From the docs: There is an Ajax Behavior Event for rowEdit
rowEdit | org.primefaces.event.RowEditEvent | When a row is edited.
You could disable the update button when the RowEditEvent got fired and release the button after the row editing was canceled or saved.
I Hope I got your question right and this helps.
This question already has an answer here:
Why do I need to nest a component with rendered="#{some}" in another component when I want to ajax-update it?
(1 answer)
Closed 7 years ago.
I thought this would be easy but I just cannot get it. I have a drop down and based on selection, I should be able to show/Hide another drop down based on a boolean. By default the boolean is false and only when it is true should the second drop down be rendered:
My page:
<h:outputLabel value="Select Report: "/>
<p:selectOneMenu value="#{daily.reportname}" id="sector" style="width: 250px;">
<f:selectItem itemLabel="ALL" itemValue="ALL" />
<f:selectItems value="#{daily.reportType()}"/>
<p:ajax event="change" update="branchrender" listener="#{daily.selectedReport()}" />
</p:selectOneMenu>
<h:panelGroup id="branchrender" rendered="#{daily.showBranchDimension}">
<h:outputText value="Branch" />
<p:selectOneMenu value="#{accounts.branchs}" id="branch" style="width: 250px;">
<f:selectItem itemLabel="ALL" itemValue="ALL" />
<f:selectItems value="#{dimensions.branchCode()}"/>
</p:selectOneMenu>
</h:panelGroup>
My selected report Method:
public void selectedReport() {
if (reportname.startsWith("cust_")) {
custrepname = reportname;
useBranch = pr.getCustRepProperties(custrepname + ".bi").getProperty("bi.useBranchDim");
showBranchDimension = useBranch.equalsIgnoreCase("true");
System.out.println("HERE: " + showBranchDimension);
} else {
custrepname = null;
}
}
showBranchDimension is a boolean having getter and setter:
public boolean isShowBranchDimension() {
return showBranchDimension;
}
public void setShowBranchDimension(boolean showBranchDimension) {
this.showBranchDimension = showBranchDimension;
}
Am I missing something? The System.out.println prints true but the component is NOT rendered.
You have to make the rendered component a rendered free because it must be exist when you submit the ajax request to server add another container to branchrender and move the rendered id to it
<h:panelGroup id="branchrender">
<h:panelGroup rendered="#{daily.showBranchDimension}">
<h:outputText value="Branch" />
<p:selectOneMenu value="#{accounts.branchs}" id="branch" style="width: 250px;">
<f:selectItem itemLabel="ALL" itemValue="ALL" />
<f:selectItems value="#{dimensions.branchCode()}"/>
</p:selectOneMenu>
</h:panelGroup>
</h:panelGroup>
See more about this.
I think problem could be with the way your implemented the p:ajax component. See the comments of p:ajax listener method not invoked.
I am using PF 5.0, JSF 2.0 (Mojarra), Spring Webflow 2.3. I am facing multiple issues with the Datatable Lazy loading.
a.) When I try to have Multiple Select for Columns with Lazy Data Model for the DataTable component, When I enable single select for Data table , it works fine .
b.) Another issue that I am facing with the Datatable is that I am unable to load dynamic columns with Lazy Data table , It used to work fine for the non-Lazy version.
Any suggestions to resolve these issues are welcome. Please find the code below.
<p:dataTable id="docsTable" var="document"
value="#{datasource}" lazy="true" paginator="true" dynamic="true"
rows="#{searchActionBean.maxRows}" paginatorTemplate="{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="10,25,50,100" rowKey="#{document.ID}"
sortMode="single" resizableColumns="true" scrollable="true" scrollHeight="350" >
<f:facet name="header">
<p:toolbar>
<f:facet name="left">
<p:commandButton type="button" title="Print" icon="ui-icon-print" />
<span class="ui-separator">
<span class="ui-icon ui-icon-grip-dotted-vertical" />
</span>
<p:commandButton id="reptoggler" value="Reports" action="reportsAction" icon="ui-icon-note">
<f:param name="stdReportName" value="reportsMain" />
</p:commandButton>
</f:facet>
<f:facet name="right">
<h:outputText value="#{searchActionBean.domainName}" />(<h:outputText value="#{searchActionBean.resultCount}" />)
<span class="ui-separator">
<span class="ui-icon ui-icon-grip-dotted-vertical" />
</span>
<h:commandLink>
<img src="${request.contextPath}/images/excel.png" width="15" height="15" />
<p:dataExporter type="xls" target="docsTable" fileName="documents" />
</h:commandLink>
<span class="ui-separator">
<span class="ui-icon ui-icon-grip-dotted-vertical" />
</span>
<h:commandLink>
<img src="${request.contextPath}/images/pdf.png" width="15" height="15"/>
<p:dataExporter type="pdf" target="docsTable" fileName="documents" />
</h:commandLink>
<span class="ui-separator">
<span class="ui-icon ui-icon-grip-dotted-vertical" />
</span>
<p:commandButton id="toggler" type="button" value="Columns" icon="ui-icon-calculator" />
<p:columnToggler datasource="docsTable" trigger="toggler" />
</f:facet>
</p:toolbar>
</f:facet>
<p:column selectionMode="multiple" style="text-align:center; width:25px">
<f:facet name="header">
<h:outputText value="Select" />
</f:facet>
</p:column>
<p:columns value="#{searchResultsColumns}" var="column" styleClass="wrap" width="#{column.width}" columnIndexVar="colIndex" sortBy="#{document[column.pfResColumnName]}" filterBy="#{document[column.pfResColumnName]}">
<f:facet name="header">
<h:outputText value="#{column.displayResultColumnName}" />
</f:facet>
<h:outputText value="#{document[column.pfResColumnName]}" rendered="#{column.resColumnType eq 'DATE'}">
<f:convertDateTime pattern="MM/dd/yyyy" />
</h:outputText>
<h:outputText value="#{document[column.pfResColumnName]}" rendered="#{column.resColumnType eq null}" />
<h:outputText value="#{document[column.pfResColumnName]}" rendered="#{column.resColumnType eq 'SPL'}">
<f:converter converterId="gov.nih.nci.ctep.idart.converters.SplConverter"></f:converter>
</h:outputText>
</p:columns>
</p:dataTable>
And the Bean code, I have verified that the Collections searchResultColumns is not empty.
public class SearchActionBean extends LazyDataModel<DocumentResultDTO> implements Serializable
{
private List<DocumentResultDTO> datasource;
#Override
public DocumentResultDTO getRowData(String rowKey) {
for (DocumentResultDTO doc : datasource) {
if (doc.getID().equals(rowKey))
return doc;
}
return null;
}
#Override
public Object getRowKey(DocumentResultDTO doc) {
return doc.getID();
}
#Override
public List<DocumentResultDTO> load(int first, int pageSize, String sortField,
SortOrder sortOrder, Map<String, Object> filters) {
datasource = new ArrayList<DocumentResultDTO>();
/*this.execute();*/
commonQueriesLocal = ejbService.getCommonQueriesLocal();
srchDelegate = new SearchDelegate();
super.setSearchDelegate(srchDelegate);
try
{
//Set the visibility of all the columns depending on the JQuery table visibility setting from the client side
String invisibleColNames = request.getParameter("invisibleColNames");
ArrayList<UserResultColumnDTO> dispCols = getDisplayColumns();
ApplicationUtils.markVisibilityForColumns(dispCols,invisibleColNames);
int iSortColumnIndex = 1;
String sSortDirection = sortOrder.toString().equalsIgnoreCase("ASCENDING") ? "asc" : "desc";
if(request.getParameter("iSortCol_0") != null)
iSortColumnIndex = Integer.parseInt(request.getParameter("iSortCol_0"));
Query query =
(Query) request.getSession().getAttribute(IdartWebGlobalConstants.USER_QUERY);
if(request.getSession().getAttribute("executeSavedQuery") != null &&
request.getSession().getAttribute("executeSavedQuery").toString().equalsIgnoreCase("true")
)
pageSize = query.getUserQuery().getPageCount();
else
query.getUserQuery().setPageCount(pageSize);
query.getUserQuery().setSortOrder(sSortDirection);
setDataSortColumn(iSortColumnIndex, getDomainNameToSetSortColumn(query.getName()), query);
performNavigation(pageSize, first);
// Save the query object in session
if(getDomainName().equalsIgnoreCase("DOCUMENTS"))
{
setSearchResults((ArrayList)request.getAttribute("documentResults"));
setSearchResultsColumns(dispCols);
}
System.out.println("search Result "+searchResults.size());
System.out.println("search Columns "+dispCols.size());
// process on filters to be displayed
customizeFilterResults();
}
catch(Exception ex)
{
log.error("-- GetData Method Error "
+ ex.getMessage()
+ " --", ex);
}
datasource= getSearchResults();
System.out.println("first "+first+" pageSize "+pageSize+" sortField "+sortField+" sortOrder "+sortOrder);
System.out.println("searchResultsColumns"+datasource);
System.out.println("searchResultsColumns "+searchResultsColumns);
System.out.println("GET searchResultsColumns "+getSearchResultsColumns());
// rowCount
int dataSize = datasource.size();
this.setRowCount(Integer.parseInt(getResultCount()));
return datasource;
}
}
Look at the console and see if you see any errors. Lazy Loading in early versions of PrimeFaces (2.0) seems to break certain PrimeFaces tooling (like ToolTips).
I was able to fix this by importing JQuery UI after loading the lazy loaded section (i.e inside the <tab> of a lazy loaded <tabView>):
<script src='${request.contextPath}/components/jquery/jquery-ui.js'></script>
In my application I have a <p:dataTable> with pagination using lazy datamodel.
I have a requirement when I click another page button from a page, a confirmation popup should generate, if I click yes then I can go to another page and if I click 'no' then I can't go to another page and I will stay in that current page.
.xhtml code are given below:
<h:form id="userListForm">
<p:dataTable var="user" id="userTable" value="#{userListController.userDataModel}" lazy="true" paginator="true" rows="25" paginatorPosition="bottom"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="25,50,100" widgetVar="userDataTable" styleClass="userTable" selectionMode="single" >
<p:ajax event="page" />
<p:column id="nameColumn" headerText="#{adbBundle['name']}"
sortBy="#{user.fullName}" filterBy="#{user.fullName}" styleClass="userName">
<h:outputText value="#{user.fullName}" />
</p:column>
<!-- other columns -->
<:/p:dataTable>
</h:form>
I am using primefaces 3.4, jsf 2.0.
Inspired from RongNK's answers, you may simply do this,
add this script block :
<script type="text/javascript">
function onPageStart() {
return confirm('Are you sure?');
}
</script>
and put this in your datatable :
<p:ajax event="page" onstart="return onPageStart()" />
You could also inline it in the <p:ajax this way :
<p:ajax event="page" onstart="return confirm('Are you sure?');" />
Tested and working with PrimeFaces 3.4.2
Did you try:
<p:ajax event="page" onstart="return tests()"/>
<script type="text/javascript">
var vpage = 1;
var prevvalue = vpage;
function tests(){
if(confirm('Are you sure?')){
var p = userDataTable.getPaginator();
vpage = p.getCurrentPage();
prevvalue = vpage;
return true;}
else {
var p = userDataTable.getPaginator();
p.setPage(prevvalue,true);
return false;}
}
</script>
Is there any way to clear the date selection using prime faces calendar?
<p:calendar pattern="MM/dd/yyyy" navigator="true" id="endDate" for="endDate"
readonlyInput="true" mindate="#{manageMarketingProgramsBean.currentDate}" showOn="button">
<f:convertDateTime pattern="MM/dd/yyyy" timeZone="America/New_York" />
</p:calendar>
I have readonlyInput="true" because I dont want user to type the date. I force them to pick the date from the calendar, there needs to be another way to provide user the ability to clear the date selected. Please let me know how can I achieve this?
The first approach that comes into my mind would be:
<p:calendar readonlyInput="true" widgetVar="calendarWidget"/>
<p:commandButton value="Reset" onclick="calendarWidget.setDate(null)"/>
This worked for me
<p:calendar widgetVar="calendarWidget" pattern="MM/dd/yyyy" />
<p:commandButton value="Reset" onclick="PF('calendarWidget').setDate(null)"
type="button" />
Primefaces for the calendar component have this property: showButtonBar.
If you set it to true like this:
<p-calendar
appendTo="body"
formControlName="someControl"
id="someID"
[maxDate]="someMaxDate"
[showButtonBar]="true"
[showIcon]="true"
></p-calendar>
Then it will display two buttons on the calendar component. Today and Clear.
Hope it helps somebody.
HTML
<p:calendar
yearRange="c-100:c+100"
readonlyInput="true"
pattern="dd/MM/yyyy"
id="identity"
navigator="true"
mindate="today"
widgetVar="dateWidget"
value="#{bean.fieldname}"
/>
JS
function name() {
var mainID = prefix + collpaseID;
-
-
-
-
clearCalendar(mainID,event);
}
function clearCalendar(collapseId) {
try {
allElements =
document.getElementById(collapseId).getElementsByClassName('hasDatepicker');
for (i = 0, n = allElements.length; i < n; ++i) {
allElements[i].setAttribute('onkeyup',
'clearDate("'+allElements[i].id+'", event)');
}
}
catch(e) {}
}
function clearDate(fieldID, e) {
try{
// 8 - backspace key, 46 - delete key
if(e.keyCode == 8 || e.keyCode == 46) {
//PF(getWidgetVarById(collapseId)).setDate(null);
document.getElementById(fieldID).value="";
}
}
catch(e){}
}
<p:calendar
widgetVar="calendarWidgetStart"
/>
<p:calendar
widgetVar="calendarWidgetEnd"
/>
<p:commandLink
value="Action"
action="#{entity.action}"
onclick="setTimeout('remoteCommand();', 100);"
/>
<p:remoteCommand
name="remoteCommand"
update="#form"
onstart="clearCalendarWidget();"
/>
<script>
function clearCalendarWidget() {
$( PF('calendarWidgetEnd').setDate(null) );
$( PF('calendarWidgetStart').setDate(null) );
}
</script>