[SalesForce] How to hide or show (
) items dynamically in a VF Component

I have the below VF Page where I am using pagination to only show 7 records at a time:
enter image description here

The VF component code in the VF page is:

<apex:pageBlock id="navGroup" rendered="true" >
<div align="center">        
    <apex:actionFunction action="{!refreshGrid}" name="queryByPage" reRender="navGroup,myButtons" >
        <apex:param name="firstParam" assignTo="{!selectedPage}" value="" />
    </apex:actionFunction>      
    <apex:dynamicComponent componentValue="{!navButtons}"/>                 
    </div>
    <br/>

and the APEX code in my controller that creates the buttons is:

public Component.Apex.outputPanel getnavButtons() {

    //the reRender attribute is a set NOT a string
    Set<string> theSet = new Set<string>();
    theSet.add('navGroup');
    theSet.add('myButtons');
            
    integer totalPages;
    if (math.mod(total_size, list_size) > 0) {
        totalPages = total_size/list_size + 1;
    } else {
        totalPages = (total_size/list_size);
    }
    
    integer currentPage;        
    if (selectedPage == '0') {
        currentPage = counter/list_size + 1;
    } else {
        currentPage = integer.valueOf(selectedPage);
    }
    
    Component.Apex.outputPanel opPanel = new Component.Apex.outputPanel();
    opPanel.id = 'myButtons';
    
    Component.Apex.OutputText htmlPrevTxtStart = new Component.Apex.OutputText(); 
    htmlPrevTxtStart.value = '<div class="block-link" disabled="{!disablePrevious}" id="PrevButton" onmouseover="ButtonMouseOver(\'PrevButton\');" onmouseout="ButtonMouseOut(\'PrevButton\');" >';     
    htmlPrevTxtStart.escape = false;  
    
    Component.Apex.CommandLink pbLinkPrev = new Component.Apex.CommandLink ();     
    pbLinkPrev.style='color: rgb(255,255,255)';
    pbLinkPrev.expressions.action = '{!Previous}';
    //pbLinkPrev.expressions.disabled = '{!disablePrevious}';  
    pbLinkPrev.value='Previous';
    pbLinkPrev.id = 'mynewButtonsPrev';

    Component.Apex.OutputText htmlPrevTxtEnd = new Component.Apex.OutputText(); 
    htmlPrevTxtEnd.value = '</div>';        
    htmlPrevTxtEnd.escape = false;         
    
    opPanel.childComponents.add(htmlPrevTxtStart);
    opPanel.childComponents.add(pbLinkPrev);
    opPanel.childComponents.add(htmlPrevTxtEnd);        
        // 
    Component.Apex.OutputText htmlNextTxtStart = new Component.Apex.OutputText(); 
    htmlNextTxtStart.value = '<div class="block-link" disabled="{!disablePrevious}" id="nextButton" onmouseover="ButtonMouseOver(\'nextButton\');" onmouseout="ButtonMouseOut(\'nextButton\');" >';     
    htmlNextTxtStart.escape = false; 
    
    Component.Apex.CommandLink pbLinkNext = new Component.Apex.CommandLink ();     
    pbLinkNext.style='color: rgb(255,255,255)';
    pbLinkNext.expressions.action = '{!Next}';
    pbLinkNext.value='Next';
    //pbLinkNext.expressions.disabled='{!disableNext}';
    pbLinkNext.id = 'mynewButtonsNext';

    Component.Apex.OutputText htmlNextTxtEnd = new Component.Apex.OutputText(); 
    htmlNextTxtEnd.value = '</div>';        
    htmlNextTxtEnd.escape = false; 

    opPanel.childComponents.add(htmlNextTxtStart);
    opPanel.childComponents.add(pbLinkNext);
    opPanel.childComponents.add(htmlNextTxtEnd);
           
    return opPanel;

}    

public PageReference refreshGrid() { //user clicked a page number        
    system.debug('**** ' + selectedPage);
    return null;
}

public PageReference Previous() { //user clicked previous button
    selectedPage = '0';
    counter -= list_size;
    return null;
}

public PageReference Next() { //user clicked next button
    selectedPage = '0';
    counter += list_size;
    return null;
}

public PageReference End() { //user clicked end
    selectedPage = '0';
    counter = total_size - math.mod(total_size, list_size);
    return null;
}

public Boolean getDisablePrevious() { //this will disable the previous and beginning buttons
    if (counter>0) return false; else return true;
}

public Boolean getDisableNext() { //this will disable the next and end buttons
    if (counter + list_size < total_size) return false; else return true;
}

public Integer getTotal_size() {
    return total_size;
}

public Integer getPageNumber() {
    return counter/list_size + 1;
}

public Integer getTotalPages() {
    if (math.mod(total_size, list_size) > 0) {
        return total_size/list_size + 1;
    } else {
        return (total_size/list_size);
    }
}

the data is paged using offset and limit in the SOQL query that returns the list for my table.

The problem I am having is that if I click the Prev button when it's already at the beginning of the dataset I get an SOQL error…

So how can I disable or hide the Prev button when it's on the first page, and disable or hide the Next button when it's reached the end of the dataset?

Best Answer

You need to split your Previous/Next navigation into uniquely addressable elements rather than grouping them together, and, ideally, use an <apex:outputPanel> or <apex:pageBlock> or even <apex:commandButton> or some other VF element that is not a vanilla <div>. Then, you can expose your existing currentPage accessor and replace your

<apex:pageBlock id="navGroup" rendered="true" >

with something more like

  • <apex: ... rendered="{!currentPage > 0}"> for your Previous button, and
  • <apex: ... rendered="{!currentPage < numPages}"> for your Next button.

Then, each time a navigation button is clicked, fetch the next or previous batch of records and rerender your navigation elements.

Related Topic