+ Start a Discussion
William Woodson 3William Woodson 3 

visualforce pages repeat without value

I want to generate a consistent number or rows in  a table regardless of how many related objects exists (i.e. I want 7 rows even when there is only 3 related list objects).

I was trying to use a repeat without a value attribute to try to just create a generic looping behavior but that does not work.  I am using a standard controller and didn't want to create an extension just to generate the other rows.  Here is the code...
 
<apex:variable var="rowNum" value="{!1}"/>
			<apex:repeat var="f" value="{!sow__c.Facilities__r}" rows="7">  
                <apex:variable var="rowNum" value="{!rowNum + 1}"/>
            	<div class="row">
                <div class="col-7">
                    <div class="row">
                        <div class="bodycell col-4">
                            <span>{!f.Account__r.Name}</span>
                        </div>
                        
                        <div class="bodycell center col-2">
                            <span>
                                <apex:outputText value="{0, number, 0}">
                                    <apex:Param value="{!f.v1__c}" />
                                </apex:outputText>                                
                            </span>
                        </div>
                        
                        <div class="bodycell center col-2">
                            <span>
                                <apex:outputText value="{0, number, 0}">
                                    <apex:Param value="{!f.v2__c}" />
                                </apex:outputText> 
                            </span>
                        </div>
                        
                        <div class="bodycell col-4">
                            <span>{!f.v3__c}</span>
                        </div>
                    </div>
                </div>
                
                <div class="bodycell col-5">
                    <span>{!f.v4__c}</span>
                </div>
            </div>
            </apex:repeat>
            <apex:repeat var="f" rows="{!(7 - rowNum)}">
            	<div class="row">
                <div class="col-7">
                    <div class="row">
                        <div class="bodycell col-4">
                            <span>&nbsp;</span>
                        </div>
                        
                        <div class="bodycell col-2">
                            <span>&nbsp;</span>
                        </div>
                        
                        <div class="bodycell col-2">
                            <span>&nbsp;</span>
                        </div>
                        
                        <div class="bodycell col-4">
                            <span>&nbsp;</span>
                        </div>
                    </div>
                </div>
                
                <div class="bodycell col-5">
                    <span>&nbsp;</span>
                </div>
            </div>
            </apex:repeat>

This does't work and I have scowered google with not resolution, any help would be greatly appreciated.
Best Answer chosen by William Woodson 3
Alain CabonAlain Cabon
Hi,

For dynamic "injection" of HTML code, JQuery is the easiest way.

<apex:variable var="rowNum" value="{!rowNum + 1}"/> is not easy to use in contrast.
<apex:page >
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <apex:slds />
    <table class="slds-table slds-table_cell-buffer slds-table_bordered">
  <thead>
    <tr class="slds-line-seven_reset">
      <th class="" scope="col">
        <div class="slds-truncate" title="Opportunity Name">Opportunity Name</div>
      </th>
      <th class="" scope="col">
        <div class="slds-truncate" title="Account Name">Account Name</div>
      </th>
      <th class="" scope="col">
        <div class="slds-truncate" title="Close Date">Close Date</div>
      </th>
    </tr>
  </thead>
  <tbody>
    <tr class="slds-hint-parent">
      <th data-label="Opportunity Name" scope="row">
        <div class="slds-truncate" title="Cloudhub"><a href="javascript:void(0);" tabindex="-1">Cloudhub</a></div>
      </th>
      <td data-label="Account Name">
        <div class="slds-truncate" title="Cloudhub">Cloudhub1</div>
      </td>
      <td data-label="Close Date">
        <div class="slds-truncate" title="4/14/2015">4/14/2015</div>
      </td>
    </tr>
    <tr class="slds-hint-parent">
      <th data-label="Opportunity Name" scope="row">
        <div class="slds-truncate" title="Cloudhub + Anypoint Connectors"><a href="javascript:void(0);" tabindex="-1">Cloudhub + Anypoint Connectors</a></div>
      </th>
      <td data-label="Account Name">
        <div class="slds-truncate" title="Cloudhub">Cloudhub2</div>
      </td>
      <td data-label="Close Date">
        <div class="slds-truncate" title="4/14/2015">4/14/2015</div>
      </td>
    </tr>
  </tbody>
