0

I've got a visualforce page with javascript formulas totaling the rows at the bottom. I've recently added the ability to add a row to the page by clicking a button. However the size of my list (!PayrollDistributionList.size) is not increasing in my formulas when I do that (unless I "save" and refresh the page), so my column total ends up incorrect, and it doesn't iterate over the new row. Can someone provide some guidance, on how to get the size of the new list after I add the row?

My page:

<apex:page standardController="Payroll_Authorization__c" sidebar="false" doctype="html-5.0" standardStylesheets="false" extensions="PayrollAuthorization_extn" applyBodyTag="true" lightningStylesheets="true">
<head>
  <meta charset="utf-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1"/>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"/>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
  <style>
      .form-control {
          padding: 6px !important;
      }
      .btn-info {
        color: #fff!important;
        background-color: #5bc0de !important;
        border-color: #46b8da !important;
        background-image: none !important;
        padding: 8px 20px !important;
    }
     .table>thead>tr>th{
            vertical-align: top !important;
            text-align: left !important;
      }
      .table>tbody>tr>td{
            vertical-align: top !important;
            text-align: left !important;
      }
      .table>tbody>tr>td, .table>tbody>tr>th, .table>tfoot>tr>td, .table>tfoot>tr>th, .table>thead>tr>td, .table>thead>tr>th {
            padding: 4px !important;
        }
        .list-group-item {
            padding: 6px 15px !important;
        }
  </style>
    <script>

    function calctotal(){
          alert ("caltotal" + {!PayrollDistributionList.size}); 
          var tempRowTotal=0;
          var percenttotal= 0;
        for(var i=1; <b>i<={!PayrollDistributionList.size};i++ </b>){

              tempRowTotal = ($('.wh'+i).val()!= null && $('.wh'+i).val() != '')?parseFloat($('.wh'+i).val()):0.0;
              percenttotal  += tempRowTotal;

            }
        return percenttotal;   
    }

    function calcRow(){
          alert ("calrow"); 

        var tempRowTotal=0;
         var percenttotal= 0;
           percenttotal= calctotal(); 
        for(var i=1; i<={!PayrollDistributionList.size};i++ ){  
          tempRowTotal = ($('.wh'+i).val()!= null && $('.wh'+i).val() != '')?parseFloat($('.wh'+i).val()):0.0;
          $('.wp' + i).text(((tempRowTotal * 100)/percenttotal).toFixed(2)+'%');
          $('.percenttotal').text(percenttotal.toFixed(2)+'%');     
          }
      }

    $(document).ready(function(){
              {
                  calcRow();
              }

      });
    </script>
    </head>
<body>
    <apex:form >
        <apex:pageBlock title="Payroll Distribution" id="er" >
        <div align="center" draggable="false" style="font-size:13px; margin-bottom:4px"  >
            <apex:commandButton value="Save" action="{!SavePA}" styleclass="btn btn-info" style="" />&nbsp;&nbsp;
            <apex:commandButton value="Cancel" action="{!Cancel}" styleclass="btn btn-info" immediate="true"/>
        </div>
        <div class="container-flud" style="font-size: 11.5px;">
            <apex:pageMessages ></apex:pageMessages>
            <div class="col-md-12" style="margin-bottom: -15px;">
                <ul class="list-group">      
                    <li class="list-group-item row" style="background-color: #702342;color: #fff;padding: 6px 10px;">
                        <h4 style="margin: 2px 0px;font-size: 12px;font-weight: bolder;">Payroll Authorization</h4>
                    </li>
                </ul>

      <div class="col-md-12" style="margin-bottom: 15px;">
        <ul class="list-group">      
            <li class="list-group-item row" style="background-color: #702342;color: #fff;padding: 6px 10px;">
                <h4 style="margin: 2px 0px;font-size: 12px;font-weight: bolder;">Payroll Distributions</h4>
            </li>
        </ul>
        </div>
    <table class="table table-bordered" >

                <thead>
                <tr>
                <th>
                    Program
                </th>
                <th>
                    Percentage worked
                </th>
                <th>
                    Percentage total
                </th>
              </tr>
                </thead>
                <tbody>
                    <apex:variable value="{!1}" var="index"/>  
                <apex:repeat value="{!PayrollDistributionList}" var="pd">
                    <tr>
                        <td><apex:inputfield value="{!pd.Program__c}"   style="Width: 50%"/></td>
                        <td ><apex:inputfield value="{!pd.Program_Percent__c}" styleClass="wh{!index}" onkeyup="calcRow()"/> </td>
                        <td Class="wp{!index}">
                            0%
                        </td>
                    </tr>
                    <apex:variable value="{!index+1}" var="index"/>

                </apex:repeat>
            </tbody>
        <tfoot> <tr>
                <th>
                </th>
                <th class="percenttotal">
                    0.0%
                </th>
                <th>
                    100.00%
                </th>
              </tr></tfoot>
          </table>
          </div>
        </div>
    <apex:commandButton action="{!addRow}" value="Add Program" immediate="true" reRender="er"/>
        </apex:pageBlock>
        </apex:form>

    </body>
