Web Parts - How to create a tabbed view

 

Web Parts - How to create a tabbed view

Categories

During my podcast interview with Craig I discuss how readers of my book learn how to take the basic components in the portal framework - zones, web parts, etc - and to customize them to suit everyday requirements.  In the book I really strove to show examples that are quite common, and that my readers would undoubtedly be called upon to implement in their own portals.  A couple of these examples were:

  1. A catalog zone which displays in a pop-up dialog.
  2. An editor zone with collapsible/expandible editor parts.
  3. The ability for users to remove web parts that cause a page to crash.

Anyways, today while browsing the ASP.NET forums I saw a request for a common portal feature - tabbed views.  Before I explain how to implement such a feature, take a look at the following 2 images which show tabbed views implemented in the Google and Live portals:

 

Live Portal Pages Google Portal Pages

 

 

Throughout the remainder of this article I will discuss what is required to allow users to have a tabbed view and to add code that allows a user to drag web parts from one tab and onto another tab.  When our page is complete it will look like so:

 

Custom Portal Pages

As you can see, it's from this simple page that a user could drag the Untitled web part from WebPartZone1 (which resides on Tab 1) and onto another zone named WebPartZone2 (which resides on Tab 2).  OK, without further ado, let's get cracking.  First things first, let's create a basic page with some tabs on it...

 

Create a page with Tabs

For our example, we'll create a very simple page with 2 tabs with a zone in each tab.  Each zone will begin with a single web part.  To do this I need to add the following HTML to my web form:

 

<asp:WebPartManager ID="WebPartManager1" runat="server" />
<div id="page">
<div id="tabs">
<span class="tabheader" id="tabheader1" onmouseover="DisplayTab('1') ;">Tab 1</span>
<span class="tabheader" id="tabheader2" onmouseover="DisplayTab('2') ;">Tab 2</span>
</div>
<div id="tab1" class="tabpage_visible">
<div class="tabbody">
<asp:WebPartZone ID="WebPartZone1" runat="server">
<ZoneTemplate>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</ZoneTemplate>
</asp:WebPartZone>
</div>
</div>
<div id="tab2" class="tabpage_hidden">
<div class="tabbody">
<asp:WebPartZone ID="WebPartZone2" runat="server">
<ZoneTemplate>
<asp:Calendar ID="Calendar1" runat="server"></asp:Calendar>
</ZoneTemplate>
</asp:WebPartZone>
</div>
</div>
</div>

 

From the HTML we can see that the first control which has been added is the WebPartManager; this control is required on all web part pages as it really is the brains of all of the portal operations.  Next we can see that I've added a DIV element with an ID of "tabs" which will contain the SPAN's for each tab that I want to display.  You could use an HTML UL for the tabs if you want to get a little fancier with the CSS styles but I've used SPAN's for simplicity.  After the tab elements we have DIV's for each page that is associated with a tab.  For example, the DIV with the ID of "tab1" is associated with the SPAN with the ID of "tabheader1".  The idea being that when the user clicks on a tabheader, a piece of javascript will get executed to ensure that the correct tab page is visible.  Before taking a look at the javascript which will handle the clicks on the tab headers, I'll quickly present the CSS that is used to layout the page:

 

.tabpage_visible {
height: 300px;
width: 400px;
background-color: yellow ;
display: "";
position: absolute ;
}
.tabpage_hidden {
height: 300px;
width: 400px;
background-color: yellow ;
display: none ;
position: absolute ;
}
.tabheader {
height: 40px;
width: 150px;
background-color: silver ;
color: black ;
position: relative ;
}
.tabbody {
height: 100%;
background-color: white ;
}

 

Again, we have some very simple stuff happening here.  The tabpages have a style for their visible and hidden state; theres a style for the tabs in the header; and finally a style which sets some styles for the body of a tab page.  Very simple stuff.  The magic that will allow a user to switch between tab pages is a small piece of javascript which is invoked when the user clicks on tab - it looks like so:

 

var tabs = ["tab1", "tab2"] ;
var _currentTab = null ;
window.onload = function() {
DisplayTab(1) ;
} function DisplayTab( tabNumber ) { var newTab = document.getElementById("tab" + tabNumber) ; if( newTab == null || newTab == _currentTab ) return ; for( var i=0; i<tabs.length; i++ ) { var tab = document.getElementById(tabs[i]) ; tab.className = (tab == newTab) ? "tabpage_visible" : "tabpage_hidden" ; } _currentTab = newTab ; }

 

