I've been struggling with this for a few days now. I have a Visualforce page that should trigger a search method on the controller. When the method returns the page should render the result. The problem is that although the method is triggered and executes fine the page does not rerender the results. It seems the whichPanelToRender attribute although set to the right value does not maintain the value when the component refreshes. Any suggestions?
This is the page code:
<apex:page controller="PortfolioCatalogController" title="NICE" sidebar="false" showHeader="false" id="NicePortfolioCatalogMain">
<apex:stylesheet ..."/>
<apex:includeScript ...}"/>
<script type="text/javascript">
$(document).ready(function()
{
MainPage.init();
});
</script>
<div id="headerContainer" class="clearfix">
<div id="header" class="clearfix">
...
</div>
</div>
<div id="pageWrapper" class="clearfix">
<div id="sideBarCollapsedTrigger"></div>
<div id="sideBar">
...
</div>
<apex:form id="theForm">
<div id="mainContentDiv" class="mainContentDiv_small">
<div id="{!IF(whichPanelToRender == 'MAIN', 'mainContentTop', 'mainContentTop_short')}">
<apex:outputPanel id="breadCrumbs" layout="block" rendered="{!whichPanelToRender == 'SEARCH_RESULT'}">
<a href="CatalogMain">home</a>search results
</apex:outputPanel>
<div id="{!IF(whichPanelToRender == 'MAIN', 'searchDiv', 'searchDiv_inner_page')}">
<div id="searchContainer">
<input class="searchInput" type="text" name="searchField" id="searchField" placeholder="Search" />
<input type="image" name="submit" id="searchSubmit" onclick="doSomeSearch();" src="{!URLFOR($Resource.nice_portfolio_catalog)}/images/emptyGif.gif" border="0"/>
<apex:actionFunction name="doSomeSearch" action="{!doSearch}" immediate="true" reRender="bottomMiddleSection">
<apex:param name="firstParam" assignTo="{!searchTerms}" value=""/>
</apex:actionFunction>
</div>
</div>
</div>
<div id="mainContentBottom">
<apex:outputPanel id="bottomMiddleSection" styleClass="bottomMiddleSection_small">
<script type="text/javascript">
//for debug
alert('{!whichPanelToRender}');
</script>
<apex:outputPanel rendered="{!whichPanelToRender == 'SEARCH_RESULT'}" id="theSearchResultsPanel" layout="block">
<table cellpadding="0" cellspacing="0" border="0" width="100%">
<tr>
<td height="32"></td>
</tr>
<tr>
<td width="100%" valign="top">
<div class="pageMainContentContainer">
<h3 class="pageTitle">Search results <span class="searchResultsNumber">({!howManyResults})</span></h3>
<div class="titleUnderline"></div>
<apex:repeat value="{!searchResults}" var="searchResult" id="allSearchResultsRepeat">
<apex:repeat value="{!searchResult}" var="objectSearchResult" id="objectSearchResultsRepeat">
<apex:dataList value="{!objectSearchResult}" var="singleSearchResult" id="singleSearchResultsRepeat">
<apex:outputLink value="{!singleSearchResult.Name}" id="aSearchResultName" styleClass="searchItemIL_title solution_ItemBullet">{!singleSearchResult.Name}</apex:outputLink>
<apex:outputText value="{!singleSearchResult.Description__c}" id="aSearchResultContent" styleClass="searchItemContent"/>
</apex:dataList>
</apex:repeat>
</apex:repeat>
</div>
</td>
</tr>
</table>
</apex:outputPanel>
<apex:outputPanel rendered="{!whichPanelToRender == 'MAIN'}" id="theMainPanel" layout="block">
<table cellpadding="0" cellspacing="0" border="0">
</table>
</apex:outputPanel>
</apex:outputPanel>
<div id="bottomRightSection">
<a href="#"><apex:image url="{!URLFOR($Resource.nice_portfolio_catalog, 'images/marketingBanner.jpg')}"/></a>
</div>
</div>
</div><!--mainContentDiv-->
</apex:form>
</div><!--pageWrapper-->
</apex:page>
This is the controller:
public class PortfolioCatalogController{
private final Portfolio_Catalog_Item__c catalogItem;
private transient static String basicInfoFields = 'Id, Name';
private transient static String Portfolio_Catalog_Item_extendedInfoFields = 'Id, Name, Full_Name__c, Item_Type__c, Value_Proposition__c, Parent_Item__c, Containing_Catalog_Item__c, Buyer__c, Base_Pricing_Model__c';
public PortfolioCatalogController(){
howManyItemsInSection = 5;
whichPanelToRender = PanelNames.MAIN.Name();
}
public enum PanelNames {MAIN, SEARCH_RESULT}
public String whichPanelToRender{get;set;}
public ID catalogItemId{get;set;}
public integer howManyItemsInSection{get;set;}
public String searchTerms{get;set;}
public List<List<Portfolio_Catalog_Item__c>> searchResults{get;set;}
public integer howManyResults{
get{
if(searchResults == null)
return 0;
return searchResults.size();
}
set;
}
public PageReference doSearch(){
String searchTerm = 'product';//hard coded for clarity
whichPanelToRender = PanelNames.SEARCH_RESULT.Name();
if(searchTerm == null || String.isBlank(searchTerm)){
system.debug(LoggingLevel.WARN, 'search terms is blank');
}
String[] searchTermList = String.escapeSingleQuotes(searchTerm).split(' ');
for(integer i = 0; i < searchTermList.size(); i++){
searchTermList[i] = searchTermList[i].deleteWhitespace();
if(searchTermList[i].isWhitespace())
searchTermList.remove(i);
}
String findSearchQuery = '';
//create SOSL FIND string from search terms
for(integer i = 0; i < searchTermList.size(); i++){
findSearchQuery += searchTermList[i];
if(i != searchTermList.size() -1)
findSearchQuery += ' OR ';
}
String queryString = 'FIND \'' + findSearchQuery + '\' IN ALL FIELDS RETURNING Portfolio_Catalog_Item__c(id, Name, Value_Proposition__c, Description__c)';
System.debug(LoggingLevel.DEBUG, queryString);
try{
searchResults = search.query(queryString);//List<List<Portfolio_Catalog_Item__c>>
}
catch(Exception e){
System.debug(LoggingLevel.WARN, e);
//return new List<List<Portfolio_Catalog_Item__c>>();
}
return null;
}
}
Attribution to: Dedo
Possible Suggestion/Solution #1
This could be due to the fact that your outputpanel isn't initially rendered, and when you try to rerender it later on, the outputpanel (in reality a div) doesn't exist in the dom, and the component cannot be found for a rerender.
what you could do is: put your outputpanel in another outputpanel, and have the outer outputpanel initially rendered, and apply your rerender to that panel
Attribution to: pjcarly
Possible Suggestion/Solution #2
I think you are supposed to re-render theSearchResultsPanel
and not the div id bottomMiddleSection
. Apex usually re-renders only apex components and not the html ones. The rendering condition will be checked on re-rendering.
Attribution to: Vignesh Damodharan
Possible Suggestion/Solution #3
Change the divs that are getting rerendered to apex:outputPanels
. There is no attribute of div called rerender. The rerender is an attribute of some of the Visualforce components.
Change
<div id="bottomMiddleSection">
....content....
</div>
to
<apex:outputPanel layout="block" id="bottomMiddleSection">
....content....
</apex:outputPanel>
Check out the apex:outputPanel documentation. When you specify layout="block"
Visualforce generates a div.
Check out the apex:commandButton documentation, specifically the rerender attribute documentation.
The ID of one or more components that are redrawn when the result of an AJAX update request returns to the client. This value can be a single ID, a comma-separated list of IDs, or a merge field expression for a list or collection of IDs.
An HTML div tag is not a Visualforce component.
Attribution to: Peter Knolle
Possible Suggestion/Solution #4
I think that
<div id="{!IF(whichPanelToRender == 'MAIN', 'mainContentTop', 'mainContentTop_short')}">
is outside all rerender regions, so is never evaluated more than once ( frist page load)
I often get stuck debugging rerender issues and my current strategy is to rerender the top-most form "theForm" from everywhere on the page, then verify all functionality is correct, and only then will i attempt to re-render individual sections.
Optimize last, imho.
Attribution to: VNE_Hess
This content is remixed from stackoverflow or stackexchange. Please visit https://salesforce.stackexchange.com/questions/5514