Help
Custom Frame Example

This example demonstrates how to build a custom Frame. It features Frame API event handling from Javascript and domain customization to register the custom frame in the domain.

You can download the component source code from CustomFrame.zip.

This custom frame has a small header at the top of the page, and reserves the rest of the page for the frame's content. At the top-left of the header, it displays the current page's title. If the frame is not displaying the home page, the top-right of the header shows a link that returns to the home page. Its rendering looks similar to this when viewing the student home page:

Custom Frame Home

When viewing a non-home page, it looks similar to this (with the home-page link):

Custom Frame Non-Home

Creating the Component

The component is a VHTML file. It includes jQuery, an open-source Javascript library that simplifies HTML document handling. Because it is a Frame component, it also provides the Frame API for other components rendered on the page within the frame.

1.

Create a file named frame.vhtm. In the head element, include <%FrameReferences%> to get the Frame API and other required dependencies for a frame. Define some CSS styles that the frame can use.

<!DOCTYPE html>
<html >
<head>
    <title>Sample Frame</title>
    
    <!-- Include the FrameReferences to get the FRAME_API and dependencies -->
    <%FrameReferences%>
    
    <!-- Define some styles that we'll use later -->
    <style type="text/css">
        body, html 
        {
          overflow:hidden; 
        }
        .frame-header 
        { 
          position: absolute; 
          left: 3px; 
          right: 3px; 
          top: 3px; 
          height: 27px; 
          background-color: Aqua;
          font-size: 14pt;
          font-family: Sans-Serif;
        }
        .frame-content { 
          position: absolute; 
          left: 0px; 
          right: 0px; 
          top: 30px; 
          bottom: 0px; 
          overflow:auto; 
        }
    </style>
</head>
2.

Within the head element, include the jQuery Javascript library. Also include frame.js, a Javascript file that we'll implement later. It's path includes <%ResourceRoot%>, which indicates the file is in the current domain's content folder.

<!-- Include jquery for use in components -->
<script type="text/javascript" 
  src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.1.min.js"></script>

<!-- Include javascript from the domain content -->
<script type="text/javascript" src="<%ResourceRoot%>/frame.js"></script>
3.

In the body HTML, create a div for the header, with a placeholder div for the frame title on the left and a div on the right with the "Return Home" link, whose href is the "Home" component URL (see URL Syntax for more details.)

<body>
  <div class="frame-header">
    <!-- Frame header -->
    <div style='float:left'>
	    <span id='frame-title'></span>
    </div>
    <div style='float:right'><span id='frame-link'>
      <a href="<%FrameRoot%>/Component/Home">Return to Home Page</a></span>
    </div>
  </div>
  
  <!-- We'll add more here in the next step. -->
  
</body>
4.

Beneath the header div, add another div with the <%FrameContent%> replacement tag inside it, which BrainHoney replaces with the actual page content when displaying a frame-with-content URL (see URL Syntax for more details.)

<div class="frame-content">
    <!-- Placeholder for the actual content -->
    <%FrameContent%>
</div>
5.

Create a Javascript file named frame.js. Within it, create an encapsulation function that will contain all our component's Javascript. This prevents collisions between our functions and other objects/functions in the global scope.

// Scope the frame logic with a global closure to prevent collisions
$(function() {

  // All other Javascript logic will go here...

});
6.

Define an object, we'll name it "myFrame". Within it, define a function that sets the page title and registers for the contentstatechanged event on the Frame API. The Frame API calls our stateChanged event handler whenever the main frame component (the component with ID "FrameContent") calls setComponentState. Finally, add the call to the initialize function.

var myFrame =
{
    initialize: function () {
        // Update the state based on the already loaded content
        this.stateChanged(FRAME_API.contentState);

        // Listen to the contentstatechanged event so we can update our title
        //   when the main content updates its title
        FRAME_API.addListener('contentstatechanged', this.stateChanged, this);
    }, 
    
    /* We'll add another function here next, so include the trailing comma above */
};
myFrame.initialize();
7.

Within the myFrame object, define the contentstatechanged event handler function (we name it stateChanged). It constructs the page title and sets both the document title and the "frame-title" element in the frame header. If the current page being displayed is the home page, the handler hides the "Return Home" link.

stateChanged: function (state) {
    //Build up a string to show for the page title
    var titles = [];
    if(state.pageTitle) {
        titles.push(state.pageTitle);
    }
    if(state.subTitle1) {
        titles.push(state.subTitle1);
    }
    if(state.subTitle2) {
        titles.push(state.subTitle2);
    }

    var title = titles.join(': ');
    // Update the document title
    document.title = title;
    // Update the title at the top of the page
    $('#frame-title').text(title);

    // Hide the link back to home if we're already there
    if (state.type == "home") {
        $('#frame-link').hide();
    }
}

That completes the component definition. To test it, you must upload it to a domain and then launch it, as described in the following sections.

Uploading the Component

You upload the frame.vhtm and frame.js files to your BrainHoney domain content folder.

1.
admin gear

Log into BrainHoney with a domain administrator account and click the Administrator gear icon to open the administration page.

2.
content tab

Click the Content tab to display the domain's content files.

3.
upload content dialog

Click the Upload Content button, choose the saved frame.vhtm file and then click [OK]. Repeat for frame.js.

If you are familiar with FTP programs, you can avoid the individual uploads and clicking by simply FTPing the files to the URL displayed in the bottom right corner of the Content tab.

Configure the Domain to use the Custom Frame

Now that the files are uploaded, configure your domain to use the frame rather than the default BrainHoney frame.

1.
admin gear

Log into BrainHoney with a domain administrator account and click the Administrator gear icon to open the administration page.

2.
customization tab

Click the Edit button to open the Edit Domain dialog and then click the Customization tab.

3.

Locate the existing <files> XML element; otherwise create one. (See files for more details.) Within it, add a file element for frame:

<files>
<file type="frame" path="frame.vhtm"/>
</files>

Click [OK] when you are done.

4.

To see the custom frame, log off and log back in to BrainHoney. You'll notice quickly that since the frame has no navigation links, you can't click to leave the page! But you can enter a different component URL in the browser's address bar. For example, replace Frame/Component/Home with Frame/Component/Calendar to see the Calendar component inside the custom frame. Clicking the Return to Home Page link, does return you to the home page.