function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
SFDCDevQASFDCDevQA 

Dynamic tabs in a related list

I'm working on a related list of opportunities that tabs the opportunities by Subject.  I have figured out how to do this if I code out each subject individually in the controller but I'd like it to be dynamic so that if a new subject is added the controller/page does not have to be recoded.  I can get my list of subjects via

public list<Schema.Picklistentry> getEntries(){
        return Opportunity.fields.Subject__c.getDescribe().getpicklistvalues();
    }  

But then I need the list for each subject such as I have here in my hardcoded example:

public List<Opportunity> getSubject1() {
        return [select id, name, stagename, closedate, amount, subject__c from Opportunity where accountid = :a.id and subject__c = 'General Chemistry' order by closedate];   
    }

and I also need the list on the visual force page as tabs such as I have here in my hardcoded example:

<apex:tab label="General Chemistry" name="GenChemOpps" id="tabGenChem">
            <apex:pageBlockTable value="{!subject1}" var="s1">     
            <apex:column headerValue="Action">       
                <apex:outputLink value="{!URLFOR($Action.Opportunity.Edit,s1.id)}">Edit</apex:outputLink>
                <apex:outputLabel value=" | "/>     
                <apex:outputLink value="{!URLFOR($Action.Opportunity.Delete,s1.id)}">Del</apex:outputLink>     
            </apex:column>              
            <apex:column headerValue="Opportunity Name"> <apex:outputLink value="{!URLFOR($Action.Opportunity.View,s1.id)}">{!s1.name}</apex:outputLink> </apex:column>  
            <apex:column headerValue="Stage" value="{!s1.StageName}"/>  
            <apex:column headerValue="Amount" value="{!s1.Amount}"/>
            <apex:column headerValue="Class Start Date" value="{!s1.CloseDate}"/>    
            <apex:column headerValue="Subject" value="{!s1.Subject__c}"/>                 
            </apex:pageBlockTable>
      </apex:tab>

 

I can pull just the list of subjects into the vf page via:

<apex:repeat value="{!entries}" var="val">
        {!val.label}<br/>
    </apex:repeat>

but I just can't seem to figure out how to mix it all together into something that works.  If anyone could help me that would be wonderful.

 

Thanks,

Amanda

Platy ITPlaty IT

Amanda,

 

I struggled with a similar requirement myself recently and ultimately learned that you cannot use apex:tabs inside of a repeat.  The only solution I could find was to do this with Dynamic Visualforce, some snippets of that below, with a lot my custom logic deleted to show just the relevant bits. You'll obviously have to adjust with your logic. 

 

public Component.Apex.OutputPanel getChildTabs(){
        
        Component.Apex.TabPanel ChildPanel = new Component.Apex.TabPanel(reRender = setRe, switchType = 'client',
        	style='padding-top:1em;', activeTabClass = 'activetab', inactiveTabClass = 'inactivetab');  

	Component.Apex.Tab ChildTab = new Component.Apex.Tab();
	ChildTab.Label = 'My Tab';
	          
         Component.Apex.OutputPanel OutPanel = new Component.Apex.OutputPanel(Id = 'opChildren');
         OutPanel.childComponents.add(ChildPanel);
         
        return OutPanel;
}

One tip, I ended up adding all of the tab content with a Visualforce component instead of writing it all out in Apex as dynamic VF.  You could do the same with the pageBlockTable in your example.  Much easier to create and maintain. 

SFDCDevQASFDCDevQA

Thanks Jessie.  Would you mind showing me the code on how this was incorporated into your VF page?  I assume this is part of your component/class and then the VF page called it.

 

Thanks,

Amanda

Platy ITPlaty IT

Certainly.  Once you have that method in your controller written to dynamically generate the tabs, the VF code is as simple as this, which calls the getChildTabs method in my previous example-

<apex:dynamicComponent componentValue="{!ChildTabs}"/>

And I left some bits out of my controller example yesterday just to keep things simple, but here's the full code for generating a tab and it's content-

Component.Apex.Tab ChildTab = new Component.Apex.Tab();
	             ChildTab.Label = (child.FormRecord.Name == null ? 'New' : child.FormRecord.Name);
	             ChildTab.Name = 'Tab ' +child.intId;
	             
	             
	             Component.ChildFormSetup ChildComp = new Component.ChildFormSetup(ChildForm = child, Sorts = Sorts, ParentForm = Form);
	             
	             ChildTab.childComponents.add(ChildComp);
	             
		         ChildPanel.childComponents.add(ChildTab);

 That "Component.ChildFormSetup" refers to a regular Visuaforce component.  I did that just to make my life easier- all of the content that I display in that tab is actually generated by the ChildFormSetup Component, which I find easier to create/edit than the dynamic VF.

Neha@SfdcNeha@Sfdc
cant display anything when i pasted the first patch posted as the solution jus to see whether it works 

and my vf is as:

<apex:page controller="page3ext">
  <apex:pageBlock >
  <apex:dynamicComponent componentValue="{!ChildTabs}"/>
  </apex:pageBlock>
   </apex:page>

controller
public class page3ext {

    public List<String> test { get; set; }
   
    public page3ext()
    {
        test=new List<String>{'one','two'};
    }
   
    public Component.Apex.OutputPanel getChildTabs(){
       
        Component.Apex.TabPanel ChildPanel = new Component.Apex.TabPanel(switchType = 'client',
            style='padding-top:1em;', activeTabClass = 'activetab', inactiveTabClass = 'inactivetab'); 

    Component.Apex.Tab ChildTab = new Component.Apex.Tab();
    ChildTab.Label = 'My Tab';
             
         Component.Apex.OutputPanel OutPanel = new Component.Apex.OutputPanel(Id = 'opChildren');
         OutPanel.childComponents.add(ChildPanel);
        
        return OutPanel;
}
}


Neha@SfdcNeha@Sfdc
i have corrected my mistake
thanks for this post...:)