An HTML Panel is an element that allows HTML to be placed in the element from external sources. The HTML can from a HTML fragment or from an ID from a complete HTML page.
This widget allows any amount of content to be pulled into a single page, one piece at a time. When using the techniques of progressive enhancement, this will allow the page to degrade gracefully in a non-Javascript environment.
<div id="mainContent"> This is static content that will remain in place until the user clicks on a link below! </div> <script type="text/javascript"> var mc = new Spry.Widget.HTMLPanel("mainContent"); </script> ... <a href="products.html" onclick="mc.loadContent(this.href, {id: "mainContent"}); return false;"">Products</a> <a href="about.html" onclick="mc.loadContent(this.href, {id: "mainContent"}); return false;"">About</a>
In the example above, an HTML Panel object is created for the div container with the "mainContent" id. This is the HTML Panel. The links on the page has an onclick attribute defined that will load the value of the href via the HTML Panel object. If you look at each onclick attribute, you will see a call to 'mc.loadContent()'. 'mc' is the name of the widget instance. This causes an asynchronous load request for the URL in the link's href attribute. Notice that an id: "mainContent" is being passed into the loadContent() call. This tells the HTML Panel to load only the content within the "mainContent" element. If you are loading HTML fragments instead of whole pages, there is no need to specify the id of the element to extract from the data being requested.
Before you add Spry to your web pages, download and link the appropriate files.
<head> ... <script src="includes/SpryHTMLPanel.js" language="javascript" type="text/javascript"> <link href="SpryHTMLPanel.css" rel="stylesheet" type="text/css"> ... </head>
<body> ... <div id="myPanel">This is default text.</div>
<table width="200" border="1">
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>4</td>
<td>5</td>
<td>6</td>
</tr>
<tr>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
</table>
<body> ... <div id="myPanel">This is default text.</div>
<script> var panelWidget = new Spry.Widget.HTMLPanel("myPanel"); </script>
<body> ... <div id="myPanel">This is default text.</div>
<a href="#" onclick="panelWidget.loadContent("frag.html");>Load Frag</a>
<script> var panelWidget = new Spry.Widget.HTMLPanel("myPanel"); </script>
Progressive Enhancement is a methodology of building pages. The idea is to start out with a basic, static web page, and incrementally add functionality to it, ensuring that it works correctly in a browser with javascript turned off or on other devices. The goal is to add polish to the page without interfering with its ability to deliver the content. Read more about it here: http://en.wikipedia.org/wiki/Progressive_enhancement.
In the above steps, we used the most basic example possible, just so understanding the concept was clear. Now, with a simple modification, we can progressively enhance the widget.
Using the code above, if javascript was turned off, there would be no way to get to the frag. There is no real value in the href field, yet, the onclick attribute has a file path to the frag. So we will modify the code to ensure this will work in a non-scripting environment.
<body> ... <div id="myPanel">This is default text.</div>
<a href="frag.html" onclick="panelWidget.loadContent(this.href);return false;">Load Frag</a>
<script> var panelWidget = new Spry.Widget.HTMLPanel("myPanel"); </script>
In this code above, we moved the file path 'frag.html' to the href of the link, where it usually goes in a link. To the onclick event, we replaces the file name with 'this.href'. This is a javascript object property who's value IS the href value for 'this' link. Therefore, we grab the actual href value and use that in the loadContent function. The 'return false' prevents the link from being followed and instead, keeps us on the same page and loads the panel.
Now, with this code, it works fine with javascript on. If javascript is off, the onclick is ignored and clicking the link will take you to 'frag.html', as expected. This makes your content readable in both environments!
Option | Default | Type | Description |
---|---|---|---|
id | null | string | This is the ID of the content within a complete HTML page that would be loaded in the widget. |
Method | Description |
---|---|
addObserver(observer) | Adds an observer to the region. As with other components within Spry, the observer can be either an object or a function callback. The set of notifications can be found here. |
removeObserver(observer) | Removes an observer that was registered with addObserver. |
enableNotifications() | Enables observer notifications. Notifications are enabled by default within an HTML Panel. * Note that the enabling/disabling of notifications is managed by an internal count, so calls to enableNotifications() and disableNotifications() can be nested within the call stack. As the callstack unwinds, the number of enableNotifications() must match the number of disableNotifications() that were previously called before notifications will be enabled again. |
disableNotifications() | Disables any notifications to observers. |
loadContent(url, opts) | Fires off a request for the HTML fragment at the specified URL. The opts arg is an object that may include the following properties:
Calling this method will result in the following notifications:
The notifications above are listed in the order that they should fire. Should the load fail, an onLoadError notification will be fired in place of an onPostLoad notification. If the HTML Panel is in the midst of loading content when this method is called. The previous load request is cancelled prior to making the new request. |
cancelLoad() | Cancels any pending request for content. If a pending request is cancelled, this method will result in the following notifications:
|
setContent(htmlFrag, id) | Replaces the contents of the region container with the content in the specified html fragment string.
Calling this method will result in the following notifications:
<input type="button" onclick="panelWidget.setContent('<strong>This is strong text</strong>');"> |
removeStateClasses() | Removes any CSS Behavior class names from the region container element. |
The following notifications will be fired off during loadContent() or setContent() calls.
Notification | Description |
---|---|
onPreLoad | The HTML Panel is about to load a new HTML Fragment. An object that describes the load request will be passed to all observers. This object will have the following properties:
This object may also contain other optional properties specified by the user during the call to loadContent(), which may include:
It should be noted that observers are allowed to modify this object to alter the loading behavior. For example, observers can use this notification to tack on extra query parameters to the URL or postData, or even add username/password info. |
onPostLoad | The HTML Panel has successfully loaded the new HTML Fragment. An object that describes the load request will be passed to all observers. This object will contain the same properties as those listed above for the onPreLoad notification, but will also contain the following properties:
|
onPreUpdate | The content within the region container is about to be updated/replaced. An object with the following properties will be passed to all observers:
It should be noted that observers are allowed to modify the data in this object to alter the actual content that is inserted into the region container. |
onPostUpdate | The content within the region container has been updated. The same object passed during the onPreUpdate notification is passed to the observers for this notification. |
onLoadError | The request for the HTML Fragment failed. An object that describes the load request will be passed to all observers. This object contains the same properties as those listed for the onPreLoad notification, but will also contain the following properties:
|
onLoadCancelled | The request for the HTML Fragment was canceled. An object that describes the load request will be passed to all observers. This object contains the same properties as those listed for the onPreLoad notification, but will also contain the following properties:
|
The HTML Panel object will place the following CSS class names on the region container element:
Class Name | Description |
---|---|
HTMLPanelLoading |
The HTML Panel is in the process of loading content. This class is placed on the container element just before a load is kicked off. |
HTMLPanelError | The HTML Panel encountered an error while loading content. This class is placed on the container if the region fails to load the content. |
These classes are automatically placed on the region container at the appropriate times. They will be automatically removed from the container when a call to loadContent() or setContent() is called. If the developer wishes to remove these classes, they can manually remove them, or call removeStateClasses().
State markup allows for 'loading' and 'error' content to be displayed as the new content is loading in the region or when an error occurs. This emulates the spry:state attribute. In order to avoid custom attributes, a set of pre-defined class names is used to identify the "state" markup.
Class Name | Description |
---|---|
HTMLPanelLoadingContent |
The content to be used when the HTML Panel is loading data. |
HTMLPanelErrorContent | The content to be used when the HTML Panel encounters an error while loading data. |
Upon instantiation, the HTML Panel will search the region container for any elements that have one of the classes listed above. Any elements found, will be removed from the document and serialized. The HTML Panel will then inject the appropriate content into the region container during the loading or error states.
It should be noted that the state content will be injected into the region container *WITHOUT* the state classes on it. The reason is that for the purposes of graceful degradation, when JavaScript is off, the designer may not want that content to be visible.
The default style sheet for the HTML Panel is:
/* This class is placed on the HTML Panel Container element * whenever it is loading data. */ .HTMLPanelLoading { } /* This class is placed on the HTML Panel Container element * when a load request has failed. */ .HTMLPanelError { } /* These classes are used to hide any HTML Panel state markup * within an HTML Panel container. */ .HTMLPanelLoadingContent, .HTMLPanelErrorContent { display: none; }
The region only supports one element per state. That is, if you place the "HTMLPanelLoadingContent" class on 2 divs underneath the region container, the HTML Panel object will only use one of those divs.
By default, the HTML Panel will not execute scripts embedded within the loaded content.
Developers may want to enable the execution of scripts. The HTML Panel has 2 built-in switches for controlling the execution of embedded scripts.
The first is a global 'Spry.Widget.HTMLPanel.evalScripts'.
By default, the value of this global is 'false', which means script will not be executed. The developer can globally enable the execution of JS in *all* HTML Panels by setting this global to 'true' before the instantiation of an HTML Panel.
Developers also have the ability to specify whether or not each region instantiated will process scripts by passing an 'evalScripts' constructor option. When set to true, if it finds any scripts, it will remove/extract the script out of the HTML fragment, insert the HTML fragment into the DOM, and then execute the script with a call to eval().
<script src="../../includes/SpryHTMLPanel.js" type="text/javascript"></script>
<script type="text/javascript">
// hr1 will not evaluate embedded script because evalScripts is false by default.
var hr1 = new Spry.Widget.HTMLPanel("region1");
// hr2 *WILL* evaluate embedded script because of the
// the evalScripts constructor option below.
var hr2 = new Spry.Widget.HTMLPanel("region2", { evalScripts: true }); // hr2 *WILL* evaluate embedded script.
or
<script src="../../includes/SpryHTMLPanel.js" type="text/javascript"></script> <script type="text/javascript"> Spry.Widget.HTMLPanel.evalScripts = true; ... // hr1 will evaluate embedded script because the global var has been changed from false to true. var hr1 = new Spry.Widget.HTMLPanel("region1"); // hr2 *WILL NOT* evaluate embedded script because of the // the evalScripts constructor option below. var hr2 = new Spry.Widget.HTMLPanel("region2", { evalScripts: false }); // hr2 *WILL NOT* evaluate embedded script.
Copyright © 2007. Adobe Systems Incorporated.
All rights reserved.