</table>
<script>
    jQuery.noConflict();  
    jQuery(document).ready(function() {    
            var rowCount = jQuery('tr').length;       
            var markup;
            for (let i=rowCount; i <= 7;i++) {
                markup += "<tr><td>new " + i + "</td><td>new "+i+"</td><td>new "+i+"</td></tr>"
            }
            if (markup) jQuery("table tbody").append(markup);
    });
</script>
</apex:page>

The little script at the end of the page creates the missing rows and append them. 
 

All Answers

Alain CabonAlain Cabon
Hi,

For dynamic "injection" of HTML code, JQuery is the easiest way.

<apex:variable var="rowNum" value="{!rowNum + 1}"/> is not easy to use in contrast.
<apex:page >
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <apex:slds />
    <table class="slds-table slds-table_cell-buffer slds-table_bordered">
  <thead>
    <tr class="slds-line-seven_reset">
      <th class="" scope="col">
        <div class="slds-truncate" title="Opportunity Name">Opportunity Name</div>
      </th>
      <th class="" scope="col">
        <div class="slds-truncate" title="Account Name">Account Name</div>
      </th>
      <th class="" scope="col">
        <div class="slds-truncate" title="Close Date">Close Date</div>
      </th>
    </tr>
  </thead>
  <tbody>
    <tr class="slds-hint-parent">
      <th data-label="Opportunity Name" scope="row">
        <div class="slds-truncate" title="Cloudhub"><a href="javascript:void(0);" tabindex="-1">Cloudhub</a></div>
      </th>
      <td data-label="Account Name">
        <div class="slds-truncate" title="Cloudhub">Cloudhub1</div>
      </td>
      <td data-label="Close Date">
        <div class="slds-truncate" title="4/14/2015">4/14/2015</div>
      </td>
    </tr>
    <tr class="slds-hint-parent">
      <th data-label="Opportunity Name" scope="row">
        <div class="slds-truncate" title="Cloudhub + Anypoint Connectors"><a href="javascript:void(0);" tabindex="-1">Cloudhub + Anypoint Connectors</a></div>
      </th>
      <td data-label="Account Name">
        <div class="slds-truncate" title="Cloudhub">Cloudhub2</div>
      </td>
      <td data-label="Close Date">
        <div class="slds-truncate" title="4/14/2015">4/14/2015</div>
      </td>
    </tr>
  </tbody>
</table>
<script>
    jQuery.noConflict();  
    jQuery(document).ready(function() {    
            var rowCount = jQuery('tr').length;       
            var markup;
            for (let i=rowCount; i <= 7;i++) {
                markup += "<tr><td>new " + i + "</td><td>new "+i+"</td><td>new "+i+"</td></tr>"
            }
            if (markup) jQuery("table tbody").append(markup);
    });
</script>
</apex:page>

The little script at the end of the page creates the missing rows and append them. 
 
This was selected as the best answer
William Woodson 3William Woodson 3
Thank you Alain Cabon, I used a modified version or your example.  I kept the rowNum variable and passed it into the javascript you provided.  I did this because I am using bootstrap grid and there was no easy way I could figure out to count the rows that only pointed to the section I needed to add the rows on.

So anyway thanks!!!
Alain CabonAlain Cabon
Hello,

Interesting feedback (boostrap) .

<apex:variable> is often used (only option at the beginning) but the Salesforce documentation insists that counters based on it will be not reliable.

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 <apex:variable> as a counter, is unsupported and undefined.
https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_compref_variable.htm?search_text=counter

Nevertheless, we often try to increment this variable in VFP despite the warning and that could almost work sometimes.

Many questions here tried to use <apex:variable> as a counter (sometimes that works) but if you master jQuery now that will be always useful for other needs in VFP.
Alain CabonAlain Cabon
jQuery is "just" a simplification of standard operations on the DOM in javascript (not mandatory itself) but it is well received by Salesforce above all in VFP and well documented ( jQuery.noConflict(); is important ).

https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_javascript_libraries.htm