</apex:page>

My extension:

public with sharing class PayrollAuthorization_extn {

    public list <PA_Distribution__c> PayrollDistributionList {get; set;}
    public Payroll_Authorization__c PA;


    public PayrollAuthorization_extn(ApexPages.StandardController controller) {

    PA = (Payroll_Authorization__c)controller.getRecord();
    PayrollDistributionList = [Select Id, Name, Program__r.Name, Program_Percent__c
            From PA_Distribution__c
            Where Payroll_Authorization__r.id =: controller.getId()];  

    }

    public void addRow(){
        PayrollDistributionList.add(new PA_Distribution__c( Payroll_Authorization__c = PA.id));
    }

    public void SavePA (){
        upsert PA; 
        upsert PayrollDistributionList;
    }


}

2 Answers 2

1

You are using the list from controller directly in JavaScript, on load it has correct value as its being rendered/loaded.

When you add call controller property to add a row, value in JavaScript is not refreshed automatically.

You have couple of options:

  1. Easiest is to rerender script on calling command button:

    <apex:outputPanel id="scriptPanel"/>
        <script>
            // your code, here you would get refreshed value
        </script>
    </apex:outputPanel>
    
    <!-- add rerender to script panel -->
    <apex:commandButton action="{!addRow}" value="Add Program" 
        immediate="true" reRender="er, scriptPanel"/>
    
    • Note: Here make sure to remove document.ready() outside the script panel which is reloaded every time, otherwise it would fire as well.
  2. Use a apex:inputHidden and oncomplete event on apex:commandButton:

    <script>
        function calcRow() {
            // access listsize as
            $( "input[name$='listsize']" ).val()
        }
    </script>
    <apex:pageBlock title="Payroll Distribution" id="er" >
        <!-- hidden input would be refreshed -->
        <apex:inputHidden value="{!PayrollDistributionList.size}" id="listsize"/>
        <!-- adding oncomplete -->
        <apex:commandButton action="{!addRow}" value="Add Program" 
            immediate="true" reRender="er" oncomplete="calcRow()"/>
    </apex:pageBlock>
    
0

You could try updating your current visualforce code to the following and see if that works. The Listsize is a variable in the extension that is set to the size of the list. Also you will see that I updated the code so that the size property of the List is not asked for in the javascript. It is parsed from the string value of the Listsize variable. Let me know if you have any questions.

