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.
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.
I'm trying to create a ModalPanel from a dataTable (RichFaces 4.5.1, MyFaces 2.2.6, Spring 3.1.1, Tomcat 7.0.27) but I can't.
The modalPanel has values to be displayed based on the selected row in the table. When I click in a commandLink, trigger a actionListener should feed these values (localidadeMB.carregarColecoes()), but it does't work, because the reference to attributes of bean is null (has not been set by the f:setPropertyActionListener located in commandLink).
What was missing?
*page.xhtml
(...)
<f:view>
<h:form id="formConsulta">
<rich:dataTable id="tabela"
value="#{localidadeMB.getLocalidadesPorPalavra()}" var="loc"
rowKeyVar="row" rows="20" width="800px" render="scroller">
<rich:column>
(...)
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value=""/>
</f:facet>
<a4j:commandLink id="editlink" ajaxSingle="true"
oncomplete="#rich:component('modalEditarLocalidade')}.show()"
actionListener="#{localidadeMB.carregarColecoes}"
render="modalEditarLocalidade">
<h:graphicImage value="/img/edit.png"/>
<f:setPropertyActionListener value="#{loc}" target="#{localidadeMB.localidade}" />
</a4j:commandLink>
</rich:column>
</rich:dataTable>
</h:form>
<ui:include src="modalPanel.xhtml" />
*modalPanel.xhtml
<ui:composition>
<rich:popupPanel id="modalEditarLocalidade" autosized="true"
modal="false" resizable="false">
<f:facet name="header">
<h:outputText value="Alterar localidade" />
</f:facet>
<f:facet name="controls">
<h:graphicImage id="modalClosePNG2" value="/img/close1.png"
style="cursor:default;"
onclick="Richfaces.hideModalPanel('modalEditarLocalidade')" />
</f:facet>
<h:form>
<h:outputLabel value="Nome da localidade:" for="nomeLocalidade" />
<h:inputText id="nomeLocalidade"
value="#{localidadeMB.localidade.nome}" required="true"
immediate="true"/>
</h:inputText>
</h:form>
</rich:popupPanel>
</ui:composition>
*ManagedBean
private Localidade localidade;
public void setLocalidade(Localidade l){
this.localidade = l;
}
public void carregarColecoes(ActionEvent action){
System.out.println(localidade.getNome());
***** print NULL *****
}
If you want to set up a variable first and then execute a method you have to use #action for that method, actionListeners are executed first but since both of your methods are actionListeners the localidadeMB.carregarColecoes is executed before the variable is set. (And btw. h:commandLink has no "ajaxSingle" or "oncomplete" attributes.)
With the suggestion of Makhiel and this link I decided.
The xhtml looked like this:
<a4j:commandLink id="editlink" ajaxSingle="true"
oncomplete="#{rich:component('modalEditarLocalidade')}.show()"
action="#{localidadeMB.carregarColecoes}"
render="modalEditarLocalidade">
<h:graphicImage value="/img/edit.png"/>
<f:setPropertyActionListener value="#{loc}"
target="#{localidadeMB.localidade}" />
</a4j:commandLink>
and ManagedBean like this:
public String carregarColecoes(){
(....)
}
I am working with jsf 2.0 et Primefaces. i have a selectOneMenu that have dynamic values of datas that correspond to the user connected. I want that when i choose a data and click on the button view the list of emails related to the data selected will be shown on the dataTable.
<p:panel>
<p:selectOneMenu id="data" value="#{mailMB.database}" styleClass="auto" required="true" effect="fade" >
<f:selectItem itemLabel="Select Data" itemValue="" />
<f:selectItems value="#{dataMB.datas}" var="data" itemLabel="#{data.keyword}" itemValue="#{data.keyword}"/>
</p:selectOneMenu>
<p:commandButton value="View" action="#{mailMB.grabemails()}" ajax="true" update="datas" icon="ui-icon-circle-check" styleClass="ui-priority-primary" />
</p:panel>
<p:panel id="panelform" header="Emails List" >
<p:dataTable value="#{mailMB.emailsByData}" var="item" id="datas" rowsPerPageTemplate="5,10,15,20,25,30"
paginator="true" rows="10"
selectionMode="single" filteredValue="#{mailMB.filteredMails}" rowKey="#{item.id}"
selection="#{mailMB.selectedMail}">
<p:ajax event="rowSelect" update=":form:dataView , :form:confirmDelete, :form:viewButton" listener="#{dataMB.onRowSelect}"/>
<p:ajax event="rowToggle" />
<p:column style="width:2%" exportable="false">
<p:rowToggler />
</p:column>
<p:column sortBy="#{item.email}" filterBy="#{item.email}">
<f:facet name="header">
<h:outputText value="Email"/>
</f:facet>
<h:outputText value="#{item.email}"/>
</p:column>
</p:dataTable>
</p:panel>
and this is my method in the managed Bean that returns the list of emails by data using the named query:
public List<Email> getEmailsByData() {
System.out.println("the database" + getDatabase());
return emailsByData = mailBusinessLocal.mails(getDatabase());
}
public List<Email> grabemails() {
return emailsByData = mailBusinessLocal.mails(database);
}
when i choose a data and click view nothing happens and the databate return null as it shown on the glassfish log.
You need to put your <p:selectOneMenu> inside a <h:form>. That's my first guess.
I'm having problems with a form that is rendered by a booleanButtom on PrimeFaces 3.5
the form appear as expected but when I commit the values of the field come null.
The code of the pag:`
<p:panelGrid>
<p:row>
<p:column>
<h:form id="city">
<p:panelGrid columns="2">
<h:outputText value="Name: "/>
<p:inputText label="Name" value="#{managedBean.city.name}"/>
<h:outputText value="Status: "/>
<p:selectBooleanButton value="#{managedBean.city.status}" onLabel="Enable" offLabel="Disable">
<p:ajax listener="#{managedBean.changeStatusCity()}"/>
</p:selectBooleanButton>
<h:outputText value="Add neighborhood?"/>
<p:selectBooleanButton id="btAddNeighborhood" value="#{managedBean.addNeighborCity}" onLabel="Cancel" offLabel="Yes">
<p:ajax update=":addNeighbor" listener="#{managedBean.addNeighborCity()}"/>
</p:selectBooleanButton>
</p:panelGrid>
</h:form>
</p:column>
</p:row>
<p:row>
<p:column>
<h:form id="addNeighbor">
<p:panel header="Neighborhood" rendered="#{managedBean.addNeighborCity}">
<p:panelGrid columns="2">
<h:outputText value="Name: "/>
<p:inputText label="Name" value="#{managedBean.neighborhood.name}"/>
<h:outputText value="Status: "/>
<p:selectBooleanButton value="#{managedBean.neighborhood.status}" onLabel="Enable" offLabel="Disable" onIcon="ui-icon-check" offIcon="ui-icon-close">
<p:ajax listener="#{managedBean.changeStatusNeighbor()}"/>
</p:selectBooleanButton>
</p:panelGrid>
</p:panel>
</h:form>
<h:form id="formBt">
<p:commandButton id="bt" value="Add" actionListener="#{managedBean.saveNeighborCity()}" update=":addNeighbor, :city:btAddNeighborhood"/>
</h:form>
</p:column>
</p:row>
</p:panelGrid>`
And the manage bean
public void addNeighborCity(){
if(addNeighborCity){
neighborhood = new Neighborhood();
neighborhood .setStatus(true);
neighborhood .setStringStatus("Enable");
}else{
neighborhood = null;
}
}
public void changeStatusNeighbor() {
if (neighborhood .isStatus()) {
neighborhood .setStringStatus("Enable");
} else {
neighborhood .setStringStatus("Disable");
}
}
public void saveNeighborCity(){
city.getNeighborhoods().add(neighborhood );
neighborhood = null;
addNeighborCity = false;
}
All the input inside of the form that was rendered doesn't send the information to the manage bean and when I put the button that add the neighbor to the list of the city the button stop working and doesn't call the manage bean any more.
Does someone knows what I'm doing wrong or what is happening.
I'm using Primefaces3.5, GlassFish4.0 and JSF2.2
As you did not post the whole managed bean, I guess that you're using the default scope of the managed bean: #RequestScoped. In that case you should use #ViewScoped.
I solved the problem, I was using glassfish 4 and it forces the jsf2.2 even when you put the jsf2.1 in our project, then I changed to glassfish 3 and all work just fine, thanks for the answers, and I'm using #ScopeSession.
I have a view scoped arrayList as bean. This is used to display the editable columns of dataTable. When the page is displayed initially and I try to update the table contents the update works fine, however when I try to update any column the second time the values which are changed do not reflect in the arrayList bean (verified in the action method using break point). The action method is also a managed bean with view scope.
<managed-bean>
<managed-bean-name>financialListBean</managed-bean-name>
<managed-bean-class>java.util.ArrayList</managed-bean-class>
<managed-bean-scope>view</managed-bean-scope>
</managed-bean>
Below is the code for dataTable
<h:form id="myform">
<h:dataTable id="financialListBean1"
value="#{financialListBean}" var="varfinancialListBean"
styleClass="dataTableEx" headerClass="headerClass"
footerClass="footerClass"
rowClasses="rowClass1, rowClass2"
columnClasses="columnClass1" border="0" cellpadding="2"
cellspacing="0">
<h:column id="columnEx17">
<h:selectBooleanCheckbox styleClass="inputRowSelect"
id="rowSelect3"
value="#{varfinancialListBean.rowSelected}"></h:selectBooleanCheckbox>
<f:facet name="header"></f:facet>
</h:column>
<h:column id="amount1column">
<f:facet name="header">
<h:outputText styleClass="outputText" value="Amount"
id="amount1text"></h:outputText>
</f:facet>
<h:inputText styleClass="small8Input" id="amount1"
value="#{varfinancialListBean.amount}" onkeypress="return only5DigitsEntry(this, event);" onkeyup="return checkRequiredFieldsForUpdateFinancialBtn(this.form, event);">
</h:inputText>
</h:column>
<h:column id="type1column">
<h:selectOneMenu styleClass="selectOneMenu" id="menu1" value="#{varfinancialListBean.type}">
<f:selectItem itemLabel="M" itemValue="M" />
<f:selectItem itemLabel="Y" itemValue="Y" />
<f:selectItem itemLabel="Z" itemValue="Z" />
<f:selectItem itemLabel="O" itemValue="O" />
<f:selectItem itemLabel="S" itemValue="S" />
</h:selectOneMenu>
<f:facet name="header">
<h:outputText styleClass="outputText" value="Type"
id="type1text"></h:outputText>
</f:facet>
</h:column>
<h:column id="recDate1column">
<f:facet name="header">
<h:outputText styleClass="outputText"
value="Recieve Date" id="recDate1text"></h:outputText>
</f:facet>
<h:inputText styleClass="outputText" id="recDate1"
value="#{varfinancialListBean.recDate}"
onclick="getClock($(this).attr('id'))" >
<f:convertDateTime pattern="MMM d, yyyy"/>
</h:inputText>
</h:column>
</h:dataTable>
<h:commandButton type="submit"
value="Update Financial Information"
styleClass="commandExButton" id="updateFinancialBtn"
action="#{pc_SocialServicesView.doFinancialUpdateBtnAction}">
<f:param name="mrn" value="#{pc_SocialServicesView.mrn}" />
</h:commandButton>
</h:form>
The action method:
public String doFinancialUpdateBtnAction() {
System.out.println("I am at doFinancialUpdateBtnAction");
try{
if(mrn.length()==0){
mrn=getFacesContext().getExternalContext().getRequestParameterMap().get("mrn");
}
setFinancialListBean(dba.updateFinancialAsistance
(getFinancialListBean(), mrn));
setErrorMsgBean("Updated successfully ...");
doInit(mrn);
}catch (Exception e) {
System.out.println("There is an exception at doFinancialUpdateBtnAction");
Log.out.error("Error in doFinancialUpdateBtnAction: "+e);
setErrorMsgBean("No record was updated ...");
e.printStackTrace();
}
return "";
}