Necessary things:
Windows XP/Vista/7/2003/2008
Visual Studio 2005 or 2008 (download the correct version of Home Site project above)
.NET Framework 2.0 and ASP.NET AJAX 1.0
Today, many browsers provide the ability to use tabs to browse more web pages and websites. Of course this is a very useful feature to replace having several browsers open at the same time, but it would also be great if it provided the ability to browse multiple web pages in one page.
For example, if your homepage is made up of many different useful web tools or sites, a tab page may be very useful. Using framesets, IFRAMEs, etc. are typical ways of hosting external content. These methods allow you to host multiple web pages on a single page. But getting them laid out correctly is not easy. Not to mention dealing with issues such as page and IFRAME scrollbars.
In this article, we try to host external data and provide a basic solution, using ASP.NET, AJAX and javascript to deal with some troubles encountered.
Plan
The main purpose is to provide a simple solution for hosting external data. This solution has the following simple requirements.
1. Provide a tab interface for easy browsing.
2. Provide a configuration method to add tabs
3. Enable each tab page to host a configured page
The basic technical requirements are:
1. Load external data content only when the tab is selected
2. Ensure that the vertical scrollbars are set to display, and only when the data that needs to be processed overflows, the scrollbars are displayed.
3. Ensure that the solution can work across browsers
The name of the solution and the name of the main page are both Home Site
Analysis
For this solution, I decided to use JQuery UI Tabs to implement tabular navigation functionality. I have also used commercial open source tab controls before. But JQuery UI Tabs are lightweight, very simple to implement, and free.
Except JQuery and tab controls and the functions provided by .net, no other controls are needed. VS2005 will be enough to combine the development environment of the entire project and choose C# as the development language.
I will be using an IFRAME to host the website content, using JQuery UI Tabs to host external web pages will not work directly due to cross-site (aka cross-domain) security restrictions.
Design
Here is a visual minimum requirement for the client:
This solution will require three different functional modules:
1. Configuration module
2. Use the tab interface of the JQuery UI Tabs plug-in
3. Use the IFRAME element to host web page content.
Configuration module:
A required feature is to make tabs configurable. I chose the minimum and put the tab configuration information into an xml file. Although I could go a step further and enable the dynamic addition and deletion of tabs, I decided to provide this functionality in the second part of this article.
The format of the XML file is as follows:
Code
|
namespace HomeSite
{
///
/// Tab configuration static handling class
///
public static class TabConfiguration
{
///
/// This class returns a collection of TabDefinition classes created from
/// parsing the tab definitions defined in the TabConfig.xml file.
///
/// The Page reference
/// calling this class
///
public static ArrayList LoadConfiguration(Page page)
{
// Local container for tab definitions
ArrayList tabList = new ArrayList();
try
{
// Read the contents of the TabConfig.xml file
StreamReader reader = new StreamReader(new FileStream(
page.MapPath("./TabConfig.xml"),
FileMode.Open, FileAccess.Read));
string xmlContent = reader.ReadToEnd();
reader.Close();
reader.Dispose();
// Create an XML document and load the tab configuration file contents
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlContent);
// Iterate through each tab definition, create a TabDefinition class,
// and add the TabDefinition to the local ArrayList container
foreach (XmlNode node in xmlDoc.SelectNodes("/configuration/tab"))
{
TabDefinition tab = new TabDefinition();
tab.ID = node.Attributes["id"].Value;
tab.DisplayName = node.Attributes["displayName"].Value;
tab.Path = node.Attributes["path"].Value;
tabList.Add(tab);
}
}
catch
{
// Do nothing
}
// Return the tab definition
return tabList;
}
}
///
/// This class serves as the container for a tab definition
///
public class TabDefinition
{
///
/// Member variable for the Unique ID for the tab
///
private string _id;
///
/// Member variable for the displayed name of the tab
///
private string _displayName;
///
/// Member variable for the web page URL to host in the tab (IFRAME)
///
private string _path;
///
/// Property for the Unique ID for the tab
///
public string ID
{
get { return _id; }
set { _id = value; }
}
///
/// Property for the displayed name of the tab
///
public string DisplayName
{
get { return _displayName; }
set { _displayName = value; }
}
///
/// Property for the web page URL to host in the tab (IFRAME)
///
public string Path
{
get { return _path; }
set { _path = value; }
}
}
}
Now, let’s take a look at the markup of the Home Site’s homepage
Code
http://www.w3.org/1999/xhtml">
The hidden code of the Home Site page is as follows:
Code
namespace HomeSite
{
///
/// Home Site (default) web page code behind class
///
public partial class _Default : System.Web.UI.Page
{
///
/// On page load we need to create the tab
/// list items for tab Interface Construction
//// & lt;/Summary & GT;
/// & LT; T;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
AddTabsToForm();
}
/// classes. This method iterates
/// through the ArrayList building HTML controls to add to the tab panel.
///
tabListItem.InnerHtml = " tab.DisplayName "" href="ContentLoader.aspx?ID="
tab.ID "&Path=" tab.Path
"">" tab.DisplayName "";
panelList.Controls.Add(tabListItem);
The hidden code does not require too much explanation. The key action is to create and set the HtmlGenericControl list item, and finally it is added to the tab panel through programming.
Problems encountered
The main problem I encountered was automatically adapting to the size of the IFRAME across browsers. The solution was tested in IE 8, Firefox v3.5.6, and Google v3.0.195.38 browsers.
I have to perform browser detection and adjust the corresponding width and height based on the size of the IFRAME tested in three browsers. Chrome and FireFox appear to have a fixed height for the IFRAME when the browser changes size. However, IE8 seems to lose the padding between the IFRAME and the top of the browser. Adjusting the width and height especially for IE seems like it should minimize the "scrunching" effect of the IFRAME to the bottom of the IE window.
Restrictions
1. The following JavaScript will cause the webpage you load to jump out of the IFRAME. I don't know of any solution to this (if it exists). The Code Project website currently has code similar to the one below, making it very easy to configure the options to point to http://www.codeproject.com/, and reproduce the actions described here.
2. In the browser, the Web page is forced to change the size of the page itself, and may jump out of the IFRAME form, thereby replacing the former parent window.
3. I have not tested this solution using Safari, Opera, earlier versions of IE, or earlier versions of any other browser, so adjust the heightAdjust and widthAdjust variables appropriately in the Home Site and adapt without testing IE browser or a browser version lower than IE8.
Summary and points of interest
While this solution is not very complex, it hosts external website content through a tabbed interface. This is a feature I've seen requested by many web forums and blogs. Please note: You can also configure tags to display your own related domain names or websites (on the same server).