<apex:page standardController="Payroll_Authorization__c" sidebar="false" doctype="html-5.0" standardStylesheets="false" extensions="PayrollAuthorization_extn" applyBodyTag="true" lightningStylesheets="true">
<head>
  <meta charset="utf-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1"/>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"/>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
  <style>
      .form-control {
          padding: 6px !important;
      }
      .btn-info {
        color: #fff!important;
        background-color: #5bc0de !important;
        border-color: #46b8da !important;
        background-image: none !important;
        padding: 8px 20px !important;
    }
     .table>thead>tr>th{
            vertical-align: top !important;
            text-align: left !important;
      }
      .table>tbody>tr>td{
            vertical-align: top !important;
            text-align: left !important;
      }
      .table>tbody>tr>td, .table>tbody>tr>th, .table>tfoot>tr>td, .table>tfoot>tr>th, .table>thead>tr>td, .table>thead>tr>th {
            padding: 4px !important;
        }
        .list-group-item {
            padding: 6px 15px !important;
        }
  </style>
    <script>

    function calctotal(){
          alert ("caltotal" + {!Listsize}'); 
          var tempRowTotal=0;
          var percenttotal= 0;
          var size = parseInt('{!Listsize}', '10');
        for(var i=1; <b>i<=size;i++ </b>){

              tempRowTotal = (jQuery('[id$=wh'+i+']').val()!= null && jQuery('[id$=wh'+i+']').val() != '')?parseFloat(jQuery('[id$=wh'+i+']').val()):0.0;
              percenttotal  += tempRowTotal;

            }
        return percenttotal;   
    }

    function calcRow(){
          alert ("calrow"); 

        var tempRowTotal=0;
         var percenttotal= 0;
           percenttotal= calctotal(); 
           var size = parseInt('{!Listsize}', '10');
        for(var i=1; i<=size;i++ ){  
          tempRowTotal = (jQuery('[id$=wh'+i+']').val()!= null && jQuery('[id$=wh'+i+']').val() != '')?parseFloat(jQuery('[id$=wh'+i+']').val()):0.0;
          jQuery('[id$=wp'+i+']').text(((tempRowTotal * 100)/percenttotal).toFixed(2)+'%');
          jQuery('[id$=percenttotal]').text(percenttotal.toFixed(2)+'%');     
          }
      }
    </script>
    </head>
<body>
    <apex:form >
        <apex:pageBlock title="Payroll Distribution" id="er" >
        <div align="center" draggable="false" style="font-size:13px; margin-bottom:4px"  >
            <apex:commandButton value="Save" action="{!SavePA}" styleclass="btn btn-info" style="" />&nbsp;&nbsp;
            <apex:commandButton value="Cancel" action="{!Cancel}" styleclass="btn btn-info" immediate="true"/>
        </div>
        <div class="container-flud" style="font-size: 11.5px;">
            <apex:pageMessages ></apex:pageMessages>
            <div class="col-md-12" style="margin-bottom: -15px;">
                <ul class="list-group">      
                    <li class="list-group-item row" style="background-color: #702342;color: #fff;padding: 6px 10px;">
                        <h4 style="margin: 2px 0px;font-size: 12px;font-weight: bolder;">Payroll Authorization</h4>
                    </li>
                </ul>

      <div class="col-md-12" style="margin-bottom: 15px;">
        <ul class="list-group">      
            <li class="list-group-item row" style="background-color: #702342;color: #fff;padding: 6px 10px;">
                <h4 style="margin: 2px 0px;font-size: 12px;font-weight: bolder;">Payroll Distributions</h4>
            </li>
        </ul>
        </div>
    <table class="table table-bordered" >

                <thead>
                <tr>
                <th>
                    Program
                </th>
                <th>
                    Percentage worked
                </th>
                <th>
                    Percentage total
                </th>
              </tr>
                </thead>
                <tbody>
                    <apex:variable value="{!1}" var="index"/>  
                <apex:repeat value="{!PayrollDistributionList}" var="pd">
                    <tr>
                        <td><apex:inputfield value="{!pd.Program__c}"   style="Width: 50%"/></td>
                        <td ><apex:inputfield value="{!pd.Program_Percent__c}" styleClass="wh{!index}" onkeyup="calcRow()"/> </td>
                        <td Class="wp{!index}">
                            0%
                        </td>
                    </tr>
                    <apex:variable value="{!index+1}" var="index"/>

                </apex:repeat>
            </tbody>
        <tfoot> <tr>
                <th>
                </th>
                <th class="percenttotal">
                    0.0%
                </th>
                <th>
                    100.00%
                </th>
              </tr></tfoot>
          </table>
          </div>
        </div>
    <apex:commandButton action="{!addRow}" value="Add Program" immediate="true" reRender="er"/>
        </apex:pageBlock>
        </apex:form>

    </body>
</apex:page>

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.