Two global variables - tabs and _currentTab - are used to store references to the tabs and to keep track of which tab is the one that is currently being displayed to the user.  When window loads, we preset the currently loaded tab to be tab1; this is achieved by calling our DisplayTab helper function and passing in the number of the tab that we want to display.  This is the same helper function which gets called when the user clicks on a tab link.

So that's the end of our simple tabbed page and at this point you can run it and click between the tab pages. 

 

Enabling dragging between tabs

Now that we've seen how to create a very simple tabbed interface we need to work out how to allow the user to drag web parts between separate tabs.  The way that we'll be doing that in this article is by listening to drag events and then writing some custom logic to determine whether the drag is occurring over one of our pages.  To do this we'll attach an event handler to the ondragover event of the document using the attachEvent method - also we must remember to clean up after ourselves by calling detachEvent when the page unloads:

 

window.onload = function() {
DisplayTab(1) ;
document.body.attachEvent("ondragover", CheckTabs);
}
document.onunload = function() {
document.body.detachEvent("ondragover", CheckTabs);
}

 

Here we see that the attach/detach event methods have been added to the code which will handle the page loading and unloading.  Now whenever the user is dragging web parts around on their page, the method that we've wired up to the ondragover event of the document will be run - the CheckTabs method which looks like so:

 

function CheckTabs() {
var eventLocation = __wpGetPageEventLocation(window.event, true);
for( var i=0; i<tabs.length; i++ ) {
var tab = document.getElementById(tabs[i]) ;
var headerId = "tabheader" + (i+1) ;
var tabHeader = document.getElementById(headerId) ;
if (IntersectsWith(eventLocation, tabHeader)) {
DisplayTab( i+1 ) ;
break ;
}
}
}
function IntersectsWith(location, el) {
var withinX = (location.x < (el.offsetLeft + el.offsetWidth)) && (location.x > el.offsetLeft)
var withinY = (location.y < (el.offsetTop + el.offsetHeight)) && (location.y > el.offsetTop)
return withinY && withinX ;
}

 

The first thing that you'll notice about the CheckTabs function is that it calls a helper function named __wpGetPageEventLocation to determine the location of the dragover event which has just taken place.  The wpGetPageEventLocation function is a private function that is contained within the resources of the ASP.NET .dll and probably isn't really designed to be called from your own code smile_regular  It doesn't really do anything overly special and so you could just include your own logic for getting the location of the event - but I'm going to use their here for brevity.

As we progress down through the CheckTabs method you will see that what we are doing is to cycle through each of the tabs and using another custom function named IntersectsWith to check whether the event location (the drag) is over a tab - if so, we call our handy DisplayTab function to display that tab.

That's really all there is to being able to drag web parts between pages and at this point you should run your page to note that when you drag a web part from one zone, and drag it up over a tab, that the tab page becomes the active page and you will be able to view the other zone.

Gotcha!

For those of you who have made it this far and run the example, you will notice that while you can drag a web part and have it switch pages, you are not actually able to drop that web part into the zone on the other page.  When I first created this sample today and I saw this behavior I was stumped - in fact it took me a couple of hours to debug the issue.  It turns out that positioning logic on the previously hidden zone is a little screwy and that, whenever we switch between tab pages we must call another private ASP.NET javascript function to make things right smile_omg.  So, provided you are happy enough calling a couple of undocumented ASP.NET javascript functions I will now show you which function to call smile_regular:

 

function DisplayTab( tabNumber ) {
var newTab = document.getElementById("tab" + tabNumber) ;
if( newTab == null || newTab == _currentTab )
return ;
for( var i=0; i<tabs.length; i++ ) {
var tab = document.getElementById(tabs[i]) ;
tab.className = (tab == newTab) ? "tabpage_visible" : "tabpage_hidden" ;
}
_currentTab = newTab ;

}

 

The function in question is highlighted in red and has been inserted at the end of the DisplayTab helper function.  This function cycles through the zones contained within the web part manager and ensures that the left, right, top, and bottom measurements are correctly reflected in the in-memory instances of all zone and web part variables. 

That's it, re-run your page now and you should have a perfectly working prototype that allows you to drag web parts from one tab page to another.

转载于:https://www.cnblogs.com/wgx1323/archive/2006/12/18/595722.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值