You need to sign in to do that
Don't have an account?

Moderators / VF experts - A bug with repeat/tabs? (full code to replicate inside)
Hi guys,
I'm experiencing some unexpected behavior when trying to use the apex:repeat function to render tabs....
Basically it seems that tabs cannot be created on demand? My controller is definitely returning data... as the second page block in my sample will show... repeat works - just the tabs are not rendered..
I'm sure any of you guys can see where I was going with this - and I guess I can achieve a similar result by dropping down to boring old html - just trying to use the standard components (as per best practice)
Any assistance greatly appreciated - as the purist coder me is seriously disturbed at the moment...
here is my 'simplified' and easily testable page & controller
and the controller
I'm experiencing some unexpected behavior when trying to use the apex:repeat function to render tabs....
Basically it seems that tabs cannot be created on demand? My controller is definitely returning data... as the second page block in my sample will show... repeat works - just the tabs are not rendered..
I'm sure any of you guys can see where I was going with this - and I guess I can achieve a similar result by dropping down to boring old html - just trying to use the standard components (as per best practice)
Any assistance greatly appreciated - as the purist coder me is seriously disturbed at the moment...
here is my 'simplified' and easily testable page & controller
Code: VF PAGE
<apex:page controller="clsRecordType"> <apex:pageBlock > <apex:tabPanel id="theTabPanel"> <apex:tab label="Account Types"/> <apex:repeat value="{!RecordTypes}" var="types"> <apex:tab label="{!types.Name}"/> </apex:repeat> </apex:tabPanel> </apex:pageBlock> <apex:pageBlock > <apex:repeat value="{!RecordTypes}" var="types"> {!types.Name}<br/> </apex:repeat> </apex:pageBlock> </apex:page>
and the controller
Code:
public class clsRecordType { list<RecordType> lrecordtypes; public list<RecordType> getRecordTypes() { if(lrecordtypes==null) lrecordtypes = [Select Name, Id, Description From RecordType where SobjectType = 'Account' and IsActive=True]; return lrecordtypes; } }
First create a Static Resource called ext and use this compacted ext.js zip as the resources contents.
Next create the following page and 2 components and you should be good to go.
Message Edited by dchasman on 07-11-2008 09:49 AM
Message Edited by dchasman on 07-11-2008 09:59 AM
All Answers
It's a known issue and I think we've got a bug on that already.
PS - Thanks for reducing your code down to a small, reproducible example. It's much appreciated by my team!
many thanks for your prompt & frank response - sadly it only served to confirm my observation (I was holding out some vague hope that I was just being a muppet).
Given the situation - is it possible for you or someone to write a quick summary of all the components that are specifically NOT compatible with repeat? - I've chased my tail for a while on this particular repeat/tab issue and I'm sure I'm not going to be the last to do so.
Likewise - perhaps one of you SF developer geniuses with the benefit of the code behind such components - can suggest a work around... I've been pondering the possibility of constructing a set of tabs in the controller code for injection back into the page etc... not sure if this is feasible for example?
Cheers,
Ben
First create a Static Resource called ext and use this compacted ext.js zip as the resources contents.
Next create the following page and 2 components and you should be good to go.
Message Edited by dchasman on 07-11-2008 09:49 AM
Message Edited by dchasman on 07-11-2008 09:59 AM
Doug
I just cannot tell you how much you rock! I just ran into this bug and was looking down and out, and then I see your solution.... thank you sooooo much!
Hi,
Many thanks for this sollution, i have using this for my application.
Tariq.
Hi I am using the below code. Instead of the Displaying detail page on Tab click , I want to send the Id of the selected tab to the controller . This is not happening currently . Any help is appreciated .
<apex:pageBlockSection title="Offering Products" id="product1">
<c:tabpanel width="1000" >
<apex:repeat var="OfferingProduct" value="{!OfferingProducts}">
<c:tab title="{!OfferingProduct.Name}">
<apex:detail Subject="{!OfferingProduct.Id}" relatedList="false"/>
<apex:inputHidden value="{!selectedValue}" id="theHiddenInput"/>
<apex:repeat var="Service" value="{!Services}">
<apex:outputLabel value="{!Service.Name}" for="theCheckbox"/>
<apex:inputCheckbox value="{!CheckBoxSelectedValue}" id="theCheckbox"/>
</apex:repeat>
</c:tab>
</apex:repeat>
</c:tabpanel>
</apex:pageblockSection>
Thanks,
Can anyone help me with the above code.. I want {!Offering.Id} in controller class
How are you passing the Id to the controller?
<apex:pageBlockSection title="Offering Products" id="product1">
<c:tabpanel width="1000" >
<apex:repeat var="OfferingProduct" value="{!OfferingProducts}">
<c:tab title="{!OfferingProduct.Name}">
<apex:repeat var="Service" value="{!Services}">
<apex:outputLabel value="{!Service.Name}" for="theCheckbox"/>
<apex:inputCheckbox value="{!CheckBoxSelectedValue}" id="theCheckbox"/>
</apex:repeat>
</c:tab>
</apex:repeat>
</c:tabpanel>
</apex:pageblockSection>
I am using the above code in my page.
Offering.Name is my tab name , my requirement is when I click the tab , it should pass the offering.Id to the controller class.below is my controller code
public List<VMobile_Product_catalogue_VM__c> getOfferingProducts() {
List<VMobile_Product_catalogue_VM__c> ProductName = new List<VMobile_Product_catalogue_VM__c>();
if(offer != NULL) {
String offerId;
for (
Vmobile_offering_product__c vProd :[select Id,vProd.VMobile_Product__c from Vmobile_offering_product__c vProd
where vProd.Vmobile_offering__c = : offer] ){
offerId = vProd.VMobile_Product__c;
for(VMobile_Product_catalogue_VM__c prod : [Select Name, Id,Is_Root__c From VMobile_Product_catalogue_VM__c where Id =: offerId])
{
if(prod.Is_Root__c == true)
{
ProductName.add(Prod);
// ProdId = OfferingProducts.Id;
system.debug('Prod Name List ==== ==='+ProductName);
List<aggregateResult> results = [Select v.VMobile_Product__c, SUM(v.Price__c) sum From Vmobile_Product_Price__c v where v.VMobile_Product__c = : offerId group by v.VMobile_Product__c ];
//List<AggregateResult> results = [Select AccountId, SUM(Amount) sum From Opportunity GROUP BY AccountId];
for(AggregateResult ar : results){
productPrice = String.valueOf(ar.get('sum'));
}
}
}
}
}
system.debug('Returning Produvt Name.....'+ProductName);
return ProductName;
}
This has been an issue for 2 1/2 years?? Salesforce, any idea when this functionality might be available out-of-the-box?
Thanks.
Doug,
This does not seem to work anymore - I made it work last year. I had Resource.Ext (instead of Ducho_Ext) and I am still using it. I even tried using ext-3.0.0.
Seems like the js files are there, but it doesn't want to work...
Hi
i am facing some issue after implementing this code.
Assume this senario :
U create the check box in Checked state. when user uncheck the check box and rerender the the block.. its rerender the check box with check state..
if u are using my code please uncheck the check box and whic is located inside the tab pabel.....
it is not capturing the uncheck state.. this happens only in this senario.
U create the check box in unchecked state every this work file..
if u remove the tab panel tags .. every thing work fine....
Can any 1 help to resolve this issue..
Apex page :
<apex:page controller="TestCheck">
<apex:form >
<apex:pageBlock id="CheckBlock">
<apex:pageBlockButtons >
<apex:commandButton action="{!markCheck}" reRender="CheckBlock" value="Save Workflow"/>
</apex:pageBlockButtons>
<apex:inputCheckbox id="checkBox" value="{!status1}"/>
<c:ashTabPanel width="980" id="thePanel" >
<c:ashtab title="test" id="tab1">
<apex:inputCheckbox id="checkBox11" value="{!status}" lang="test"/>
</c:ashtab>
</c:ashTabPanel>
</apex:pageBlock>
</apex:form>
</apex:page>
Controller:
public class TestCheck
{
public boolean status {get;set;}
public boolean status1 {get;set;}
public TestCheck()
{
status = true;
status1 = true;
}
public void markCheck()
{
}
}
Solution (with <apex:detail />) does not work anymore. Any ideas why?
Just discovered that apex:repeat and apex:tab don't work together; looks like many hours of extra (and potentially fragile) work is now going to be needed.
+1 for the platform providing support for this.
Would love to know why this doesn't work with apex:detail too...
here is an idea for SFDC to support apex:tab inside of apex:repeat:
https://success.salesforce.com/ideaView?id=08730000000l3gHAAQ
Please vote for the idea!
BUT I HAVE A PROBLEM.
I have a pretty complex page that has several dynamic tab panels and dynamic tabs. The code works create with one dynamic tab panel, but when I add a second one, it duplicates the information from the first tab. I tried creating different components with different Id's, tabPanelA and tabA, but I cannot get this to work at all.
I am somewhat of a novice with Javascript, but I think I need a way to pass a unique id with each implementation of the c:tabPanel.
Any ideas?
And YES, vote for the enhancement - it has been 6 years with only 4 votes.
There two new attributes added to the component:
- uid is an id for the tab panel component. It can be any text string, but there has to be a unique uid for every tab panel component onthe visualforce page.
- rowStyle specifies a style class that is associated with the ul.x-tab-strip. The two classes are defined in the component code as:
- onerow - The width defined in onerow should be large enough so that all of your tabs show in a single row. If the number of tabs require more than the width specified, the row will wrap. Be aware that this also expands the width of the tab component, which can result in a lot of scrolling.
- multirow - The width for multi row should always be "100%". This will cause the tab row to wrap to fit the size of the browser window and to dynamically expand or contract if the browser window side changes.
Screenshots of the different rowStyle values:- rowStyle = "oneRow" - tab headers in a long single row. Note how the tab area is stretched to width specified in the onerow style class.

- rowStyle = "multirow" - tab headers wrapped into multiple rows to fit the browser window size.

WARNING - This works in Chrome and Internet Explorer. But I have had problems with rerendering the page in Internet Explorer when using <apex:actionSupport>. For some reason, the refresh operation in IE does not refresh anything inside of the tab panel component.New tab panel component is below. Refer to dchasman's original post for the rest of the instructions.