0

I am trying to display an output field value in VF page before saving the record. If user select checkIn & checkOut date (both are date field), display the "Length of stay". Length of Stay is a formula field which is equal to (Check out date - check in date). Data is successfully saved as expected after clicking SAVE button, but I want the Length of Stay value to be shown in VF before saving the record (partialrelaod of the page)

enter image description here

Below is whatever I have tried so far (no error in any code):

Method 1: VF

<table id="check-table">
<thead> <td style="font-weight:bold"> Check In </td>       <td style="font-weight:bold"> Check Out </td> <td> </td> <td></td> </thead>                       
<tr>
    <td> <c:NoDateLink > <apex:inputField value="{!objectReservation.Check_In__c }" id="startdate" style="width:10rem; margin-right:1rem;"  /> </c:NoDateLink> </td> <!--  rerender="lengthOfStay" background:url('DateIcon.png'); background-size: 1px 2px; background-repeat: no-repeat; -->
    <apex:actionRegion >
        <apex:outputPanel >
            <td><c:NoDateLink > <apex:inputField value="{!objectReservation.Check_Out__c }"   id="enddate" style="width:10rem;"  > 
                <apex:actionSupport event="onchange" rerender="lengthOfStay"   />                                  
                </apex:inputField> </c:NoDateLink> </td>   
        </apex:outputPanel>
    </apex:actionRegion>
    <td style="padding:0 2rem 0 2rem;" >  Length of Stay </td>
    <td >  <apex:outputField value="{!objectReservation.Length_of_Stay__c}" id="lengthOfStay"/> </td>
</tr>

No error in VF page, but, onchange in CheckOut field, nothing changes.

Method 2: I also tried to put value from Apex class, but not sure about the syntax as follow: Apex:

public void onChangeFnCall(){
    if(objectReservation.Check_Out__c  != null){

        Integer numberOfStay = (objectReservation.Check_In__c).daysBetween(objectReservation.Check_Out__c);
//      objectReservation.Length_of_Stay__c = numberOfStay;
    }

VF

<table id="check-table">
<thead> <td style="font-weight:bold"> Check In </td>       <td style="font-weight:bold"> Check Out </td> <td> </td> <td></td> </thead>                       
<tr>
    <td> <c:NoDateLink > <apex:inputField value="{!objectReservation.Check_In__c }" id="startdate" style="width:10rem; margin-right:1rem;"  /> </c:NoDateLink> </td> <!--  rerender="lengthOfStay" background:url('DateIcon.png'); background-size: 1px 2px; background-repeat: no-repeat; -->
    <apex:actionRegion >
        <apex:outputPanel >
            <td><c:NoDateLink > <apex:inputField value="{!objectReservation.Check_Out__c }"   id="enddate" style="width:10rem;"  > 
                <apex:actionSupport event="onchange" action="{!onchangefncall}" rerender="lengthOfStay"   />                                  
                </apex:inputField> </c:NoDateLink> </td>   
        </apex:outputPanel>
    </apex:actionRegion>
    <td style="padding:0 2rem 0 2rem;" >  Length of Stay </td>
    <td >  <apex:outputField value="{!objectReservation.Length_of_Stay__c}" id="lengthOfStay"/> </td>
</tr>

1
  • you have to write custom logic(same as formula field) in vf to display values ..
    – Ratan Paul
    Dec 11, 2016 at 7:47

2 Answers 2

1

Edit: It's also possible that the actionRegion is causing the failure, or the NoDateLink component.

  • Make sure you're using renderRegionOnly="false", otherwise the length of stay field will be outside the scope of the action.

  • Make sure you're not removing Visualforce elements from the DOM, because Bad Things can happen.

  • Try a more basic version, as demonstrated below, then add in functionality you're trying to achieve until it breaks.


You need some Apex Code, because formulas only recalculate during certain phases, such as when a record is loaded from the database. There's a method to force recalculation, though, that would solve your problem:

public void recalculateValues() {
  objectReservation.recalculateFormulas();
}

Just set the apex:actionSupport event handler as follows:

<apex:actionSupport action="{!recalculateValues}"
                    event="onchange" 
                    rerender="lengthOfStay" />

Basic minimum working version:

public class recalcController {
    SObject record;

    public recalcController(ApexPages.StandardController controller) {
        record = controller.getRecord();
    }

    public void recalculateFormulas() {
        record.recalculateFormulas();
    }
}

<apex:page standardController="Reservation__c" extensions="recalcController">
    <apex:form>
        <apex:pageBlock>
            <apex:pageBlockSection>
                <apex:inputField value="{!Reservation__c.Start__c}">
                    <apex:actionSupport event="onchange" action="{!recalculateFormulas}" reRender="lengthOfStay" />
                </apex:inputField>
                <apex:inputField value="{!Reservation__c.End__c}">
                    <apex:actionSupport event="onchange" action="{!recalculateFormulas}" reRender="lengthOfStay" />
                </apex:inputField>
                <apex:outputField id="lengthOfStay" value="{!Reservation__c.Duration__c}" />
            </apex:pageBlockSection>
        </apex:pageBlock>
    </apex:form>
</apex:page>
5
  • I tried as you suggest, but again no error, no desired output
    – Tanmoy Das
    Dec 11, 2016 at 15:18
  • @tanmoy It works without the actionRegion, so that might be your problem.
    – sfdcfox
    Dec 11, 2016 at 15:51
  • Thanks for your reply. I am using Custom Controller, I am trying to apply your extension, but syntax error Error: Unknown constructor 'recalcController.recalcController(NewReservationClass controller)'
    – Tanmoy Das
    Dec 11, 2016 at 16:29
  • your code is working good for standard controller :) Can I just copy the EXTENSION code inside my custom controller? What would be the proper way to copy then?
    – Tanmoy Das
    Dec 11, 2016 at 16:30
  • @tanmoy You can copy the function into your controller. I made some additional observations in my answer. It's most likely your actionRegion that's causing the problem.
    – sfdcfox
    Dec 11, 2016 at 16:44
