2

I am displaying a list of wrappers on a Visualforce search page using the table html tag and apex:repeat. The wrapper is an easy way to work with a list of PriceBookEntries and other attributes like quantity. When I display a simple list of PriceBookEntries, my rerender works fine and the search results section completely rerenders based on the search input. However, when I instead display the list with my wrappers, the search results add to the end of the list and the section does not rerender.

I can't figure out what is going on!

This works:

        <!-- Search Box -->
        <apex:outputPanel id="searchSection">
            <div class="container">
                <div class="well" id="searchBox">
                    <div class="row">
                        <div class="col-md-6">
                            <span id="helpBlock" class="help-block">Please search by Product Name</span>
                            <apex:inputText styleClass="typeahead form-control" value="{!searchText}" id="userinput" >
                                <apex:actionSupport event="onchange" action="{!reset}" reRender="products"/>
                            </apex:inputText>

                            <span class="input-group-btn">
                                    <apex:commandButton value="Search" action="{!search}" styleClass="btn btn-default" reRender="products,errorPanel">
                                        <apex:actionFunction name="search" action="{!search}" rerender="products,errorPanel"/>
                                    </apex:commandButton>
                            </span>  
                        </div>                 
                    </div>
                </div>
            </div>
        </apex:outputPanel>

<!-- Available Products -->
<apex:outputPanel id="products">
    <div class="container">
        <div class="well col-md-12"> 
            <div class="row">                                                                                     
                        <h4 style="padding-left:16px">Available Products</h4>
                            <div class="col-lg-8">                                                                   
                                <div class="table table-responsive">
                                    <table class="table table-condensed table-hover" id="availableProducts">
                                        <tr class="info">
                                            <th>Product Name</th>
                                            <th>Product Type</th>
                                            <th>Description</th>
                                            <th>Unit Price</th>
                                            <th>Quantity</th>
                                            <th>Dimensions</th>
                                            <th></th>
                                        </tr>
                                        <apex:repeat value="{!products}" var="prod"> <!--this is a list of PriceBookEntries -->
                                            <tr>
                                                <td>{!prod.name}</td>
                                                <td>{!prod.product2.recordtype.name}</td>
                                                <td>{!prod.product2.description}</td>
                                                <td>£{!prod.unitprice}</td>
                                                <td><apex:input id="quantity" value="{!selectedQuantity}" type="number" html-min="0" html-max="10">
                                                <apex:actionSupport event="onmouseout" reRender="products" action="{!filter}"/></apex:input>
                                                </td>
                                                <td>height<apex:inputField id="seconddim" value="{!prod.product2.length__c}" type="number" html-min="0" html-max="100"/>columns<apex:inputField id="firstdim" value="{!prod.product2.width__c}" type="number" html-min="0" html-max="100"/></td>
                                                <td>{!selectedQuantity}</td>
                                                <td><apex:commandLink id="btn" action="{!addProduct}" value="Select" styleClass="btn btn-primary btn-sm" style="color:white" >
                                                <apex:param id="selectId" name="selectId" value="{!prod.Product2Id}" assignTo="{!selectedProductId}" />
                                                <apex:param id="selectedquantity" name="selectedquantity" value="{!selectedQuantity}" assignTo="{!tempQuantity}" />
                                                </apex:commandLink></td>
                                            </tr>
                                        </apex:repeat>
                                    </table>
                                    <nav>
                                      <ul class="pager">
                                        <li><a href="#">Previous</a></li>
                                        <li><a href="#">Next</a></li>
                                      </ul>
                                    </nav>
                                </div>                                        
                            </div>                           
                    </div>
            </div>
        </div>
    </apex:outputPanel>

