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
Darla.ax69Darla.ax69 

Iframe height

I use a custom tab to show a URL in an iframe. The URL points to my app, which includes pages of varying heights.

When the custom tab is defined, I'm forced to enter a specific height. But that height isn't the best height for each page of my app.

What I'd like to do is have the iframe height automatically set itself based on the height of my page. Unfortunately when I try to access the iframe object to modify it with JavaScript, I get a permission denied error.

Viewing the source of the salesforce.com page that contains my iframe, I see a doResize() method that appears it would set the height of the iframe to fit my content. Unfortunately I can't call that method from my page; it also gives me a permission denied error.

If I specify a height of 600 (for example) when I define my custom tab, the iframe has scrollbars. I could possibly be ok with that, except that if the browser window isn't tall enough, the main window also has scrollbars. So I've got double scrollbars which is very unpleasant to use. You have to scroll the main window down in order to be able to scroll the iframe all the way down.

My solution for now has been to specify an iframe height that's taller than I expect my pages to be (5000) to make sure the iframe won't have scrollbars, only the main window. The problem with that is that the user isn't taken to the top when a new page is clicked on. So if a user is at the bottom of a long page and clicks a link to go to a short page, the window doesn't automatically scroll to the top, so the user doesn't see anything on the short page, just empty space.

If I could control the main window scrollbar, I could fix that problem. But I don't have permission for that either.

At this point I'm out of ideas for what to do, so any suggestions are greatly appreciated.

For a future release, could salesforce make specifying the iframe height optional? And if you didn't specify a pixel height, the doResize() method would be called to automatically set the height?

Thanks for any advice,

=> Darla
DevAngelDevAngel
Hi Darla,

I may have a workaround for you. The problem you face is that due to browser security, you are not allowed access across the iframe boundary, even to the point of the I frame that is hosting your document. This is because your document is being served up from a different domain than the iframe that is hosting it.

You can cross the boundary though if what is hosted is served from the same domain as the iframe. This is the case with an scontrol. If instead of a url web link you created a simple scontrol that first, set the size of the hosting iframe, and second, redirected to your document passing on what ever merge info was required, you could at least change the iframe size initially. Not sure if there is a way to further control the size of the iframe during navigation to other pages, but I think you may be able to actually create an iframe in the scontrol to host your pages and set it up so that page navigations can be detected and the scontrol can then adjust the iframe height. It'll take a little digging for you to figure this one out fully.
Darla.ax69Darla.ax69
Hi Dave,

Thanks for the response. With your help, I've come up with a solution I can live with. This may be kind of long, but I wanted to share what I've learned for anyone else dealing with the same problem.

The main salesforce window contains an iframe named itarget. I created an s-control (that lives in itarget) with an iframe named cc which holds my app.