1

I like your method 2. I ain't sure of rest of your page, standard controller, extension, etc. So I tried to replicate the code you have shared. I've tweaked a bit and was able to achieve the result.

Visualforce Page:

<apex:page standardController="LengthOfStay__c" extensions="LengthOfStayExtension" >
    <apex:form >
        <table id="check-table">
        <thead>
            <td style="font-weight:bold"> Check In </td>
            <td style="font-weight:bold"> Check Out </td> 
            <td> </td> 
            <td> </td> 
        </thead>                       
        <tr>
            <apex:actionRegion >
                <td><apex:inputField value="{!los.Check_In__c }" id="startdate" style="width:10rem; margin-right:1rem;"  /> </td>
                <apex:outputPanel >
                    <td>
                        <apex:inputField value="{!los.Check_Out__c }"   id="enddate" style="width:10rem;"  > 
                            <apex:actionSupport event="onchange" action="{!onchangefncall}" rerender="lengthOfStay" />                                  
                        </apex:inputField>
                    </td>   
                </apex:outputPanel>
            </apex:actionRegion>

            <td style="padding:0 2rem 0 2rem;" >  Length of Stay </td>
            <td > <apex:outputPanel id="lengthOfStay"> <apex:outputText value="{!numberOfStay}" /> </apex:outputPanel></td>
        </tr>
        </table>
    </apex:form>
</apex:page>

Extension:

public class LengthOfStayExtension 
{
    public LengthOfStay__c los { get;set; }
    public Integer numberOfStay { get;set; }

    public LengthOfStayExtension(ApexPages.StandardController controller) 
    {
        this.los = (LengthOfStay__c)controller.getRecord();
    }

    public void onChangeFnCall()
    {
        if(los.Check_Out__c  != null)
        {
            System.debug('Check In : ' +los.Check_In__c);
            System.debug('Check Out : ' +los.Check_Out__c);
            numberOfStay = (los.Check_In__c).daysBetween(los.Check_Out__c);
        }
    }
}

Notable Changes:
1. Create a objectReservation (I called it "LengthOfStay__c") variable and initialize in the constructor using getRecord method
2. Placed the rerender part inside an output panel and rerendered the panel
2. Displayed the "numberOfStay" value calculated in "onChangeFnCall" on the rerendered part
3. Included the "Check_In__c" inputfield within the actionregion area

I hope this helps you.

3
  • Is there any way to directly show the output field value in the VF page, rather than separately calculate the output field in controller? I need to apply similar logic to another output field which is cross object formula field with picklist (seems like that will be complicated to apply in custom controller)
    – Tanmoy Das
    Dec 11, 2016 at 11:07
  • I am using custom controller in the VF page, tried to add this Extension. but failed. feel like the following line of code need modification for custom controller. public LengthOfStayExtension(ApexPages.StandardController controller)
    – Tanmoy Das
    Dec 11, 2016 at 11:11
  • @tanmoy You can follow the sfdcfox answer to directly get the formula value without any calculation in the controller. Yes, you need to modify the constructor for your custom controller or you can tailor this code snippet and paste.
    – Seesh
    Dec 11, 2016 at 19:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .