1

Below is a snippet of code in which an apex:variable is not increment inside an apex:repeat tag. In this case, the var="rowCount" gets incremented without any issues, but the var="headerCount" does not increment at all. Can anyone provide some insight?

Sample Code

<apex:pageBlock >
      <!-- Tracks the row in the table -->
      <apex:variable var="rowCount" value="{!-1}" />// This variable increments properly
      <apex:variable var="headerCount" value="{!0}" />// This variable does not increment at all

      <apex:pageBlockSection columns="1" title="{!Title}" id="pbSec">
          <apex:pageBlockTable value="{!sObjRecords}" var="sObj" styleClass="dataTable table table-fixedheader" id="pageBlockTable">
              <!-- Displays the multiple columns based on the user input -->

              <apex:repeat value="{!Fields}" var="fld">
                  <apex:column >

                    <apex:outputText value="{!sObj[fld]}"/>

                    <apex:facet name="header">{!headers[headerCount]}</apex:facet>
                      <apex:variable var="headerCount" value="{!headerCount+1}" />
                  </apex:column>
              </apex:repeat>

              <!-- Action Column with buttons - May not be used if attribute is false -->
              <apex:column rendered="{!IsActionColumnEnabled}" >
                  <apex:facet name="header">{!$Label.YAHS_PRT_Action}</apex:facet>
                  <apex:repeat value="{!Buttons}" var="button">

                  <apex:variable var="rowCount" value="{!rowCount+1}" />
8
  • Unless you can relate the two, you need a separate apex:repeat for header since they use different variables.
    – crmprogdev
    Jun 28, 2016 at 18:45
  • If I understand you correctly, they are under different repeat tags. <apex:repeat value="{!Fields}" var="fld"> and <apex:repeat value="{!Buttons}" var="button">
    – Kevin
    Jun 28, 2016 at 18:46
  • In this case it would be <apex:repeat value="{!headers}" var="hdrs"> or whatever you want to use. Your header is above where the buttons are located. look at where your first apex:repeat ends. You've not posted all of your code, but each repeat requires a close. I may have misunderstood your question, but I was looking at the one above where your buttons start (above the </apex:repeat>).
    – crmprogdev
    Jun 28, 2016 at 18:52
  • Yes, I have a close for all the repeat tags. When I do the repeat as you have suggested, then I seem to get a table within a table, that's why I've been trying to have a param increment.
    – Kevin
    Jun 28, 2016 at 19:17
  • That's why I was saying you need to relate !Fields to !headers. This would normally be done via a wrapper class.
    – crmprogdev
    Jun 28, 2016 at 19:22

3 Answers 3

1

please refer to Salesforce documentation for apex:variable.

Note: apex:variable does not support reassignment inside of an iteration component, such as apex:dataTable or apex:repeat. The result of doing so, e.g., incrementing the as a counter, is unsupported and undefined.

Regardless of few confusions in your code, this design (using variable inside repeat) will never work perfectly and will always leave a possibility for random failures.

I suggest you to use apex:repeat as it was originally intended - as a repeat over a collection of elements. There is always other way to iterate over something then incrementing a apex:variable.

2
  • How do you recommend I increment a value via the VF page then? Any suggestions?
    – Kevin
    Jun 29, 2016 at 13:23
  • I prefer not to do that. What is the actual problem you are trying to solve? As I understand, value rowCount will be equal to {!Buttons.size()} and headerCount will be equal to {!Fields.size()}.
    – Andrei.Z
    Jun 29, 2016 at 15:57
0

The safe way to retrieve a value from a collection of values inside <apex:repeat> is to use a Map, e.g. Map<String, String> in your case, where the key is the field name and the value is the header for the field. Maps use the same syntax in VisualForce as Lists, so your code looks something like:

<apex:repeat value="{!myList}" var="myVar">
    <apex:outputText value="myMap[myVar]" />
</apex:repeat>

Unfortunately, I don't know of any obvious way to duplicate this functionality without a custom controller or extension. If the value you are iterating over happens to be a primitive or you only need an iterating number, you can use Javascript to get similar functionality:

<script>
    var myVarList = new Array();
    var iteratorForList = 0;
    <apex:repeat value="{!myVarList}" var="myVar">
        myVarList.push('{!myVar}');
    </apex:repeat>
</script>
<apex:repeat value="{!otherControllerList}" var="myOtherVar">
    <apex:outputText id="textPlacer" />
    <script>
        document.querySelector('#{!$Component.textPlacer}').innerText = myVarList[iteratorForList];
        iteratorForList++;
    </script>
</apex:repeat>
0

You could simply re-declare the variable at the end of your repeat iteration and increment it within the repeat like this...

    <apex:variable var="iter" value="1" />
    <apex:repeat value="{!myList}" var="lis">
        .... all your page elements here

        <apex:variable value="{!iter+ 1}" var="iter" />
    </apex:repeat>

this has worked for me in the past.

You must log in to answer this question.

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