0

I have an apex variable that is the summed value of record amounts in a pageBlockTable. The idea is when an amount value is changed, a javascript function is called to recalculate the amount for all the records in the table, update the apex variable, and re-render the output panel where the variable is displayed. I cannot get this to work, and I have no idea why.

The code I am using:

<apex:page id="AwardsPlanner" standardController="Award__c" recordSetVar="awards" lightningStylesheets="true">
<apex:form>
    <apex:variable var="totalAwards" value="0"/>

    <apex:pageBlock title="Hello, {!$User.FirstName}!">

        <p>Please edit the awards below and save them when you are done.</p>
        <apex:actionFunction name="rerenderOutputPanel" reRender="totalCashAmounts"/>
        <apex:outputPanel title="Total Amount Planned" id="totalCashAmounts">
            <apex:outputText id="totalAmount">Total Cash Amount: {!totalAwards}</apex:outputText>
        </apex:outputPanel>

    </apex:pageBlock>

    <apex:pageBlock title="Your Planned Awards">
        <apex:pageMessages/>

        <apex:pageBlockButtons>
            <apex:commandButton value="Save" action="{!save}"/>
        </apex:pageBlockButtons>

        <apex:pageBlockTable value="{!awards}" var="award" id="awardTable">
            <apex:column value="{!award.Emp_Name__c}"/>
            <apex:column headerValue="Cash Award Value">
                <apex:inputField value="{!award.Cash_Award_Amount__c}" styleClass="cashAwards"
                                 onChange="updateTotal()"/>
            </apex:column>
        </apex:pageBlockTable>

    </apex:pageBlock>
</apex:form>

<script>
    function updateTotal() {
        var currentTotal = 0;
        var awards = document.getElementsByClassName('{!$Component.awardTable.cashAwards}');

        for (var a in awards) {
            currentTotal += parseInt(awards[a].value);
        }

        document.getElementById('totalAwards').value = currentTotal;
        rerenderOutputPanel();
    }
</script>

I have tried a number of different options such as using actionSupport tags and calling the javascript function using the onchange inputfield attribute. Nothing really seems to work, so I'm curious if there's something more fundamental that I'm missing.

Thank you all for your help!

1

There's a few parts of your code that are incorrect.

document.getElementById('totalAwards').value = currentTotal;

You can't get a variable by name; it is a construct that only exists while the server is rendering the page. Instead, you would need a real client-side DOM element to work with.


var awards = document.getElementsByClassName('{!$Component.awardTable.cashAwards}');

$Component is used to refer to a component's ID, not by class; you would normally just want to use querySelectorAll and get the elements in question.


Overall, either do this all in Visualforce, or all in JavaScript. Don't try to get clever. Since it appears you're not using any Apex Code at all, just go with plain JavaScript:

<apex:outputText id="totalAmount">
   Total Cash Amount: <span id="totalAwardsAmount">0.00</span>
</apex:outputText>

function updateTotal() {
  document.getElementById("totalAwardsAmount").innerText =
    Array.prototype.reduce.call(
      document.querySelectorAll(".cashAwards"),
      function(acc, val) {
        return acc + parseFloat(val.value);
      }, 0);
}
  • Yeah, seems like I have a pretty fundamental misunderstanding of Visualforce elements. I did change your solution slightly because I was getting [object HTMLInputElement]00000 returned. So I put the querySelectorAll values into a var and then used Array.prototype.forEach.call() to iterate over the list, which seemed to work. Also, you're right, I'm not using much Apex -- just a standard controller. Haven't quite wrapped my head around controller extensions, yet. But it seemed like sending data to/from the server-side controller was unnecessary for this particular issue. – justinpdove Feb 25 '18 at 21:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.