2

This is now working. The illustration and related code snippet is below alongwith the orignal question.

Inspecting the element showed the DOM path does not need the outputPanel nor tab ID's. This path is used as a combination of page, form, pageBlock, pageBlockSection and value.

val1 = parseInt(document.getElementById("{!$Component.page:form1:block1:LOB_CA:LOB_CA1:value1}").value);

Not getting these fields to add up or display if numbers not adding up to 100%. The inputfields are firing the jsctipt via onchange="checkNumbersEnviron();" Is there something wrong with the DOM path I am using on document.getElementById('{!$Component..... ?

enter image description here

<apex:page id="page" standardStylesheets="true" standardController="Account_Summary__c" readOnly="false" extensions="AccountSummaryController" showHeader="true" action="{!redirectCREPage}" >

<script type="text/javascript">
/*
Script checks and prints to output text if numbers add up to 100 or not. 
use of ParseInt will produce a NaN (not a number) condition should the user enter alpha numeric text. 
*/
function checkNumbersEnviron() {

    var val1 = 0;  // Percent Local Radius
    if(document.getElementById("{!$Component.page:form1:block1:LOB_CA:LOB_CA1:value1}") != null)
        val1 = parseInt(document.getElementById("{!$Component.page:form1:block1:LOB_CA:LOB_CA1:value1}").value);
    if(isNaN(val1))
        val1 = 0;

    var val2 = 0; // Percent Intermediate Radius
    if(document.getElementById("{!$Component.page:form1:block1:LOB_CA:LOB_CA2:value2}") != null)
        val2 = parseInt(document.getElementById("{!$Component.page:form1:block1:LOB_CA:LOB_CA2:value2}").value);
    if(isNaN(val2))
        val2 = 0;

    var val3 = 0; // Percent Intermediate Radius
    if(document.getElementById("{!$Component.page:form1:block1:LOB_CA:LOB_CA3:value3}") != null)
        val3 = parseInt(document.getElementById("{!$Component.page:form1:block1:LOB_CA:LOB_CA3:value3}").value);
    if(isNaN(val3))
        val3 = 0; 

    var tot = val1 + val2 + val3;   
    document.getElementById('{!$Component.page:form1:block1:LOB_CA:LOB_CA4:valueTotOpEnvironHidden}').value = tot; // use apex hidden input field to save value for validation rule.
    document.getElementById('{!$Component.page:form1:block1:LOB_CA:LOB_CA5:valueTotOpEnviron}').innerHTML = tot;   // writes to apex output field for UI benefit.  

    if (tot < 100 || tot > 100)  
    {
        document.getElementById('{!$Component.page:form1:block1:LOB_CA:LOB_CA6:answerEnviron}').innerHTML = 'Total percent operating environment not equal to 100.';
    }
    else
    {
        document.getElementById('{!$Component.page:form1:block1:LOB_CA:LOB_CA6:answerEnviron}').innerHTML = 'Total percent operating environment equal to 100.'; 
    }
}
</script>

<apex:form id="form1">
<!-- <apex:sectionHeader title="Comprehensive Risk Evaluation"  help="{!$Resource.Help_MaidenReUWGuidelines}"/> -->
<apex:pageBlock id="block1" dir="" >

<apex:outputPanel id="OutputTabPanel">
<apex:tabPanel switchType="client" selectedTab="name2" id="theTabPanel" headerClass="tabPanel" tabClass="activeTab" inactiveTabClass="inactiveTab" > 
<apex:tab label="Comm Auto" name="tab3" id="tab3"  > 
<apex:outputPanel Style="width:100%;" id="InputTabPanel" layout="block"> 
<apex:pageBlockSection columns="2" id="LOB_CA" title="Commercial Auto" showHeader="false" >



<!-- ********** -->
                <apex:pageBlockSectionItem dataStyleClass="col"  >
                    <apex:outputLabel value="Radius of Operations Breakdown (under construction)" StyleClass="col1" />
                    <apex:outputLabel value=""   /> 
                </apex:pageBlockSectionItem>

                    <apex:pageBlockSectionItem dataStyleClass="col" >
                     <apex:outputLabel value=""   />  
                    </apex:pageBlockSectionItem>
<!-- ********** -->

                <apex:pageBlockSectionItem dataStyleClass="col" id="LOB_CA1" >
                    <apex:outputLabel value="local (0-50 Miles)"  StyleClass="col4"  />
                    <apex:inputField value="{!Account_Summary__c.CA_Operating_Environment_Rural__c}" StyleClass="col2" id="value1" html-value1="value1" onchange="checkNumbersEnviron();" /> 
                </apex:pageBlockSectionItem>

                    <apex:pageBlockSectionItem dataStyleClass="col" >
                        <apex:outputLabel value=""  />  
                    </apex:pageBlockSectionItem>
<!-- ********* -->
                <apex:pageBlockSectionItem dataStyleClass="col" id="LOB_CA2" >
                    <apex:outputLabel value="Intermediate (51-200 Miles)"  StyleClass="col4"  />
                    <apex:inputField value="{!Account_Summary__c.CA_Operating_Environment_Suburban__c}" StyleClass="col2" id="value2" onchange="checkNumbersEnviron();"  /> 
                </apex:pageBlockSectionItem>

                    <apex:pageBlockSectionItem dataStyleClass="col" >
                        <apex:outputLabel value=""  />  
                    </apex:pageBlockSectionItem>
<!-- ********* -->
                <apex:pageBlockSectionItem dataStyleClass="col" id="LOB_CA3" >
                    <apex:outputLabel value="Long Haul (> 200 Miles)"  StyleClass="col4"  />
                    <apex:inputField value="{!Account_Summary__c.CA_Operating_Environment_Urban__c}" StyleClass="col2" id="value3" onchange="checkNumbersEnviron();" /> 
                </apex:pageBlockSectionItem>

                    <apex:pageBlockSectionItem dataStyleClass="col" >
                        <apex:outputLabel value=""  />  
                    </apex:pageBlockSectionItem>
<!-- ********* -->
                <apex:pageBlockSectionItem dataStyleClass="col" id="LOB_CA4" >
                    <apex:outputLabel value=""  StyleClass="col4"  />
                    <apex:inputHidden value="{!Account_Summary__c.Total_Percent_Op_Environ__c}" id="valueTotOpEnvironHidden"  /> 
                </apex:pageBlockSectionItem>

                    <apex:pageBlockSectionItem dataStyleClass="col" >
                        <apex:outputLabel value=""  />  
                    </apex:pageBlockSectionItem>                    
<!-- ********* -->                    
                <apex:pageBlockSectionItem dataStyleClass="col"  id="LOB_CA5" >
                    <apex:outputLabel value="TOTAL"  StyleClass="col4"  />
                    <apex:outputField value="{!Account_Summary__c.Total_Percent_Op_Environ__c}" id="valueTotOpEnviron" StyleClass="col2"   /> 
                </apex:pageBlockSectionItem>

                    <apex:pageBlockSectionItem dataStyleClass="col" >
                        <apex:outputLabel value=""  />  
                    </apex:pageBlockSectionItem>                    
<!-- ********* -->                     
                <apex:pageBlockSectionItem dataStyleClass="col" id="LOB_CA6" >
                    <apex:outputText id="answerEnviron" value="" style="color:blue"   />
                    <apex:outputLabel value=""   /> 
                </apex:pageBlockSectionItem>

                    <apex:pageBlockSectionItem dataStyleClass="col" >
                     <apex:outputLabel value=""   />  
                    </apex:pageBlockSectionItem>
<!-- ********** -->

</apex:pageBlockSection>
</apex:outputPanel> 
</apex:tab>    
</apex:tabPanel> 
</apex:outputPanel>
</apex:pageBlock>
</apex:form>
</apex:page>

2 Answers 2

5

Yes, you have a problem. Every Visualforce parent (elements starting with apex:) between the root of the page and the element in question must have an ID, and must be referenced in $Component. In particular:

<apex:outputPanel Style="width:100%;" layout="block">

This is a parent of LOB_CA, and so needs an ID and needs to be referenced in your $Component merge fields. Alternatively, you can probably remove it or replace it with a simple span or div instead.

I personally prefer using a non-conflicting way of getting to my elements when possible. One way you can avoid the madness of dealing with these ID values could be to use an html pass-through attribute, then query for those instead:

<apex:inputHidden html-data-total-percent-op-environ="x" value="{!Account_Summary__c.Total_Percent_Op_Environ__c}" id="valueTotOpEnvironHidden"  /> 

Which would allow you to write something like this:

var totalPercentOpEnviron = document.querySelector("[data-total-percent-op-environ]").value;

This is compatible with all versions of browsers officially supported by Salesforce, and is a lot easier to manage when you have deeply nested elements as you do here.

2
  • first thing I tried adding id="InputTabPanel" to the outputPanel and referenced it in the JScript $Component. Still not getting the 'value' of the field. Shows as 0 thru the alerts. Updated the source above.
    – rickmac
    Commented Aug 25, 2017 at 16:10
  • Figured it out and updated the post for anyone else. Would be interested to see how you would use pass thru HTML attributes.
    – rickmac
    Commented Aug 25, 2017 at 20:23
2

You can getElementsByTagName to find the input and do the summation and as suggested by sfdcfox assign the tot in the hidden field.

    var tot;
    //identify the table 
    var table = document.getElementById('LOB_CA');
    //retrieve the row count
    var rowCount = table.rows.length;
    for(var i=0; i < rowCount; i++) {        
        var cells = table.rows[i].getElementsByTagName('input');
        alert('cells=' + cells); 
        if(cells.length>0){
            //print the inputField value
            tot = parseInt(cells[0].value);
        }
    }
1
  • thanks. I want to stick with previous VisualForce pages where I've used the same approach.
    – rickmac
    Commented Aug 25, 2017 at 20:24

You must log in to answer this question.

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