3 Replies Latest reply on Jan 2, 2012 11:20 PM by poesys

    a4j:commandButton does not call action

    poesys

      I've reviewed similar posts, but I haven't found any solutions.

       

      I have a form that includes a tree, a selected transaction display with an embedded table, and a panel for entering new transaction items. There are two command buttons, one to submit the updated transaction (works fine) and one to add the new transaction item to the data table of items. The latter button successfully submits ajax and renders the right components, it just doesn't call the action method (or action listener, I've tried both). There is a single form, and both buttons are inside the form and are of type button.

       

      Here is the code fragment for the button:

       

       

      <a4j:commandButton id="addItemToTransaction" type="button" execute="@form" render="@this itemPanel itemTable" image="/images/add-small.png" title="Click to add item to transaction" actionListener="#{tree.addItemToTransaction}" styleClass="buttonIconImage" />
      

       

      Here is the action listener method in the Tree class:

       

       

        /**
         * An action method that adds the current view Item DTO to the set of items in
         * the selected transaction.
         * @param event the commmand button event
         */
        public void addItemToTransaction(ActionEvent event) {
          logger.debug("Calling addItemToTransaction method");
          boolean valid = checkForValidItem();
          if (valid) {
            TransactionDelegate delegate =
              TransactionDelegateFactory.getTransactionDelegate();
            BsItem newItem =
              delegate.createItem(selectedTransaction,
                                  selectedTransaction.getTransactionId(),
                                  item.account.getAccountId(),
                                  item.account.getYear(),
                                  item.amount,
                                  item.debit,
                                  false);
            selectedTransaction.addItemsItem(newItem);
            // Set new item to null to remove panel.ed
            item = null;
          }
        }
      

       

      For reference, here is the complete index.xhtml file that contains the form and the errant button:

       

       

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
      
      <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:a4j="http://richfaces.org/a4j" xmlns:rich="http://richfaces.org/rich" xml:lang="en">
      
         <f:view>
            <body>
               <p>
                  There's no accounting for taste!
               </p>
            </body>
            <ui:composition template="/facelets/templates/standard.xhtml">
               <ui:define name="title">Poesys Accounting</ui:define>
               <ui:define name="css">
                  <link rel="stylesheet" type="text/css" href="/accounting/styles/index.css" />
               </ui:define>
               <ui:define name="content">
                  <div id="content">
                     <h:messages />
                     <h:form id="treeForm">
                        <rich:panel id="treePanel" header="Fiscal Year Transactions" styleClass="treePanel">
                           <rich:tree id="treeComponent" nodeType="#{node.type}" var="node" value="#{tree.rootNodes}" toggleType="ajax" toggleListener="#{tree.nodeToggled}" selectionType="ajax" selectionChangeListener="#{tree.selectionChanged}">
                              <rich:treeNode type="FiscalYear" icon="/images/folder-32.png">
                                 <h:outputText value="#{node.name}" />
                              </rich:treeNode>
                              <rich:treeNode type="MajorCategory" icon="/images/folder-32.png">
                                 <h:outputText value="#{node.name}" />
                              </rich:treeNode>
                              <rich:treeNode type="AccountCategory" icon="/images/folder-32.png">
                                 <h:outputText value="#{node.name}" />
                              </rich:treeNode>
                              <rich:treeNode type="Account" icon="/images/folder-32.png">
                                 <h:outputText value="#{node.name}" />
                              </rich:treeNode>
                              <rich:treeNode type="Transaction" icon="/images/new_page-32.png">
                                 <h:outputText value="#{node.name}" />
                                 <a4j:ajax event="click" render="@all" />
                              </rich:treeNode>
                           </rich:tree>
                        </rich:panel>
                        <rich:panel id="currentTransactionPanel" header="Current Transaction" rendered="#{not empty tree.selectedTransaction}" styleClass="currentSelectionPanel">
                           <rich:calendar id="transactionDate" value="#{tree.selectedTransaction.transactionDate}" datePattern="MMM d, yyyy"></rich:calendar>
                           <br />
                           <rich:inplaceInput id="description" defaultLabel="Click to enter description" maxlength="4000" size="100" value="#{tree.selectedTransaction.description}" required="true" requiredMessage="Must enter description" />
                           <h:message for="description" />
                           <br />
                           <rich:dataTable id="itemTable" value="#{tree.selectedTransaction.items}" var="item" styleClass="dataTable" columnClasses="textcell, numcell, checkboxcell, buttoncell">
                              <rich:column id="accountColumn" rendered="#{!item.deleted}">
                                 <f:facet name="header">
                                    <h:outputText value="Account" title="Account to which to apply the debit or credit" styleClass="colheader" />
                                 </f:facet>
                                 <h:outputText value="#{item.displayAccountNumberAndName}" />
                              </rich:column>
                              <rich:column id="amountColumn" rendered="#{!item.deleted}">
                                 <f:facet name="header">
                                    <h:outputText value="Amount" title="Amount of the debit or credit within the transaction" styleClass="colheader" />
                                 </f:facet>
                                 <rich:inplaceInput value="#{item.amount}" defaultLabel="Enter amount">
                                    <f:convertNumber type="currency" />
                                 </rich:inplaceInput>
                              </rich:column>
                              <rich:column id="debitColumn" rendered="#{!item.deleted}">
                                 <f:facet name="header">
                                    <h:outputText value="Debit" title="Select to specify item is debit; un-select to specify item is credit" styleClass="colheader" />
                                 </f:facet>
                                 <h:selectBooleanCheckbox label="DR/CR" value="#{item.debit}" />
                              </rich:column>
                              <rich:column rendered="#{!item.deleted}">
                                 <f:facet name="header">
                                    <h:outputText value="Delete" title="Click on red button to delete an item" styleClass="colheader" />
                                 </f:facet>
                                 <a4j:commandButton id="deleteItem" image="/images/delete-small.png" type="button" action="#{tree.deleteItem(item)}" render="itemTable" />
                              </rich:column>
                           </rich:dataTable>
                           <a4j:commandButton id="saveTransaction" value="Save" type="submit" action="#{tree.saveTransaction}" title="Click to save transaction to database" styleClass="formButton" execute="@form" render="@form" />
                           <a4j:commandButton id="resetTransaction" value="Reset" type="reset" action="#{tree.resetTransaction}" title="Click to reset transaction to database content" styleClass="formButton" execute="@form" render="@form" />
                           <h:outputText value="Total: " styleClass="transactionTotal" />
                           <h:outputText id="transactionTotal" style="bold" value="#{tree.selectedTransaction.itemTotalAmount}">
                              <f:convertNumber type="currency" />
                           </h:outputText>
                           <a4j:commandButton id="addItem" image="/images/add-small.png" type="button" action="#{tree.addItem}" title="Click to create a new item for the transaction" render="@form" execute="@this" styleClass="buttonIconImage" />
                           <rich:panel id="itemPanel" header="New Item" rendered="#{tree.item != null}" columns="9">
                              <h:outputLabel for="itemAccountAutocomplete" value="Account: " styleClass="label" />
                              <rich:autocomplete id="itemAccountAutocomplete" mode="ajax" layout="table" autocompleteMethod="#{tree.suggestAccounts}" var="account" value="#{tree.item.displayString}" fetchValue="#{account.displayAccountNumberAndName}">
                                 <rich:column>
                                    <h:outputText value="#{account.displayAccountNumber}" />
                                 </rich:column>
                                 <rich:column>
                                    <h:outputText value="#{account.name}" />
                                 </rich:column>
                              </rich:autocomplete>
                              <h:outputLabel for="itemAmount" value="Amount: " styleClass="label" />
                              <h:inputText id="itemAmount" value="#{tree.item.amount}" styleClass="currency">
                                 <f:convertNumber type="currency" />
                                 <a4j:ajax event="blur" execute="@this" render="@this @newTotal" />
                              </h:inputText>
                              <h:outputText value="Total: " styleClass="transactionTotal" />
                              <h:outputText id="newTotal" style="bold" value="#{tree.item.totalAmount}">
                                 <f:convertNumber type="currency" />
                              </h:outputText>
                              <h:outputLabel for="itemDebit" value="Debit: " styleClass="label" />
                              <h:selectBooleanCheckbox id="itemDebit" label="Debit" value="#{tree.item.debit}" />
                              <a4j:commandButton id="addItemToTransaction" type="button" execute="@form" render="@this itemPanel itemTable" image="/images/add-small.png" title="Click to add item to transaction" actionListener="#{tree.addItemToTransaction}" styleClass="buttonIconImage" />
                           </rich:panel>
                        </rich:panel>
                     </h:form>
                     <a4j:log />
                  </div>
               </ui:define>
            </ui:composition>
         </f:view>
      </html>
      
        • 1. Re: a4j:commandButton does not call action
          healeyb

          A couple of suggestions, can you try without type="button", and especially if you're using a webkit based

          browser like chrome can you try f:view contentType="text/html". I'm not sure if the h:messages tag needs

          to be inside the form, if it does you might be missing validation errors that would prevent the partial submit.

          I think the problem is type="button" though, I'd not expect this to submit any form components (you'd want

          type="submit"), and you'd typically use this with javascript only.

           

          Regards,

          Brendan.

          • 2. Re: a4j:commandButton does not call action
            poesys

            type="button" removed, using the default (presumably "submit")--no change. The explicit execute should submit everything in the form. In any case, using a submit button doesn't change anything. Also, I should note that the other button has type="button" and works fine every time.

             

            Moved messages inside form, no validation errors.

             

            contentType set, no change.

            • 3. Re: a4j:commandButton does not call action
              poesys

              Solved, I guess.

               

              When I started testing the Save feature, a validation error showed up on the ItemAmount field (an input field with a currency converter next to the button that wasn't doing anything). I had entered a number (24.03) but it found that that wasn't a valid currency value, so I added a dollar sign ($24.03) and tried my errant button again, and now it worked fine.

               

              So the problem was apparently the validation phase failed but did not return a validation error, and so the processing never got to executing the action listener. The actual problem was that I used a currency converter on the data entry field without realizing that would require me to enter the $ and other "currency" pattern details.