function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
mauricio.ramosmauricio.ramos 

Buton not Rerendering correctly

Hello,

 

I have a VF page with a button that should be hidden while the Id of its parent record is null (meaning until the Save buton higher up in the page is clicked and a save method is executed which will persist the object in the DB. At that point I want to have the button farther down (which creates instances of child records to appear again so that releated items can be added.  See the code below:

 

This is at the top of the page where a save buton is placed to execute the saving of the Sales Order (parent object)

 

<apex:pageblockButtons >
<apex:commandButton action="{!saveSO}" value="Save Changes" reRender="out,btnAddSOI" status="saveStatus">
</apex:commandButton>

  then at the bottom of the page in another pageblock I have the following:

 

    <apex:pageBlockButtons >
    <apex:outputPanel id="btnAddSOI" rendered="{!SOsaved}">
       <apex:commandButton action="{!AddSOI}" value="Add New Item" rerender="tablePnl"  />
    </apex:outputPanel>
    </apex:pageBlockButtons>

 This is the button that should dissapear if the parent record has not been saved yet and should magically reapear once the button has been saved. Currently on page load the visibility reflect correctly(e.g. if editing an existing record via the VF page then the button is visible, else if its a new record via the same VF page then the button is hidden) The problem lies in that the button doesn't REAPPEAR once the record is saved.  Below is the controller method in use (SOsaved):

 

    public Boolean SOsaved {
        get { 
        boolean bool;
        bool= so.Id <> null ? True : False;
        System.debug('SO saved ' + bool + ' - ' + so.Id);
        return bool;
        }
    }

 Can someone please assist???

Best Answer chosen by Admin (Salesforce Developers) 
mauricio.ramosmauricio.ramos

Hello,

 

I am posting my final code in order for it to be of use to anyone experiencing the same issue. I have solved this some time ago but did not get to the solution without much trial and error. I cannot recall the exact solution I found but I will paste the relevant code that is working so anyone can reference it. See below:

 

 

The button in question:

 <apex:pageBlockButtons location="top" >
        <apex:commandButton value="Add New" action="{!AddSOI}" rerender="tablePnl,detailPanel"  disabled="{!so.id == null}" id="btnAddSOI"  status="loadingStatus" />
    </apex:pageBlockButtons>  

 The button that should fire the rerender:

<apex:commandButton action="{!saveSO}" value="Save Changes" reRender="out,btnAddSOI,btnAddSOI_small,tablePnl,msgs, fOppId" status="saveStatus" disabled="{!so.ERP_Company_Id__c == ''}"/>

 

 

Keep in mind that I have added other stuff to the page so the same code that was before may now be a litle different, but the basic functionality in question is the same.

All Answers

Eugene PozniakEugene Pozniak

Actually, you can't reRender more than one component for one action.

It should work fine if you write reRender="btnAddSOI".

SeAlVaSeAlVa

I'm sure you can rerender more than one component.

 

Just have to change 

 

<apex:pageBlockButtons >
    <apex:outputPanel id="btnAddSOI" rendered="{!SOsaved}">
       <apex:commandButton action="{!AddSOI}" value="Add New Item" rerender="tablePnl"  />
    </apex:outputPanel>
    </apex:pageBlockButtons>

 

to

 

<apex:pageBlockButtons id="btnAddSOI" >
    <apex:outputPanel rendered="{!SOsaved}">
       <apex:commandButton action="{!AddSOI}" value="Add New Item" rerender="tablePnl"  />
    </apex:outputPanel>
    </apex:pageBlockButtons>

 

 

(You have to rerender parent component in order to "rendered" tag to be evaluated again)

mauricio.ramosmauricio.ramos

I've made the changes but NO LUCK! I checked a debug statement to see if the {!SOsaved} method is returning true or false when it should and it does. Also the button that fires off the  saveSO method (at the top of the page, is working correctly as well since when it rerenders the "out" panel I have the name field updated to the actual record name:

 

  <apex:commandButton action="{!saveSO}" value="Save Changes" reRender="out,btnAddSOI" status="saveStatus">

 

To reply to SeAlVa, I have another component that fires off a method and rerenders several fields at the same time so I think that the rerendering can happen for more than one component from one method execution.

 

So I am unsure if it's the order of the rerendering or some missing tag but it still not rerendering the button.

 


SeAlVaSeAlVa

If you have required fields, they might not let you rerender. Try (as a temporal way to check it) immediate=true.

 

If that is your problem, you may have to use <apex:actionRegion or the immediate="true" to get what you want.

mauricio.ramosmauricio.ramos

Thank you for your reply, I have tried adding the immediate = "true" parameter with no luck, we do not have any required fields on the object yet so that should not be the issue.

 

mauricio.ramosmauricio.ramos

I am attaching entire VF code minus some middle static input fields that do not do anything special, also adding in the controller code in the chance that I may be writting something wrong and you can identify it.

 

<apex:page controller="VF_SalesDoc_CreateDoc_Controller_MR" tabStyle="SCRB_SalesOrder__c" >
<apex:sectionHeader title="Create Sales Document" subtitle="{!Account.Name}"/>
 <apex:messages />
<apex:form id="theForm">
<apex:actionRegion id="detail">
<apex:pageBlock tabStyle="SCRB_SalesOrder__c" >
     <apex:actionStatus startText="Saving changes..."  id="saveStatus"  startstyle="font-weight:bold-color:Red-size:4" />
    <apex:pageblockButtons >
       <apex:commandButton action="{!saveSO}" value="Save Changes" reRender="out,btnAddSOI" status="saveStatus" immediate="true">
        </apex:commandButton>
         <apex:commandButton action="{!saveCloseSO}" value="Save & Close" />
         <apex:commandButton value="Cancel" action="{!cancel}"/>
    </apex:pageblockButtons>   
    <apex:outputPanel id="out">
        <apex:pageblockSection collapsible="true" id="docInfo" showHeader="true" title="Document Information"  columns="2"  >
            <apex:pageblocksectionItem >  
               <apex:outputLabel value="Name" />
               <apex:outputLabel value="{!SavedSOName }" id="lblName" />
            </apex:pageblocksectionItem>
            <!-- SOME MORE INPUT FIELDS REMOVED FROM HERE THAT ARE NOT RELEVANT AND DO NOT IMPACT ANYTHING-->
         </apex:pageblockSection>
    </apex:outputPanel>  
 </apex:pageBlock>
</apex:actionRegion>

    <apex:pageblock title="Sales Order Items"  tabStyle="SCRB_SalesOrder__c" >    
    <apex:pageBlockButtons>
       <apex:commandButton action="{!AddSOI}" value="Add New Item" rerender="tablePnl"  disabled="{!NOT(SOsaved)}" id="btnAddSOI" />
    </apex:pageBlockButtons>  
    
        <apex:outputPanel id="tablePnl">
            <apex:pageblockTable value="{!SOItems}" var="SOI" id="SOIList" columnsWidth="25px, 50px, 100px, 100px, 25px, 25px, 50px, 50px, 50px, 25px, 50px, 25px" columns="12">
              
                <apex:column headerValue="Action">
                    <apex:commandLink value="Del" action="{!del}" rerender="tablePnl" style="font-weight:bold"  >&nbsp;|&nbsp;
                        <apex:param name="delname" value="{!SOI.id}" assignTo="{!currSOIid}"/>
                        <apex:outputLink title="" value="/{!SOI.id}" style="font-weight:bold" target="_blank" >View</apex:outputLink>
                    </apex:commandLink>
                </apex:column>
                               
                <apex:column headerValue="Line type">
                    <apex:inputField value="{!SOI.Line_Type__c}" id="fLineType">
                        <apex:actionSupport event="onchange" reRender="detailBlock"/>
                    </apex:inputField>
                </apex:column> 
                     
                <apex:column headerValue="Product">
                   <apex:actionRegion id="prodRgn">
                    <apex:inputField value="{!SOI.ProductId__c}" id="fProd">
                        <apex:commandLink id="lknProduct" action="{!updateSOIProductData}" value="Refresh" reRender="tablePnl,fDiscAmt,fTotalPrice,fProfit">                    
                          <apex:param name="currSOI" value="{!SOI.Id}" assignTo="{!currSOIid}"/>
                          <apex:param name="currProd" value="{!SOI.ProductId__c}" assignTo="{!currProdId}"/>
                        </apex:commandLink>
                     </apex:inputField>
                       </apex:actionRegion>
                </apex:column>  
                 
                <apex:column headerValue="Description">
                    <apex:inputField value="{!SOI.Description__c}" id="fDescr" />
                </apex:column>
               
                <apex:column headerValue="Quantity">
                    <apex:actionRegion >
                        <apex:inputField value="{!SOI.Quantity__c}"  id="fQTY">
                         <apex:actionSupport event="onchange" rerender="fDiscAmt,fTotalPrice,fProfit" action="{!calculateTotalPrice}">
                             <apex:param name="currSOIQty" value="{!SOI.Id}" assignTo="{!currSOIid}"/>
                             </apex:actionSupport>
                        </apex:inputField>
                    </apex:actionRegion>
                </apex:column>  
               <apex:column headerValue="Unit Cost" >
                    <apex:inputField value="{!SOI.Unit_Cost__c}" id="fUnitCost" />
                </apex:column>
                <apex:column headerValue="Sales Price ex VAT">
                    <apex:inputField value="{!SOI.SalesPrice__c}" id="fSalesPrice" >
                    <apex:actionSupport event="onchange" rerender="fDiscAmt,fTotalPrice,fProfit" action="{!calculateTotalPrice}">
                             <apex:param name="currSOISlsPr" value="{!SOI.Id}" assignTo="{!currSOIid}"/>
                             </apex:actionSupport>
                             </apex:inputField>
                </apex:column>
                <apex:column headerValue="Line Disc Pct.">
                    <apex:inputField value="{!SOI.Line_Discount_Pct__c}" id="fDiscPct">
                        <apex:actionSupport event="onchange" rerender="fDiscAmt,fTotalPrice,fProfit" action="{!calculateTotalPrice}">
                             <apex:param name="currSOIPct" value="{!SOI.Id}" assignTo="{!currSOIid}"/>
                        </apex:actionSupport>
                     </apex:inputField>
                </apex:column>
                <apex:column headerValue="Line Disc Amt.">
                    <apex:inputField value="{!SOI.Line_Discount_Amount__c}" id="fDiscAmt">
                    <apex:actionSupport event="onchange" rerender="fDiscAmt,fTotalPrice,fProfit" action="{!calculateTotalPrice}">
                             <apex:param name="currSOIPAmt" value="{!SOI.Id}" assignTo="{!currSOIid}"/>
                        </apex:actionSupport>
                     </apex:inputField>
                </apex:column>
                 <apex:column headerValue="Profit" width="25px" style="{!IF((SOI.Profit__c <> 0 && SOI.Profit__c >0),'color:red','color:green')}">
                    <apex:outputField value="{!SOI.Profit__c}" id="fProfit">
                        
                     </apex:outputField>
                </apex:column>
                <apex:column headerValue="Total Price">
                    <apex:inputField value="{!SOI.TotalPrice__c}" id="fTotalPrice">
                    <apex:actionSupport event="onchange" rerender="fDiscAmt,fTotalPrice,fProfit" action="{!calculateTotalPrice}">
                             <apex:param name="currSOIPct" value="{!SOI.Id}" assignTo="{!currSOIid}"/>
                        </apex:actionSupport>
                     </apex:inputField>
                </apex:column>
                <apex:column headerValue="Line Status" >
                    <apex:outputField value="{!SOI.Line_Status__c }" id="fLineStatus"  />
                </apex:column> 
            </apex:pageBlockTable>
        </apex:outputPanel>
        
       <!--Dynamic ajax rerender section that depends on above selected values for the table row. TO COMPLETE-->
        <apex:outputPanel >
            <apex:pageBlockSection title="Sale Order Item Detail" columns="2" id="SOIs" showHeader="true" >
           <!-- <apex:inputField id="timeEst" label="Time Estimate" value=""/>-->
            </apex:pageBlockSection>
           
        </apex:outputPanel>
  
    </apex:pageblock>

</apex:form>
</apex:page>

 And here goes the controller code:

 

public class VF_SalesDoc_CreateDoc_Controller_MR {

    public PageReference cancel() {
        return null;
    }

    //class variables
    private  SCRB_SalesOrder__c so;
    private List<SCRB_SalesOrderLineItem__c> SOIs = new List<SCRB_SalesOrderLineItem__c>();
    public List<SCRB_SalesOrderLineItem__c> forDeletion = new List<SCRB_SalesOrderLineItem__c>();
    public Account account {get; private set;}
    public Opportunity opportunity {get; private set;}
    Private SCRB_SalesOrderLineItem__c currSOI;
   // public String currProdId ;
    private PriceBookEntry pbEntry;
    Private salesOrderManager som;
    Private String PageAction;
    Private String DocType;
    Private Id accountId;
    Private Id contactId;
    Public String mPricebook;

    public String currSOIid {
        get{ 
            return currSOI.id;} 
        set {
            if(value <> null ){
                for(SCRB_SalesOrderLineItem__c soi: SOIs) {
                    if (soi.id == value) {
                        currSOI = soi;
                    }
                }
            } else {
                currSOI = null;}
        }
    }
    public String currProdId {
        get {
            return currProdId;}
        set{
           currProdId = value;
        }
    }
    
    //**Controller constructor**//
    public VF_SalesDoc_CreateDoc_Controller_MR() {
    //check if its a new action, if so prepopulate fields:
        Id id = ApexPages.currentPage().getParameters().get('id');
        PageAction = ApexPages.currentPage().getParameters().get('PageAction');
        DocType = ApexPages.currentPage().getParameters().get('DocType');
        accountId = ApexPages.currentPage().getParameters().get('aId');
        contactId = ApexPages.currentPage().getParameters().get('cId');

          
        //create a Sales Order Manager and load new/existing Sales Order
        som = new SalesOrderManager ();
        so = loadSalesOrder(id);
        
        if (PageAction != null) {
                if (PageAction == 'New') {
                    // we arrived from account so we load this account into the header 
                    account = som.loadAccount(accountid);   
                    this.populateSOwithAccount(account);
                     so.Pricebook__c = 'Standard Price Book';               
                }
                }else {
                    //if SO exists then load SOIs
                    //removed code from here
                }
        }
    //**end of controller constructor**//
    /////////////////////////////////////
        public SCRB_SalesOrder__c getSo() {
        return so;
    }
    
    public SCRB_SalesOrder__c loadSalesOrder(id pSOid){
        //remved code here since irrelevant to issue at hand
            return mSO;
}
      public PageReference updateSOIProductData() {
          //retrieve the Product data for selected product. Then update all  price fields accordingly
          //Removed the code since this is not related and there is 20k character limit on the post.
    }
    
    
    public pagereference calculateTotalPrice () {
        //recalulate total price from inputs 
       //removed this code as it is irrelevant for the issue
        return null;
    }
    private decimal getDiscountAmt (decimal pSubTotal) {
       //removed code as it is irrelevant to the issue
        return discAmt;
    }

    private void populateSOwithAccount(Account account){
                     this.so.Type__c=DocType;
                     //so.Name=so.Type__c;  //Opportunity.Name when logic creating opp is in place
                     this.so.AccountId__c = account.Id; 
     //update some more fields...
    }
    
    
    // gets/sets list of all Sales Order Items
    public List<SCRB_SalesOrderLineItem__c> SOItems {
        get { return SOIs;}
        set {SOIs = value;}
    }
     public Integer SOItemsSize {
        get { return SOIs.size();}
    }
   
    public Boolean SOsaved {
        get { 
        boolean bool;
        bool= so.Id <> null ? True : False;
        System.debug('###SO saved: '+ bool + ' - ' + so.Id);
        return bool;
        }
    }
   public String getSavedSOName () {
      String name= so.Id <> null ? so.Name : 'Sales Order not saved yet!';
      system.debug('### so: ' + so);
      return name;
   }
   //add one new Sales Order Item to the list
    public PageReference AddSOI(){
        //removed code as it is irrelevant to the issue
        return null;
    }
 
     public PageReference saveSO (){
            upsert so;
            so = loadSalesOrder(so.id);
            if (SOIs.size()>=1) {
            for (SCRB_SalesOrderLineItem__c  soi: SOIs) {
                if(soi.SalesOrderId__c == null) {soi.SalesOrderId__c = so.id;}
            }
            }
            return null;
    }
    public PageReference saveCloseSO (){
            upsert so;
            system.Debug('### SOIs: ' + SOIs);
            saveSOIs(so.id);
            PageReference sop= new ApexPages.StandardController(so).view();
            sop.setRedirect(true);
            return sop;
    }
    
    public void saveSOIs(id soid) {
        try {
           //removed some code here 
        } catch ( DmlException exc) {
          ApexPages.addMessages(exc);
        }
    }
     
    public PageReference del(){
        //removed code here as well, it does not affect the issue at hand
        return null;
    }
    
}

 Hope this gives a more complete picture of the issue

Eugene PozniakEugene Pozniak

Try to transfer Id from <apex:commandButton> to <apex:pageBlock>:

 

<apex:pageblock title="Sales Order Items" tabStyle="SCRB_SalesOrder__c" id="btnAddSOI">    
    <apex:pageBlockButtons>
       <apex:commandButton action="{!AddSOI}" value="Add New Item" rerender="tablePnl"  disabled="{!NOT(SOsaved)}" />
. . . 
</apex:pageblock>

 

 

SeAlVaSeAlVa

Try replacing 

 

<apex:pageBlockButtons>
    <apex:commandButton action="{!AddSOI}" value="Add New Item" rerender="tablePnl"  disabled="{!NOT(SOsaved)}" id="btnAddSOI" />
</apex:pageBlockButtons>

 with 

<apex:pageBlockButtons>
    <apex:outputPanel id="btnAddSOI">
        <apex:commandButton action="{!AddSOI}" value="Add New Item" rerender="tablePnl"  disabled="{!NOT(SOsaved)}" />
    </apex:outputPanel>
</apex:pageBlockButtons>

 

Just for future coding, 

you have to take into account that when you rerender a component, you rerender its content. what means that if there is a tag rendered="{!xxx}" it will not be recalculated. You will have to rerender its parent to do so.

 

mauricio.ramosmauricio.ramos

Hello,

 

I am posting my final code in order for it to be of use to anyone experiencing the same issue. I have solved this some time ago but did not get to the solution without much trial and error. I cannot recall the exact solution I found but I will paste the relevant code that is working so anyone can reference it. See below:

 

 

The button in question:

 <apex:pageBlockButtons location="top" >
        <apex:commandButton value="Add New" action="{!AddSOI}" rerender="tablePnl,detailPanel"  disabled="{!so.id == null}" id="btnAddSOI"  status="loadingStatus" />
    </apex:pageBlockButtons>  

 The button that should fire the rerender:

<apex:commandButton action="{!saveSO}" value="Save Changes" reRender="out,btnAddSOI,btnAddSOI_small,tablePnl,msgs, fOppId" status="saveStatus" disabled="{!so.ERP_Company_Id__c == ''}"/>

 

 

Keep in mind that I have added other stuff to the page so the same code that was before may now be a litle different, but the basic functionality in question is the same.

This was selected as the best answer
mauricio.ramosmauricio.ramos

Hello,

 

I am posting my final code in order for it to be of use to anyone experiencing the same issue. I have solved this some time ago but did not get to the solution without much trial and error. I cannot recall the exact solution I found but I will paste the relevant code that is working so anyone can reference it. See below:

 

 

The button in question:

 <apex:pageBlockButtons location="top" >
        <apex:commandButton value="Add New" action="{!AddSOI}" rerender="tablePnl,detailPanel"  disabled="{!so.id == null}" id="btnAddSOI"  status="loadingStatus" />
    </apex:pageBlockButtons>  

 The button that should fire the rerender:

<apex:commandButton action="{!saveSO}" value="Save Changes" reRender="out,btnAddSOI,btnAddSOI_small,tablePnl,msgs, fOppId" status="saveStatus" disabled="{!so.ERP_Company_Id__c == ''}"/>

 

 

Keep in mind that I have added other stuff to the page so the same code that was before may now be a litle different, but the basic functionality in question is the same.