[SalesForce] use instead of apex:repeat

I need to find the way to use something different than apex:repeat. to assign the
value="{!thousandBlocks} var="block" This is creating multiple tables and i don't want that.

Let me explain you, the class is requesting a large amount of data and i created a wrapper class. and for some reason the vf page is displaying many pageBlockTables and I just want to display just one. My guess is that the apex:repeat is causing this. So I was wondering if there is another apex control that I can use instead of 'repeat' to get the value="{!thousandBlocks} var="block"

I will appreciate any help

VF Page code:

       <apex:pageBlock >

          <apex:repeat value="{!thousandBlocks} var="block"   >

           <apex:pageBlockTable value="{!block.zeroInventory}" var="p" id="mid">
           <apex:column value="{!p.Account__r.Name}"/>
           <apex:column value="{!p.Name}"/>
           <apex:column value="{!p.Product_Name__c}"/>


           </apex:pageBlockTable>
          </apex:repeat>
    </apex:pageBlock>

class:

    public class dashBoardPOIssues {
 private limitWrapper[] thousandBlocks = new limitWrapper[]{};
 private final integer listLimit;  

 public dashBoardPOIssues(){

    //for zero inventory
    listLimit = 950;
 }

  //for zero inventory
  public limitWrapper[] getthousandBlocks()
{
thousandBlocks = new limitWrapper[]{};

integer counter = 0;
integer loopCount = 0;
NRProducts__c[] tmpcase = new NRProducts__c[]{};

for(NRProducts__c c:[SELECT id, Name, Account__r.Name, ASIN__c,CreatedDate,Product_Name__c,Virtual_Amz__c,Total_Inventory2__c,Days_of_Inventory__c,X24_Hr_Units__c,X7_Day_Units__c,X30_Day_Units__c   FROM NRProducts__c  WHERE  Total_Inventory2__c = 0  AND Buyer_lookup__c =:UserInfo.getUserId()])
{
    if(counter < listLimit)
    {
        tmpcase.add(c);
        counter++;
    }
    else
    {
        loopCount++;
        thousandBlocks.add(new limitWrapper(tmpcase,loopCount));
        tmpcase = new NRProducts__c[]{};
        tmpcase.add(c);
        counter = 0;
    }            
  }

if(thousandBlocks.size() == 0)
{
    loopCount++;
    thousandBlocks.add(new limitWrapper(tmpcase,loopCount));
}

return thousandBlocks;
}

 public class limitWrapper
 {
  public NRProducts__c [] zeroinventory {get;set;}
  public integer blockNumber {get;set;}
  public limitWrapper(NRProducts__c[] accs, integer i)
{
    zeroinventory = accs;
    blockNumber = i;
}

}
}

Best Answer

I've answered a similar question some time ago: Add more than 1000 picklist values in visualforce page (controller 1000 list items limit)

You should ask yourself how usable it'll be to display over 1000 records? This suggests it's going to be a dashboard component - that'd be pretty long one...


Your "proper" options:

  1. If it's a readonly display of data then mark the <apex:page readonly="true"> and the limit will go to 10K.
  2. If it's acceptable for you to display some kind of pagination then you should read up on how to use StandardSetController for example.
  3. You could build a listview in that objects tab that meets the filter criteria (Use formula field like in How to create a list view the returns all the records related to a current user? to implement the filter on the Buyer_lookup__c). Once you have that you can simply throw the <apex:enhancedList> at the page, no apex code required, no unit tests to write...
  4. If it's really to be a dashboard component - why not simply build a report?

Your "subprime" ;) option (because even if you'll manage to get it to work you'll hit limits like viewstate or the one you've quoted: "Response size exceeded 15MB") would be to create a List<List<NRProducts__c>> and have 2 nested <apex:repeat>s.

It could look similar to that (I have 36 Opportunities in my Developer Edition):

enter image description here

public class ListLimitWorkaround{
    public ListLimitWorkaround(){}

    public List<List<Opportunity>> getChunkedRecords(){
        Integer sizeLimit = 5;    // flip to 1000
        List<List<Opportunity>> opps = new List<List<Opportunity>>();

        List<Opportunity> temp = new List<Opportunity>();
        for(Opportunity o : [SELECT Id, Name FROM Opportunity]){
            temp.add(o);
            if(temp.size() == sizeLimit){    // limit reached? Then add our current workaround list and spawn new one
                opps.add(temp);
                temp = new List<Opportunity>();
            }
        }
        // We've left the loop? We should check if there are any leftovers in 'temp' that still have to be added
        if(!temp.isEmpty()){
            opps.add(temp);
        }
        return opps;
    }
}

<apex:page controller="ListLimitWorkaround">

<div style="width:50%;float:left;">
    <ol>
        <apex:repeat value="{!chunkedRecords}" var="chunk">
            <apex:repeat value="{!chunk}" var="opp">
                <li>{!opp.Name}</li>
            </apex:repeat>
        </apex:repeat>
    </ol>
</div>
<div style="width:50%;float:left;">
    <ol>
        <apex:repeat value="{!chunkedRecords}" var="chunk">
            <li><ol>
                <apex:repeat value="{!chunk}" var="opp">
                    <li>{!opp.Name}</li>
                </apex:repeat>
            </ol></li>
        </apex:repeat>
    </ol>
</div>
</apex:page>