You need to sign in to do that
Don't have an account?
SATHISH REDDY.
Apex Tabs in Visualforce must load data only when clicked
Hello Trailblazers,
I'm trying to design a VFP with TWO apex tabs with each tab having a table with list of records within along with some custom "search" logic. Tab 1 will load the data by default on initial page load but I want tab 2 data to be loaded only when clicked(as a best practice). i also have a custom button within each tab which will just get the specific records onto the table. I'm really having hard time in figuring out how to achieve this as i tried to use the actionfunction ontabenter which didn't work. Please shed some light on what i might be doing wrong or share any examples specific to my use case.
VFP:
Controller:
Thanks in advance!
I'm trying to design a VFP with TWO apex tabs with each tab having a table with list of records within along with some custom "search" logic. Tab 1 will load the data by default on initial page load but I want tab 2 data to be loaded only when clicked(as a best practice). i also have a custom button within each tab which will just get the specific records onto the table. I'm really having hard time in figuring out how to achieve this as i tried to use the actionfunction ontabenter which didn't work. Please shed some light on what i might be doing wrong or share any examples specific to my use case.
VFP:
<apex:page controller="MarginTrackerController" sidebar="false"> <apex:form > <apex:tabPanel title="Margin Tracker" id="tabpanelId" tabClass="activeTab" inactiveTabClass="inactiveTab" value="{!varTabId}"> <apex:tab label="Summary" name="Summary" ontabenter="onClickSummaryTab();" switchType="ajax" id="Summary"> </apex:tab> <apex:tab label="Margin" name="Margin" ontabenter="onClickMarginTab();" switchType="ajax" id="Margin"> <div style="width:800px;float:left;"> <!-- this is the filter used to SearchAction--> <apex:selectList multiselect="false" size="1" value="{!selectedTimeframe}"> <apex:selectOptions value="{!timeframeList}"></apex:selectOptions> </apex:selectList> <apex:commandButton value="Go" action="{!searchAction}" status="status" rerender="formId,oppsPanel"> </apex:commandButton> </div> <p><div class="oppstbldiv"> <table class="oppstbl" id="myOppsTable"> <thead> <tr> <th colspan="1">Opportunity</th> <th colspan="1"> Type</th> <th colspan="1"> Start</th> <th colspan="1"> End</th> <th colspan="1">Net Budget</th> <th colspan="1">Sold Margin ($)</th> <th colspan="1">Sold Margin (%)</th> <th colspan="1">Booking Margin ($)</th> <th colspan="1">Booking Margin (%)</th> <th colspan="1">Revised Margin ($)</th> <th colspan="1">Revised Margin (%)</th> </tr> </thead> <tbody> <apex:repeat value="{!oppList}" var="opp"> <tr> <td style="text-align:left">{!opp.Name}</td> <td>{!opp.Market__c}</td> <td> <apex:outputText value="{0,date,MM'/'dd'/'yyyy}"> <apex:param value="{!opp.Start_Date__c}" /> </apex:outputText> </td> <td> <apex:outputText value="{0,date,MM'/'dd'/'yyyy}"> <apex:param value="{!opp.End_Date__c}" /> </apex:outputText> </td> <td> <apex:outputText value="{0, number, currency}"> <apex:param value="{!opp.Net_Budget__c}" /> </apex:outputText> </td> <td> <apex:outputText value="{0, number, currency}"> <apex:param value="{!opp.Sold_Margin__c}" /> </apex:outputText> </td> <td> <apex:outputText value="{0, number, ##.##}%" rendered="{!NOT(ISNULL(opp.Sold_Margin_Percentage__c))}"> <apex:param value="{!opp.Sold_Margin_Percentage__c}"/> </apex:outputText> </td> <td> <apex:outputText value="{0, number, currency}"> <apex:param value="{!opp.Booked_Margin__c}" /> </apex:outputText> </td> <td> <apex:outputText value="{0, number, ##.##}%" rendered="{!NOT(ISNULL(opp.Booked_Margin_Percentage__c))}"> <apex:param value="{!opp.Booked_Margin_Percentage__c}"/> </apex:outputText> </td> <td> <apex:outputText value="{0, number, currency}"> <apex:param value="{!opp.Revised_Margin__c}" /> </apex:outputText> </td> <td> <apex:outputText value="{0, number, ##.##}%" rendered="{!NOT(ISNULL(opp.Revised_Margin_Percentage__c))}"> <apex:param value="{!opp.Revised_Margin_Percentage__c}"/> </apex:outputText> </td> </tr> </apex:repeat> </tbody> </table> </div></p> </apex:tab> <apex:actionFunction action="{!SummaryTab}" name="onClickSummaryTab"/> <apex:actionFunction action="{!MarginTab}" name="onClickMarginTab"/> </apex:tabPanel> </apex:form> </apex:page>
Controller:
public class MarginTrackerController { public List<Opportunity> oppList{get; set;} public Opportunity opp{get;set;} public List<SelectOption> timeframeList{get;set;} public String selectedTimeframe { get; set; } public String varTabId { get; set; } public MarginTrackerController(){ } public pageReference SummaryTab(){ varTabId = 'Summary'; /*some logic to fetch records*/ return null; } public pageReference MarginTab(){ varTabId = 'Margin'; opp = new Opportunity(); timeframeList = new List<SelectOption>(); timeframeList.add(new SelectOption('', '--None--')); selectedTimeframe = ''; oppList = new List<Opportunity>(); oppList = [SELECT Id, Name,Market__c, Start_Date__c, End_Date__c, Net_Budget__c, Sold_Margin__c, Sold_Margin_Percentage__c, Booked_Margin__c, Booked_Margin_Percentage__c, Revised_Margin__c, Revised_Margin_Percentage__c FROM Opportunity ORDER BY createdDate DESC LIMIT 100]; return null; } public void searchAction(){ timeframeList.add(new SelectOption('', '--None--')); timeframeList.add(new SelectOption('Q1', 'Q1')); timeframeList.add(new SelectOption('Q2', 'Q2')); timeframeList.add(new SelectOption('Q3', 'Q3')); timeframeList.add(new SelectOption('Q4', 'Q4')); timeframeList.add(new SelectOption('Date', 'Date')); /*fetch the filtered records here*/ } }
Thanks in advance!
I am quiet confused why you are facing the issue because <apex:facet name="start"> is bascially used for AJX request and it automatically gets closed when the ajax request is completed as per Salesforce Documentation. Even I have tried the same and it's working for me perfectly.
Just to add some delay in code, I have changed the code a little bit and it's still working for me. As I don;t have your exact code I can only guess that you must have mis placed something.
Please try below code in your org as it is, look if it is working for you if not let me know. But if it is working for you just try to place your code on similar lines:
There are slight changes from previous version, On Vf page I have added an alert which will pop up once ajax request is complete this will help you to figure out that when ajax request is completed then only loading image is getting disappeared:
VisualForce Page : onClickTabControllerVF Class Name: onClickTabController
Just like I have mentioned that to add a delay from AJAX I have added an unnecessary for loop to incerease the time.
So first check this code work for you or not, if it works then just make changes in code accordingly on similar line.
Regards,
Santosh
All Answers
I have written a sample working code which you can use as per your need.
I guess you are missing reRender in your action:Region as you need to refresh your Tab once data is fetched from server. I guess that is only the missing part in your code. (render attribute mark as bold in below code.)
VF Page: onClickTabVf
Class: onClickTabController
If it still doesn't work for you let me know we can figure this out.
If you find the above solution helpful. Please mark as Best Answer to help others too.
Thanks and Regards,
Santosh Kumar
Hi Santosh,
Thanks for you help, I used the reRender attribute before but looks like i left the actionfunction within the tabpanel which prevented the rerender to happen in the 1st place. Removed & placed it outside the tabpanel & it works!
However, i did notice that on the initial load, when i switch to tab2 it shows just the table header & after a couple of seconds the data loads into the table which makes the transition bit ugly & bad UX. I tried to use the Actionstatus to have the spinner shown on tab switch & changed the switchtype to "ajax" to cover it. It didn't help either as it continues to show the header 1st & loads the data into the table after 2 to 3 seconds. Any suggestions on that part is really appreciated!
Thanks!
Sathish
I have updated the vf with loading image. This will help you :
If you find the above solution helpful. Please mark as Best Answer to help others too.
Thanks and Regards,
Santosh Kumar
Note:- This happens when we open the VFP and then click on Tab2.
Hi Santosh,
Can you please help me with my previous query, just noticed that the above mentioned delay is increased when record count is increased. So this seems to be an issue as "action status" is unable to cover that lag.
Thanks,
Sathish
I am quiet confused why you are facing the issue because <apex:facet name="start"> is bascially used for AJX request and it automatically gets closed when the ajax request is completed as per Salesforce Documentation. Even I have tried the same and it's working for me perfectly.
Just to add some delay in code, I have changed the code a little bit and it's still working for me. As I don;t have your exact code I can only guess that you must have mis placed something.
Please try below code in your org as it is, look if it is working for you if not let me know. But if it is working for you just try to place your code on similar lines:
There are slight changes from previous version, On Vf page I have added an alert which will pop up once ajax request is complete this will help you to figure out that when ajax request is completed then only loading image is getting disappeared:
VisualForce Page : onClickTabControllerVF Class Name: onClickTabController
Just like I have mentioned that to add a delay from AJAX I have added an unnecessary for loop to incerease the time.
So first check this code work for you or not, if it works then just make changes in code accordingly on similar line.
Regards,
Santosh
Awesome! I initially added the "status" to <apex:tab> instead of actionfunction which caused this issue where the tab click shows the status & dissappears before ajax req is complete. Now i added status to actionfunction & removed from tab component. Thank you are really appreciate your help!
Sathish
An extension to this, when i add this script, the tab click is not working
<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="app.js"></script>
I have a table in tab two where the rows are collapsaible with inner table content. I'm using this script to allow row click toggle show/hide the inner table. Trying to achieve this https://webdesignerhut.com/data-table-with-collapsible-table-rows/
Please share your input. thank you!