Sizing Frames

Last summer, we explained a techniqueIE4 Only for customizing a framesets appearance that only runs on Internet Explorer 4.0. In this article, we explore a solution that can run in existing JavaScript aware browsers (except IE3 which we are working on fixing). When targeting Internet Explorer 4.0, we still recommend the Internet Explorer 4.0 solution as it provides more efficient and flexible control over the frameset.

This technique for resizing frames is based on the object model's ability to dynamically generate new pages from scratch. Each time the user clicks on the checkbox to hide or show the table of contents, a new document is generated in the bottom frame.

Setting up the HTML

This works by constructing two framesets - an outer frameset that contains a frame with the hide/ show checkbox, and an inner frameset that contains the table of contents and the body frame. The outer frameset will contain all your logic. For example:

    <FRAMESET ROWS='120,*'>
      <FRAME SRC='adbar.htm' name=header>
      <FRAME SRC='main.htm' NAME=main>
    </FRAMESET>

This splits the screen into two rows. The top row must contain the checkbox, and the bottom row will contain the main contents. The main.htm file refers to a frameset document that further splits the screen between the table of contents and the information:

    <FRAMESET COLS='200,*'>
      <FRAME SRC='contents.htm'>
      <FRAME SRC='body.htm' NAME=body>
    </FRAMESET>

Together, these documents create the default layout and display all three documents.

Adding the Code

The next step is to add the code the responds to the user clicking on the checkbox. We place this code in the outer-most frameset.

 <SCRIPT>
    var hidden = false //Tracks the state

    function buildFrameset(state) {      
      var str = "<TITLE>Sizing Framesets</TITLE>"
      // Get the main document being displayed 
      if (frames["main"].frames.length!=0)
        bodyLoc =  frames["main"].frames["body"].location.href
      else
        bodyLoc =  frames["main"].location.href
      if (state) {
        // Display the frameset with the table of contents
        str+="<FRAMESET COLS='200,*'>"
        str+="<FRAME SRC='contents.htm'>" 
        str+="<FRAME SRC='"+bodyLoc+"' name=body>"
        str+="</FRAMESET>"
        frames["main"].document.open() 
        frames["main"].document.write(str)
        frames["main"].document.close()
      } else 
        // Do not display the frameset
        frames["main"].location.href =  bodyLoc
      hidden = !(hidden)
     }

     function testCheckbox() {
       // Initialize state
       hidden = (frames["main"].frames.length!=0)
       // Make sure frame exists
       if (frames["header"].document.forms["f1"]!=null)      
         frames["header"].document.forms["f1"].elements["c1"].checked = hidden
     }
 
     window.onload=testCheckbox;
  </SCRIPT>

The function buildFrameset() takes a boolean argument that determines whether to display the table of contents. The testCheckbox() function is called when the frameset is finished loading to correctly initialize the state of the checkbox.

The only remaining step is to add the checkbox to the document in the header frame and hook up the checkbox to the buildFrameset() function:

  <SCRIPT>
    var p = parent.parent
    function updateFrames(el) {
      p.buildFrameset(el.checked)
    }
  </SCRIPT>
  <BODY>
    <FORM NAME=f1>
      <LABEL FOR=update>Display Contents:</LABEL> 
      <INPUT TYPE="checkbox" ONCLICK="updateFrames(this)" 
             NAME=c1 ID=update CHECKED>
    </FORM>

On the code page, we list the source code for all the pages.

© 1998 InsideDHTML.com, LLC. All rights reserved.