This does not work (the search results only make the table larger, rather than refreshing the results):

   <apex:repeat value="{!productWrappers}" var="prod">
                                            <tr>
                                                <td>{!prod.name}</td>
                                                <td>{!prod.recordTypeName}</td>
                                                <td>{!prod.description}</td>
                                                <td>£{!prod.unitprice}</td>
                                                <td><apex:input id="quantity" value="{!prod.quantity}" type="number" html-min="0" html-max="10">
                                                <apex:actionSupport event="onmouseout" reRender="products" action="{!tempMethod}" status="fetchStatus"/></apex:input>
                                         <apex:outputPanel style="color:#4AA02C;font-weight:bold">
                                            <apex:actionStatus id="fetchStatus" startText="Please wait..." stopText=""/>
                                        </apex:outputPanel>
                                                </td>
                                                <td>{!prod.height} x {!prod.columns}</td>
                                                <!--<td>height<apex:input id="seconddim" value="{!prod.height}" type="number" html-min="0" html-max="100"/>columns<apex:input id="firstdim" value="{!prod.columns}" type="number" html-min="0" html-max="100"/></td>-->
                                                <td><apex:commandLink id="btn" action="{!addProduct}" value="Select" styleClass="btn btn-primary btn-sm" style="color:white" >
                                                <apex:param id="selectId" name="selectId" value="{!prod.pbeId}" assignTo="{!selectedProductId}" />
                                                <apex:param id="selectedquantity" name="selectedquantity" value="{!prod.quantity}" assignTo="{!tempQuantity}" />
                                                </apex:commandLink></td>
                                            </tr>
                                        </apex:repeat>

My wrapper class:

/*
* Pricebookentry Wrapper Class
* @params: PriceBookEntry p
*/
public class productWrapper {
    public String pbeId {get; set;}
    public String productId {get; set;}
    public String name {get; set;}
    public Decimal unitPrice {get; set;}
    public String description {get; set;}
    public Decimal salesPrice {get; set;}
    public Integer quantity {get; set;}
    public String recordTypeName {get; set;}
    public Decimal height {get; set;}
    public Decimal columns {get; set;}

    public productWrapper(Id pricebookentryId){
        PriceBookEntry p = [select id,product2id,name,unitprice,product2.description,product2.recordtype.name,product2.length__c,product2.width__c from PriceBookEntry where id=:pricebookentryId];
        this.pbeId = p.Id;
        this.productId = p.Product2Id;
        this.name = p.name;
        this.unitPrice = p.UnitPrice;
        this.description = p.Product2.Description;
        this.recordTypeName = String.valueOf(p.product2.recordtype.name);
        this.height = p.product2.length__c;
        this.columns = p.product2.width__c;
    }
}

And the method to call it:

/*
* Returns list of product wrappers for 'products' section of VF page
* @params: list<Pricebookentry> pbes
*/
public list<productWrapper> getProductWrappers(list<PriceBookEntry> pbes){

    for(PriceBookEntry pbe : pbes){
        productWrapper pwrap = new productWrapper(pbe.id);
        productWrappers.add(pwrap);
    }   
    return productWrappers;
}

2 Answers 2

1

For anyone else who comes across this post - I also posted it to Developerforce and received the solution from Bob Buzzard: https://developer.salesforce.com/forums/ForumsMain?id=906F0000000BHfzIAG

You must clear the wrapper list prior to the for loop:

    public list<productWrapper> getProductWrappers(list<PriceBookEntry> pbes){
    productWrappers.clear();
    for(PriceBookEntry pbe : pbes){
        productWrapper pwrap = new productWrapper(pbe.id);
        productWrappers.add(pwrap);
    }  
    return productWrappers;
 }
0

The problem occurs because you are doing SOQL Query in for loop. productWrapper pwrap = new productWrapper(pbe.id); You have created productWrapper class and it his constructor you fetching data. I think you are getting 101 error message.

Thanks,

1
  • Nope - the SOQL query in the for loop is obviously not a good idea, but I am not receiving a 101 query exception. I have removed the SOQL query but the problem is still the same. Commented May 6, 2015 at 10:05

You must log in to answer this question.

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