11 Replies Latest reply on Jul 10, 2010 6:00 AM by Milo van der Zee

    <a4j:commandButton> didnt work after some time

    Elena Veretilo Newbie

      Hi all! I need your brilliant minds again)

       

      There is a problem: I get the <rich:modalPanel> with <a4j:commandButton> (this button save the value), and it works fine if I go to the page first. But if I go th that page twice or after some time this button doesn't work. What I do wrong?

       

      Here is the code of page and my bean:

       

       

       

       

      /**
       * 
       */
      package no.sfront.sales;
      
      import java.util.Calendar;
      import java.util.List;
      import java.util.Set;
      import java.util.HashSet;
      import java.util.Date;
      import java.util.Collections;
      
      import javax.faces.application.FacesMessage;
      import javax.faces.context.FacesContext;
      import javax.faces.event.ActionEvent;
      import javax.faces.event.ValueChangeEvent;
      import javax.faces.model.SelectItem;
      
      import no.sfront.torque.generated.StoreSales;
      
      /**
       * @author Elena Veretilo
       *
       */
      public class SetStoreSalesBean 
      {
           public final static int LAST_YEAR = 1950;
            
           private List<SelectItem> companyDepartments;
           private List<SelectItem> departmentStores;
           private List<StoreSales> storeSales;
           private StoreSales selectedStoreSale;
           private int currentDepartment;
           private int currentStore;
           private Date currentDate;
           private Double currentStoreValue;
           private Double currentStoreBudget;
           private StoreSalesUtils storeSalesUtils;
           private Calendar calendar;
           private boolean addNewValueVisible;
           private int storeSalesSize;
           private Set <Integer>rowsToUpdate;
                    
           // Constructor
           public SetStoreSalesBean() 
           { 
                storeSalesUtils = StoreSalesUtils.getInstance();
                this.companyDepartments = storeSalesUtils.createCompanyDepartmentsList();
                this.departmentStores = storeSalesUtils.createDepartmentStoresList(1);
      //          this.storeSales = storeSalesUtils.createStoreValuesList(1);
      //          this.storeSales.clear();
                
                this.addNewValueVisible = false;
                this.rowsToUpdate =  new HashSet<Integer>();
                
                this.calendar = Calendar.getInstance();
                this.currentDate = this.calendar.getTime();
           }
           
           public static SetStoreSalesBean getInstance() {
                FacesContext facesContext = FacesContext.getCurrentInstance();
      
                return (SetStoreSalesBean) facesContext.getApplication()
                          .getELResolver().getValue(facesContext.getELContext(), null,
                                    "setStoreSalesBean");
           }   
             
           public void saveStoreSales(ActionEvent event)
           { 
                Calendar c = Calendar.getInstance();
              c.setTime(this.currentDate);
              
                int diff = c.get(Calendar.YEAR) - LAST_YEAR;
                System.out.println("diff = " + diff + "; this.calendar.YEAR = " + c.get(Calendar.YEAR));
                
                int currMonth = diff * 12 + (c.get(Calendar.MONTH) + 1);
                System.out.println("currMonth = " + currMonth + "; (c.get(Calendar.MONTH) + 1) = " + (c.get(Calendar.MONTH) + 1));
                
                Double currValue = this.getCurrentStoreValue();
                Double currBudget = this.getCurrentStoreBudget();
                int storeId = this.getCurrentStore();
                
                storeSalesUtils.saveStoreSales(storeId, currMonth, currValue, currBudget);
                
                this.storeSales = null;
                this.storeSales = storeSalesUtils.createStoreValuesList(storeId);
                this.storeSalesSize = this.storeSales.size();
                
                this.setAddNewValueVisible(false);
                  
                this.clear(event);
           }   
              
           public void updateStoreSales(ActionEvent event)
           {    
                this.selectedStoreSale.setValue(this.currentStoreValue);
                this.selectedStoreSale.setBudgetValue(this.currentStoreBudget);
                storeSalesUtils.updateStoreSales(this.selectedStoreSale);
                rowsToUpdate = Collections.singleton(storeSales.indexOf(this.selectedStoreSale));
      
      /*          
      //           for updating all rows if needed
                for (int i = 0; i < this.storeSales.size(); i++) 
                {
                     storeSalesUtils.updateStoreSales(this.storeSales.get(i));
                }
                
                this.storeSales = null;
                this.storeSales = storeSalesUtils.createStoreValuesList(this.getCurrentStore());
                this.storeSalesSize = this.storeSales.size();
      */          
                this.setCurrentStoreValue(0.0);
                this.setCurrentStoreBudget(0.0); 
           }
            
           public void changeStoreSale(ActionEvent event)
           {   
                this.currentStoreValue = this.selectedStoreSale.getValue(); 
                this.currentStoreBudget = this.selectedStoreSale.getBudgetValue(); 
           }
           
           public void addNewValue(ActionEvent event)
           {  
                this.setAddNewValueVisible(true);
                System.out.println("this.addNewValueVisible = " + this.addNewValueVisible);
           }      
           
           public void clear(ActionEvent event)
           {   
                this.setCurrentStoreValue(0.0);
                this.setCurrentStoreBudget(0.0);
      //          this.setAddNewValueVisible(false);
           }        
             
           public void loadCurrentDepartment(ValueChangeEvent event){
                Integer id = (Integer)event.getNewValue(); 
                System.out.println("--------- departmentId = " + id);
                this.setCurrentDepartment(id);
                
                this.departmentStores = null;
                this.departmentStores = storeSalesUtils.createDepartmentStoresList(id);
                
                this.storeSales = null;
           }  
           
           public void loadCurrentStore(ValueChangeEvent event){
                Integer id = (Integer)event.getNewValue(); 
                System.out.println("--------- storeId = " + id);
                this.setCurrentStore(id);
                
                this.storeSales = null;
                this.storeSales = storeSalesUtils.createStoreValuesList(id);
                this.storeSalesSize = this.storeSales.size();
           }     
           
           public void loadCurrentDate(ValueChangeEvent event){
                Date tempDate = (Date)event.getNewValue(); 
                this.setCurrentDate(tempDate); 
           }
      }
      
        • 1. Re: <a4j:commandButton> didnt work after some time
          Milo van der Zee Newbie

          Hello,

           

          what do you mean with "does not work"? Is the backend called or doesn't the button do anything?

           

          Milo

          • 2. Re: <a4j:commandButton> didnt work after some time
            Elena Veretilo Newbie

            Hi! Thanks for quick reply!

             

            After some time, when we click on this button the actionListener method doesn't wake up. So I suppose that the event doesnt occur. Why? And what should I do? How I need to change my code?

            • 3. Re: <a4j:commandButton> didnt work after some time
              Milo van der Zee Newbie

              Ok, then it has nothing to do with your backend and the code shown. From the little knowledge of your situation I have I would say that it has to do with some refreshing of the page. Please submit your jsf file.

              • 4. Re: <a4j:commandButton> didnt work after some time
                Elena Veretilo Newbie

                Couldn't add the jsf page - doesnt appear in reply.

                I will try to paste it by parts

                 

                1)

                 

                <ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:a4j="http://richfaces.org/a4j"
                xmlns:rich="http://richfaces.org/rich"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:fc="http://www.fusioncharts.com"
                xmlns:t="http://myfaces.apache.org/tomahawk"
                xmlns:jsp="http://java.sun.com/jsp/jstl/core"
                template="template.xhtml">
                <ui:define name="title">Set Store Sales Page</ui:define>
                <ui:define name="content">

                <style type="text/css">
                .special tr[id]{
                display:none;
                }
                </style>

                 

                <h:form id="setStoreSalesForm">
                <h:outputText value="Save store sales value"/><br/><br/><br/>
                <div style="width: 700px;">
                <rich:comboBox id="selectDepartmentBox" value="#{setStoreSalesBean.currentDepartment}" defaultLabel="Select a department" style="width: 200px;"
                valueChangeListener="#{setStoreSalesBean.loadCurrentDepartment}" converter="saveUserConverter">
                <f:selectItems value="#{setStoreSalesBean.companyDepartments}" />
                <a4j:support ajaxSingle="true" event="onselect" reRender="storeSalesPanel" />
                </rich:comboBox>
                <br/><br/><br/>    

                <h:panelGroup id="storeSalesPanel">
                <rich:comboBox id="selectStoreBox" value="#{setStoreSalesBean.currentStore}" defaultLabel="Select a store" style="width: 200px;"
                valueChangeListener="#{setStoreSalesBean.loadCurrentStore}" converter="saveUserConverter">
                <f:selectItems value="#{setStoreSalesBean.departmentStores}" />
                <a4j:support ajaxSingle="true" event="onselect" reRender="storeValuesDataTable" />
                </rich:comboBox>
                <br/><br/><br/>    

                <rich:dataTable id="storeValuesDataTable" rows="#{setStoreSalesBean.storeSalesSize}" width="100%" var="sale"
                value="#{setStoreSalesBean.storeSales}" sortBy="#{sale.monthInYear}"
                ajaxKeys="#{setStoreSalesBean.rowsToUpdate}">
                <rich:column>
                <f:facet name="header">
                <h:outputText value="Date"/>
                </f:facet>

                <h:outputText value="#{sale.monthInYear}" converter="numberToDateConverter" />
                </rich:column>

                <rich:column>
                <f:facet name="header">
                <h:outputText value="Budget value"/>
                </f:facet>

                <h:outputText id="budget" value="#{sale.budgetValue}"/>
                </rich:column>

                <rich:column>
                <f:facet name="header">
                <h:outputText value="Sales value"/>
                </f:facet>

                <h:outputText id="sale" value="#{sale.value}"/>
                </rich:column>

                <rich:column>
                <f:facet name="header">
                <h:outputText value="Udpate"/>
                </f:facet>
                <center>
                <a4j:commandButton ajaxSingle="true" value="Update value"
                oncomplete="#{rich:component('saleEditPanel')}.show()" style="width: 50%;" reRender="saleInfo">
                <f:setPropertyActionListener value="#{sale}" target="#{setStoreSalesBean.selectedStoreSale}" />
                </a4j:commandButton>
                </center>
                </rich:column>

                </rich:dataTable>
                <br/><br/><br/>

                 

                 

                2)

                 

                <rich:modalPanel id="saleEditPanel">
                <f:facet name="header">Edit sale value:</f:facet>
                <h:form>
                <h:panelGrid id="saleInfo">

                <h:outputLabel for="budgetValueInput" value="Budget value:"/>
                <h:inputText id="budgetValueInput" value="#{setStoreSalesBean.currentStoreBudget}">
                <a4j:support ajaxSingle="true" event="onchange" />
                </h:inputText>

                <h:outputLabel for="saleValueInput" value="Sale value:"/>
                <h:inputText id="saleValueInput" value="#{setStoreSalesBean.currentStoreValue}">
                <a4j:support ajaxSingle="true" event="onchange" />
                </h:inputText>

                <h:panelGrid columns="2">
                <a4j:commandButton ajaxSingle="true" id="storeButton" value="Store" actionListener="#{setStoreSalesBean.updateStoreSales}"
                oncomplete="#{rich:component('saleEditPanel')}.hide()" reRender="storeValuesDataTable, sale, budget"/>
                <a4j:commandButton ajaxSingle="true" value="Cancel" actionListener="#{setStoreSalesBean.clear}" 
                onclick="#{rich:component('saleEditPanel')}.hide()"/>
                </h:panelGrid>
                </h:panelGrid>
                </h:form>
                </rich:modalPanel>

                <a4j:commandButton ajaxSingle="true" value="Add new value" actionListener="#{setStoreSalesBean.addNewValue}" reRender="storeSalesPanel,storeSalesTable" style="width: 20%;"/>
                <br/><br/>

                <h:panelGroup id="storeSalesTable" rendered="#{setStoreSalesBean.addNewValueVisible}">
                <rich:panel id="storePanel">
                <f:facet name="header">
                Add new value to store sales
                </f:facet>

                <table cellspacing="5" cellpadding="5">
                <tr>
                <td>
                <rich:calendar value="#{setStoreSalesBean.currentDate}"
                popup="false" datePattern="yyyy.MM"
                showWeekDaysBar="false" showFooter="false"
                showApplyButton="true" styleClass="special"
                oncurrentdateselected="event.rich.component.selectDate(event.rich.date)"
                converter="dateTimeZoneConverter" style="width: 200px;">
                <a4j:support ajaxSingle="true" event="onchanged" reRender="currentDateOutput"/>
                </rich:calendar>
                </td>         
                <td>         
                <h:outputText value="#{setStoreSalesBean.currentDate}" id="currentDateOutput" converter="dateTimeZoneConverter"/>                                           
                </td>
                </tr>
                <tr>    
                <td>
                <h:outputText value="Set budget for selected store:" />
                </td>
                <td>
                <h:inputText id="saleValue" value="#{setStoreSalesBean.currentStoreBudget}"
                style="width: 200px; margin-right: 5px; float:right; text-align: right; margin-bottom:4px;"/>
                </td>
                </tr>
                <tr>    
                <td>
                <h:outputText value="Set sales for selected store:" />
                </td>
                <td>
                <h:inputText id="budgetValue" value="#{setStoreSalesBean.currentStoreValue}" 
                style="width: 200px; margin-right: 5px; float:right; text-align: right; margin-bottom:4px;"/>
                </td>
                </tr>
                </table>

                <center>
                <a4j:commandButton ajaxSingle="false" value="Save store sales" actionListener="#{setStoreSalesBean.saveStoreSales}" style="width: 20%;" reRender="storeValuesDataTable"/>
                <a4j:commandButton ajaxSingle="true" value="Clear" actionListener="#{setStoreSalesBean.clear}" style="width: 20%;" reRender="storeValuesDataTable"/>
                </center>
                </rich:panel>
                </h:panelGroup>


                </h:panelGroup>
                <br/><br/><br/>  

                 

                </div>
                </h:form>

                </ui:define>
                </ui:composition>

                 

                 

                 

                Message was edited by: Elena Veretilo

                • 5. Re: <a4j:commandButton> didnt work after some time
                  Milo van der Zee Newbie

                  You mean that this :

                   

                  <a4j:commandButton ajaxSingle="false" value="Save store sales"

                  actionListener="#{setStoreSalesBean.saveStoreSales}" style="width: 20%;"

                  reRender="storeValuesDataTable"/>

                   

                  at the end of the jsf file stops functioning? Might be that your bean is not session scoped but request scoped.

                   

                   

                  Check your faces-config.xml for it. It must look something like:

                  <managed-bean>

                    <managed-bean-name>setStoreSalesBean</managed-bean-name>
                    <managed-bean-class>no.sfront.sales.SetStoreSalesBean</managed-bean-class>

                    <managed-bean-scope>session</managed-bean-scope>
                  </managed-bean>

                   

                  Milo

                  • 6. Re: <a4j:commandButton> didnt work after some time
                    Elena Veretilo Newbie

                    No - another button:

                     

                    <a4j:commandButton ajaxSingle="true" id="storeButton" value="Store" actionListener="#{setStoreSalesBean.updateStoreSales}"
                    oncomplete="#{rich:component('saleEditPanel')}.hide()" reRender="storeValuesDataTable, sale, budget"/>

                     

                    The bean is session bean and I tried even applicatuion scope - the same result(

                     

                    Message was edited by: Elena Veretilo

                    • 7. Re: <a4j:commandButton> didnt work after some time
                      Milo van der Zee Newbie

                      This one?:

                       

                      <a4j:commandButton ajaxSingle="true" value="Update value"
                        oncomplete="#{rich:component('saleEditPanel')}.show()"

                        style="width:  50%;" reRender="saleInfo"

                      >
                         <f:setPropertyActionListener  value="#{sale}" target="#{setStoreSalesBean.selectedStoreSale}" />
                      </a4j:commandButton>

                       

                      JSF only stores values if they are changed in the view. I'm not sure but that could be the reason that tjis does not work the second time. You could clear the view from the backend but that defeats the whole ajax rendering and you'll end up with flashing screen updates.

                       

                      Or just change the code a bit. You want to add the row to the sales list and so a normal a4j:commandbutton would function perfectly. In the backend you then read the row and use that to store the new sales.

                       

                      Change commandbutton to:

                      <a4j:commandButton  ajaxSingle="true" value="Update value"

                        actionListener="#{setStoreSalesBean.storeSelectedSale}"

                        oncomplete="#{rich:component('saleEditPanel')}.show()"

                        style="width:  50%;" reRender="saleInfo"

                      />

                      and in the backend create:

                      public void storeSelectedSale(actionEvent event) {

                        sale = getRowDataForActionEvent(event);

                        ...

                      }

                       

                      Accessing the row:

                       

                      public static Object getRowDataForActionEvent(ActionEvent event) {
                        HtmlDataTable htmlDataTable = getTableForActionEvent(event);
                        if(htmlDataTable!=null) {
                          return htmlDataTable.getRowData();
                        }
                        return null;
                      }

                       

                      private static HtmlDataTable getTableForActionEvent(ActionEvent event) {
                        Object uic = event.getSource();
                        while(uic!=null && uic instanceof UIComponent) {
                          // Find HtmlDataTable...
                          if(uic instanceof HtmlDataTable) {
                            HtmlDataTable htmlDataTable = (HtmlDataTable) uic;
                            return htmlDataTable;
                          }
                          uic = ((UIComponent) uic).getParent();
                        }
                        return null;
                      }

                      • 8. Re: <a4j:commandButton> didnt work after some time
                        Elena Veretilo Newbie

                        The problem with this button:

                         

                        <a4j:commandButton ajaxSingle="true" id="storeButton" value="Store" actionListener="#{setStoreSalesBean.updateStoreSales}"
                        oncomplete="#{rich:component('saleEditPanel')}.hide()" reRender="storeValuesDataTable, sale, budget"/>

                         

                        Its the button, which do update.

                         

                         

                         

                        The bean is session bean and I tried even applicatuion scope - the same result(

                        • 9. Re: <a4j:commandButton> didnt work after some time
                          Milo van der Zee Newbie

                          Ok Bit confusing which button you meant.

                           

                          So a breakpoint in updateStoreSales() is only hit the first time you click the button? I could make a guess why the values on the screen are not updated but if you say that the method is not even called I don't know why.

                           

                          Setting ajaxSingle="true" means that only that link is sent and not the rest of the fields. So JSF does not update the values and so stay the same. What happens if you leave that to false?

                          1 of 1 people found this helpful
                          • 10. Re: <a4j:commandButton> didnt work after some time
                            Elena Veretilo Newbie

                            Hi Milo van der Zee! Thank you for your help! I figure out what was wrong - I have my modalPanel in the form and thats why it didnt work, because need refresh.

                            Now I get modalPanel out of form - and everything works fine.

                             

                            Anyway - thanks for much for helping, I just newbie in richfaces and jsf, so there will be a lot of stupid questions)

                            • 11. Re: <a4j:commandButton> didnt work after some time
                              Milo van der Zee Newbie

                              Super! happy coding

                               

                              MAG,

                              Milo