Since the main window and itarget contents are now served from the same server, my s-control can modify itarget as you said. But since my app and the s-control are on different servers, they can't communicate. Even though the s-control contains my app, the s-control can't access anything in my app. (I tried to determine my app's appropriate size, for example.)

So I decided to make the itarget iframe take up what I determined to be an appropriate amount of space:

* When there is no sidebar, the iframe fills the available space in the window, so there is no scrollbar on the main window.

* When there is a sidebar and the height of the sidebar is short enough that scrolling isn't required, the iframe fills the available space in the window, so there is no main window scrollbar.

* When there is a sidebar and the height of the sidebar is tall enough to require scrolling, the iframe is as tall as the sidebar. So there's still a main window scrollbar, but the itarget iframe looks like its an appropriate height. It's not too small, shrinking the app smaller than it needs to be, and it's not too big, making the main window scroll area very large.

The iframe has scrollbars if my app is too large to fit in the iframe. I'm still not real happy about possibly having 2 scrollbars, but it's more manageable now that the main window scrollbar isn't for too large an area.

So here's what's in my s-control:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html>

<head>
<title>Customer Connection</title>
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<script language="JavaScript" type="text/javascript">

  function init() {

    // This should only apply when the app is opened in an iframe.
    if (self == top) {
      return;
    }

    // Make sure the iframe objects are available.
    var sfdcIframe = parent.document.getElementById("itarget");
    var ccIframe = document.getElementById("iframe_cc");
    if (!sfdcIframe || !ccIframe) {
      return;
    }

    // Get the table cell that holds the iframe.
    var parentCell = sfdcIframe.offsetParent;

    // Hide the iframes while the appropriate sizing is determined.
    sfdcIframe.style.display = "none";
    ccIframe.style.display = "none";

    // Get the height of the available space in the top-level window.
    var availableHeight = 0;
    if (top.innerHeight) {
      availableHeight = top.innerHeight;
    }
    else if (top.document.body && top.document.body.parentNode.clientHeight) {
      availableHeight = top.document.body.parentNode.clientHeight;
    }

    // Get the height the full document takes up (without the iframe, which is currently hidden).
    var docHeight = 0;
    if (top.document.body && top.document.body.scrollHeight) {
      docHeight = top.document.body.scrollHeight;
    }
    else if (top.document.body && top.document.body.offsetHeight) {
      docHeight = top.document.body.offsetHeight;
    }

    var newIframeHeight = 0;

    // How the height is set depends on whether or not there's a sidebar.
    // If the containing cell is visible without the iframe, there's a sidebar.

    // If there's a sidebar...
    if (parentCell.offsetHeight >= 20) {

      // If the document height is more than the available height, there will be a scrollbar
      // regardless of the iframe height. Set the iframe to the height of its containing cell,
      // which should match the size of the sizebar. That way the page won't have to scroll any more.
      if (docHeight >= availableHeight) {
        newIframeHeight = parentCell.offsetHeight - 10;
      }

      // Otherwise, set the iframe to the height of the sidebar plus any leftover space.
      // That should fill the available space but not require any scrolling.
      if (newIframeHeight <= 0) {
        newIframeHeight = parentCell.offsetHeight + (availableHeight - docHeight) - 30;
      }
    }

    // If there's no sidebar...
    else {
      // The iframe should be tall enough to fill the available space on the page.
      newIframeHeight = availableHeight - docHeight - 20;
    }

    // Set a minimum size, just in case...
    newIframeHeight = Math.max(newIframeHeight, 400);

    // Turn off scrolling in the parent iframe; the child iframe will handle the scrolling.
    sfdcIframe.scrolling = "no";

    // Update the height of the parent iframe.
    sfdcIframe.style.height = newIframeHeight + "px";

    // Make the parent iframe visible again (needed to determine its size).
    sfdcIframe.style.display = "";

    // Update the size of the child iframe.
    ccIframe.style.width = sfdcIframe.offsetWidth + "px";
    ccIframe.style.height = sfdcIframe.offsetHeight + "px";

    // Make the child iframe visible.
    ccIframe.style.display = "";
  }
</script>
<noscript>
  JavaScript must be enabled to use Customer Connection.<br />
  If you need assistance enabling JavaScript, <a href="http://www.insidescoop.com/support.html">contact support</a>.
</noscript>
</head>

<body id="body" style="padding:0px; margin:0px; background-color:#ffffff" onLoad="init()">

<iframe id="iframe_cc" name="cc" src="https://apps.insidescoop.com/cc/accounts/index.jsp?crm=salesforce&crmUsername={!User_Username}&crmSessionId={!API_Session_ID}&crmServerUrl={!API_Partner_Server_URL_60}&crmObjectId={!Account_ID}" width="100%" height="100%" scrolling="auto" marginWidth="0" marginHeight="0" frameborder="0"></iframe>

</body>

</html>


I've tested this in IE 5.5 and Firefox 1.5 so far and it seems fine. Thanks again for pointing me in the right direction. I hope others find this useful.

=> Darla
michaelforcemichaelforce

This is brilliant... thanks for posting, it helped me greatly.

I wonder if you will be able to control the size of in-line s-controls dynamically with this method in winter 07.

Topher SympsonTopher Sympson
I believe sControls are no longer the answer here.. but how would this translate to what you would need to do today?