We have a page layout for a custom object and want to put a Visualforce page as a section in it. However, the height of the content varies, and when I drop the section in, there is a large white space if the content does not fill. How do I deal with this (the part with the big red 'X' through it)?
4 Answers
Yes it is possible. See the Update - Success at the bottom:
Old Answer - close but not so much
Resizing the VF Page within a Page Layout is not possible though there is an option on the Page Layout that allows scrollbars for the embedded content.
Another option is to (1) make the "embedded" Visualforce Page a Visualforce Component, and (2) write a VF Page similar to:
<apex:page standardController="Your_Object__c">
<apex:detail subject="{!Your_Object__c.Id}" relatedList="true"/>
<c:yourComponent recordId="{!Your_Object__c.Id}" />
</apex:page>
Then override the View
Standard Button or Link
on the Object page with this VF Page.
This option does have some minor downsides in that developers will have to go into the Object from the Setup to change the Page Layout rather than the using the "Edit Layout" link on the top-right. Also Developers will lose the Dev Tools Menu. Again, these are minor issues for Developers, but this could add the functionality you are looking for. It's worth a try.
Update - Success
VF Pages embedded in a Page Layout come over as iframe
s, so the solution is to write a VF Page using only <apex:detail .../>
to bring over the Page Layout and then have JavaScript (via jQuery) resize all the iframe
s.
Example
<apex:page standardController="Custom_Object__c">
<apex:detail subject="{!Custom_Object__c.Id}" relatedList="true"/>
<apex:includeScript value="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"/>
<script>
var j$ = jQuery.noConflict();
j$("iframe").each(function(){
j$(this).load(function() {
j$(this).height( j$(this).contents().find("body").height() );
});
});
</script>
</apex:page>
-
Yeah that's a good idea! My only question is: Does this limit my embedded content to only being at the bottom of the page? We need to have it between 2 other sections in the page layout.– kb_Aug 6, 2014 at 23:03
-
Yes, the content is separate from the Page Layout. To include embedded in the Page Layout, you are stuck with the fixed Height + Scrollbars Aug 6, 2014 at 23:04
-
It might be possible to resize the Embedded VF Page in a Page Layout via JavaScript. Aug 6, 2014 at 23:10
-
-
Ok so if I understand this correctly, we're still doing the detail page on top and the resized iframe/vfpage on the bottom? still unable to nest it then?– kb_Aug 7, 2014 at 1:33
Yes it is possible.
@AmatorVitae's answer will certainly work if you can set up your visualforce page to use apex:details.
If you need more than apex:detail
To resize a visualforce page with a more complex structure, you can do so with some cross domain scripting.
In my answer here, I go into detail about how to accomplish this.
To summarize
You need to
- Add a custom link section to your sidebar that executes some javascript stored in a static resource.
- Add a static resource that is set up to receive a message from another domain and then use the message's value as the new height of the iframe.
- Add some script to your visualforce page that will send a message to the parent domain with the value of the content's height.
Some more ideas on this include using HTML 5 postMessage() and cross-domain messaging for iframes. I've written up a blog post on how this can be used to not only do dynamic iframe resizing, but also implement basically any collaboration between the parent page and embedded VF that your business requires. HTH
http://salesforcehacks.blogspot.com/2014/12/resizing-embedded-vf.html
If you are in lightning, you can use Sfdc.canvas.publisher.resize
Sample code
<apex:page standardController="Case">
<script src="/canvas/sdk/js/publisher.js" />
<apex:variable var="isClassic" value="{! $User.UIThemeDisplayed == 'Theme2' || $User.UIThemeDisplayed == 'Theme3' }" />
<script>
// If we are in lightning , set Page Layout section height to 0 px
if ({! NOT(isClassic)}) {
Sfdc.canvas.publisher.resize({ height: "0px" });
}
</script>
<div rendered="{! isClassic }">
<h1>Renders Only In Classic</h1>
</div>
</apex:page>