Click here to Skip to main content
15,867,765 members
Articles / Web Development / IIS
Article

OverLibWrapper -- C# wrapper of the overLIB DHTML popup JavaScript library

Rate me:
Please Sign up or sign in to vote.
4.67/5 (12 votes)
15 Feb 2005CPOL12 min read 114.1K   1.1K   53   29
An article on the use of the OverlibPageControl and OverlibPopupAnchor for extended manipulation of the overLIB popup JavaScript library.

Shows the OverlibPageControl in action-PageControlDesign.jpg

Overlib objects in action

Introduction

There are plenty of popup controls out there; just do a Google search and thousands will pop up (no pun intended). More often than not, these implementations are either pure JavaScript or simplified web control extensions. While these implementations are good, I was looking for a control that would be capable of writing the JavaScript for me and providing good design-time support. In the end, what I needed was a control that was a little more robust and capable of handling multiple pre-determined and on-the-fly popups from a central location on the page. Also, the need to provide massive amounts of information via a conventional tool tip just wasn't possible. After doing some research on DHTML implementations, I came across the overLIB DHTML library and was impressed with the way that more information could be arranged in the JavaScript DHTML environment. The big limitation for this library was the fact that the developer had to write all of the commands by hand. Although there were sites out there that could write the appropriate code blocks for you, I still needed a control that had everything localized.

The purpose of this article is to discuss the capability of the wrapper control that I developed in order to accomplish the need for showing formatted information whether it be from a database, dataset, or other forms of information repository. The source code provides extensive comments on how these controls operate and what was needed to wrap the overLIB functionality. The two major controls are the OverlibPageControl which resides on any particular web page and is a central repository for binding popup tool tips to all web controls, e.g., Labels, CheckBoxes, etc., during design time, and the OverlibPopupAnchor which is a simplified hyperlink for adding popup capabilities to a word or word groups on any particular web form. I will discuss how to create and modify the popup during design- and run-time. The goal of this article is to show how this control can save time during the design and testing when lots of information, if shown as is, on a web page will make the webpage unreadable or cause major headaches when switching to lower screen resolutions.

Background

One of my previous projects needed to have the ability to show through tool tips extra data concerning a particular keyword or web control. Because of this, my searches led me to Code Project and the popup capabilities of Tomas Petricek and others within the Code Project arena.

Yet what we needed, however, was what none of these items seemed to be able to do. What we really needed was a way to handle a lot of popups from a central location within a page and also define new ones dynamically. Thus the OverLibWrapper C# namespace was created. For a more complete definition of the overLIB commands, go to the overLIB documentation site. There are a lot of commands and the definitions are much better explained on the Bosrup and Boughner pages.

Using the code

First of all, you will need to add the OverLibWrapper.dll file to your Toolbox. I will not go into the details of installing it, because many who are using this control should be familiar with adding/removing visual and non-visual controls to their IDE toolboxes. The OverLibWrapper namespace contains visual controls: OverlibPageControl, OverlibPopupAnchor and ColorComboBox. Never mind the ColorComboBox, it is a control that was developed because of some UI requirements for the design-time development of an OverlibCommand. For a quick run down, download the demo to test out the operations of the controls.

The two controls that are the most important are the OverlibPageControl and OverlibPopupAnchor. The OverlibPopupAnchor wraps itself around the basic <a> HTML control with some side benefits. For those developers that don't want or don't have a lot tool tips or even just want to play around similar to what is shown on Robert Boughner or Erik Bosrup's pages; you will want to use this item. The concept is just like adding a new hyperlink to your page, but you can also change some of the parameters to make it view whatever you wish. It contains all of the other designers there are for the OverlibPageControl so if you don't want to put a page control for just one measly anchor, you don't have to.

In the screenshots at the beginning of the article, you can see what the OverlibPageControl looks like during design-time. The following shows what is seen in the HTML view:

ASP.NET
<asp:Label id="Label1" style="Z-INDEX: 101; LEFT: 56px; 
   POSITION: absolute; TOP: 112px" runat="server">Label</asp:Label>
<asp:CheckBox id="CheckBox1" style="Z-INDEX: 102; LEFT: 32px; 
   POSITION: absolute; TOP: 160px" runat="server" Text="CheckBoxName">
</asp:CheckBox>
<olwc:OverlibPageControl id="OverlibPageControl1" runat="server" 
   PageDefaults="STICKY,FGCOLOR,'#D2691E',CAPCOLOR,'#D4D0C8',WRAP">
   <OverlibPopup ControlLink="Label1" 
   Text="This is the Tip Text shows when the control is clicked"
     Commands="STICKY,CENTER,CAPTION,'Clicked caption'" EventType="OnClick" />
   <OverlibPopup ControlLink="Label1" 
   Text="This shows when the user passes the mouse over" 
           Commands="STICKY,CENTER" 
     EventType="OnMouseOver" />
</olwc:OverlibPageControl>
The OverlibPageControl Designer

The OverlibPageControl has two properties that enable it to function within a web form. They are PageDefaults and Tips.

Properties page

The PageDefaults property connects to a custom UITypeEditor that allows the developer to build the appropriate commands that will be used for every call to the underlying overlib function call. These are the same commands that would have been normally typed by hand to the overLIB JavaScript library.

Command Editor

The Tips property opens a CollectionEditor that allows for the designer to create, delete, and modify popups for particular controls that reside on the current page. One of the good things about this control is that it allows for the developer to link more than one popup to a particular control with different actions. There are only two event types currently, OnMouseOver and OnClick. These are the most commonly used events in web development. For this article, they will be the ones that are referenced most often. As illustrated in the image below, there are two popups that govern Label1. When you mouse over Label1, a popup will appear; when you click on Label1, another popup will appear. Technically, the number of popups per control is only limited to the number of events that a particular control can handle.

Collection Editor

Inside of the CollectionEditor, the Commands property opens up the OverlibCommandEditor which is used to add commands that will be run on this particular popup. The Text property opens a text editor, and it also allows for the direct input of what the text for the ToolTip will be.

Code

Not only can popups be built in the designer, but they can also be built during runtime. This allows for greater flexibility when dynamic popups are needed.

C#
// We want to add another popup -- so we build one from scratch
    OverLibWrapper.OverlibPopup pop = new OverLibWrapper.OverlibPopup();
    pop.Text = "This is a color test";
    //this is a little hex color utility that was built 
    //by http://www.tonesco.com
    string colorStr = 
          HexColor.HexColorUtil.ColorToHex(System.Drawing.Color.Beige);
    string colorStr2 = 
          HexColor.HexColorUtil.ColorToHex(System.Drawing.Color.IndianRed);
    //add the commands that we want for this call to the overlib function
    pop.AddCommand(OverLibWrapper.OverlibCommand.BackgroundColor,colorStr2);
    pop.AddCommand(OverLibWrapper.OverlibCommand.ForegroundColor,colorStr);
    pop.AddCommand(OverLibWrapper.OverlibCommand.Caption,"This is a color Test");
    //add out control to link to -- this is the control.ID value
    //Note: if the ControlLink property is not set. 
    ///During the pre render of the control an exception will be issued 
    pop.ControlLink = "Label1";
    //add out event type: the default is onmouseover
    //Note: that if two or more controls have the same control 
    //link and have the same
    //ControlEventType, the first event will be captured, but the second
    // will be discarded even though it will remain within the code or 
    //within the design collection
    pop.EventType = 
        OverLibWrapper.ControlEventType.OnClick;
    OverlibPageControl1.Tips.Add(pop);

One of the other classes to use during run-time is the OverlibPopupTextBuilder. This class provides the same functionality as the Text Editor, but allows for the developer to specify the exact layout of the information during run-time. It is useful if you want to create a table to organize the data to display in the tool tip.

C#
OverLibWrapper.OverlibPopupAnchor anchor = 
            new OverLibWrapper.OverlibPopupAnchor();
OverLibWrapper.Design.OverlibPopupTextBuilder optb = 
            new OverLibWrapper.Design.OverlibPopupTextBuilder();
    optb.AddTable();
    optb.AddTableAttribute("border","1");
    int rowIndex = optb.AddTableRow();
    optb.AddRowCell(rowIndex,"this is some information in a cell");
    optb.AddRowCell(rowIndex,"This is an cell with information");
    anchor.Title = "Inner popup";
    anchor.PopupText = "This is text inside the popup";
    anchor.IsInnerPopupAnchor = true;
    anchor.OverlibCommands = 
            "STICKY,CAPTION,'This is an inner popup caption',WRAP";
    rowIndex = optb.AddTableRow();
    optb.AddRowCell(rowIndex,"This is another cell");
    optb.AddRowCell(rowIndex,anchor.HyperlinkString());
    string popupInformation = optb.PopupText();
//popupInformation will read:
//<table border=\'1\'>
//<tr><td>this is some information in a cell </td> 
//<td>This is an cell with
//information</td></tr><tr><td>
//This is another cell</td> 
//<td><a href="javascript:void(0);" 
//onmouseover=
//  "overlib2('This is text inside the popup',STICKY,CAPTION,'This is an
// inner popup caption',WRAP)" onmouseout="nd()2;">Inner popup</a>
//</td></tr> </table>
//this is then added to another anchor or popup and the 
//entire object is written to the rendered html

To understand more of the workings of the OverlibPopupTextBuilder, download the source code and see what is going on under the hood.

OverlibPopupAnchor

The OverlibPopupAnchor contains the same items that an OverlibPageControl does, except that it is more compact in its representation to the developer. This control displays a text hyperlink that is already set up to display popups. One limitation to using the anchor is that it cannot have multiple event types added during design time.

OverlibCommand and OverlibCommandCollection

The OverlibCommand and OverlibCommandCollection are two of the classes that build the command structure for a call to the overlib function. The OverlibCommand contains the entire list of 100+ overLIB commands that comprise the core and official plug-in for the overLIB library. The OverlibCommandCollection is a strongly typed collection that allows for the normal methods for a collection (i.e., Add, Remove, IndexOf, etc). One of the more interesting methods of the OverlibCommandCollection is the ToString() method. When calling the ToString(), the return value is a comma delimited string containing all of the commands that were inserted into the collection. This is the exact format that the overLIB JavaScript library expects the commands to be in. The OverlibCommandEditorDialog contains an OverlibCommandCollection that will parse the incoming string of commands and convert them into valid OverlibCommands for editing. It is best not to directly create an OverlibCommand, but to use the OverlibPopup to add particular commands with values to the popup.

OverlibPopup

This class is one of the other important items within the OverLibWrapper namespace. The OverlibPopup class is parsed and generated by the OverlibPageControl. The OverlibPopupCollection contains the popups during design and rendering. When adding a new OverlibPopup during design and runtime, it is imperative that the ControlLink property is set to a WebControl that is currently on the design view of the web form. By setting the ControlLink property, you are indicating that the particular popup is going to show for that particular WebControl. If the property is not set then exceptions will be thrown when execution of the web page happens.

Examples of each of the above mentioned command types are:

C#
OverlibCommand.Sticky; //flag type command
    OverlibCommand.Caption; //quoted text command
//a text command; this is required for those commands that
//are looking for objects on the page using JavaScript    
OverlibCommand.Frame;  
// a color command in the form of '#FFCCAA'
    OverlibCommand.ForegroundColor;

The following is an example of creating a popup and adding the various commands with their associated values:

C#
OverLIBWrapper.OverlibPopup pop = new OverLIBWrapper.OverlibPopup();
    pop.Text ="A new popup";
     //this is a plugin command (unofficial)
    pop.AddCommand(OverLIBWrapper.OverlibCommand.Draggable);
    //this is a core command
    pop.AddCommand(OverLIBWrapper.OverlibCommand.Center); 
    //core command with a quoted text value the single quotes are 
    //optional because the logic behind the OverlibCommand is 
    //that it will automatically determine whether or 
    //the text has to be quoted.  Another item is that it will automatically 
    //escape the single quotes that internal to the string value.
    pop.AddCommand(OverLIBWrapper.OverlibCommand.Caption,"This is a test");  

    //if the controlLink is not set there will be exceptions thrown 
    //during pre-render of this control
    pop.ControlLink = "Label1";  //this is equivalent to Lable1.ID
    //this adds the command to the current page control's popup collection
    OverlibPageControl1.Tips.Add(pop);

Points of Interest

A point of interest that you may find interesting is the problem with trying to find the particular controls on the page. Tomas (mentioned earlier) got me half way to point with his UITypeEditor that finds controls via the current context instance. However, when you create a new instance of a CollectionEditor and add a new object, there is a problem with finding the current service that gives you the reference that has all of the controls on the page. The following snippet can be used with some minor modifications to find anything on the page that you wish:

C#
public override object EditValue(ITypeDescriptorContext context,
                        IServiceProvider provider,object value){
  if (context!=null && context.Instance!=null && provider!=null) {
      edSvc=(System.Windows.Forms.Design.IWindowsFormsEditorService)
   provider.GetService(typeof(
       System.Windows.Forms.Design.IWindowsFormsEditorService));
        if (edSvc!=null) {                    
            lb=new System.Windows.Forms.ListBox();
            lb.BorderStyle=System.Windows.Forms.BorderStyle.None;
            lb.SelectedIndexChanged+=
                new EventHandler(lb_SelectedIndexChanged);
            ArrayList items = new ArrayList();
            System.Web.UI.Control parentControl = null;
            // gets all controls from the form
            //this grabs the service for all the references that the provider has
            //this is key if you are calling this editor 
            //from inside another editor
            //,i.e., a CollectionEditor
            IReferenceService service = 
              (IReferenceService)provider.GetService(typeof(IReferenceService));
            object[] references = 
                service.GetReferences(typeof(System.Web.UI.Control));
            //grabs the parent control based on the references.
            foreach(Control control in references){
                if(control.GetType() == typeof(System.Web.UI.UserControl) ||
                   control.GetType() == typeof(System.Web.UI.Page)){
                    parentControl = control;
                    break;
                }
            }
            if (parentControl == null) {
                return "No controls found";
            }
            //recursively grabs all the controls 
            //within each control's Controls container
            //otherwise the only level we will see 
            //is the Page level controls, i.e. those
            //controls that put on the actual page.
            //All other controls that are placed 
            //inside panels,
            //or other containers will not be shown 
            //and thus if you wish to get a 
            //control that is two or three levels deep or if there is a 
            //master page context
            //you will be out of luck.
            //This is especially the case when wanting to create a UserControl.
            //and adds them to the item list
            foreach(Control ctrl in parentControl.Controls){
                GetControls(ctrl, items);
            }
            items.Sort();
            lb.Items.AddRange(items.ToArray());
            edSvc.DropDownControl(lb);
            if (lb.SelectedIndex==-1) return value;
            return lb.SelectedItem;
        }
    }

    return value; 
}

Another item to note is that trying to incorporate an already valid piece of code without rewriting it for yourself can be a big problem. Since this was the case in using overLIB JavaScript files, the idea of compiling them as resources and then inserting the resource files into the calling web project was both a good idea and a challenge. Two other classes inside the OverLibWrapper namespace helped in the manipulation of the web.config file and inserting the appropriate folders and files into the current web project. These classes are generic enough to insert and manipulate just about any embedded resource that you want inserted into a particular web project. OverLibWrapper.Design.ProjectController handles the file insertion from an embedded resource. OverLibWrapper.Design.AppConfig works with and manipulates the configuration files. For those of you who are sticklers for comments, you can even insert a comment into the particular configuration file based on the key that you had just inserted.

During the OnPreRender() of both the OverlibPageControl and the OverlibPopupAnchor, the requisite overLIB JavaScript elements are generated and written to the page. Both controls are smart enough that if there are problems with the overLIB script location, or with the text that is supposed to be displayed, nothing will be injected into the page so that there is no clutter when you are trying to troubleshoot other elements of your web form source.

Tips, Tricks, and Troubleshooting

OverlibPageControl

  • Dragging and dropping more than one page control onto a web form will result in an exception. Don't worry. This is by design. Since the OverlibPageControl holds a collection of OverlibPopups there is really no need to have more than one control per page.
  • The JavaScript files for the overLIB library are embedded into the .dll. This means that the user never needs to worry about the ultimate location of the JavaScript files. It is loaded into the current web project automatically.

    Image 6

  • The action of dragging and dropping the control will automatically load into the web project the appropriate files and also insert into the web.config the appropriate JavaScript file location set to the root level.
    XML
    <appSettings>
      <add key="overLIBLocation" value="/OverlibDemo/overLIBScripts" />
    </appSettings>
    
  • If you wish to get rid of the page control, do not delete the overLIBScripts folder or the appSettings key first. If this happens and then you delete the control, during its refresh and initialization cycle the location of the key and the actual physical folder will be checked. If neither item exists, it will restore the key and all of the files. Don't worry, this is done by design. Too many times in the past, when other component developers developed high-speed low-drag controls, there was lots of work on the down-level developer's part to ensure that external file folders existed during the development and deployment process. This is not the case with this control. It has everything it needs to survive on your page, short of a nuclear explosion. The key here is to delete the control on the page first, then delete the web.config key, and finally the directory that holds the overLIB JavaScript files.
  • One of the nice things about this control is that when you feel there is an update on the overLIB JavaScript's, you can just copy the files over to the local file folder, and barring any unforeseen function or keyword additions, the code will work as is.
  • The goal of wrapping the overLIB library was to leave the JavaScript alone and just allow the control to do all the work. I think that has been accomplished.
  • The OverlibPageControl's mission is to be designer friendly. It will tell you where it sees the appropriate files, <appSettings></appSettings> key, and also the total number of popups that the control contains.
  • This control has a rich UI that allows for the developer to do most of the work during design-time.

OverlibPopupAnchor

  • Dragging and dropping the control onto the web form will conduct the same actions as the OverlibPageControl. Like the OverlibPageControl, adding this control to your page will insert the <appSettings> reference and also put the overLIBScripts folder in your web project.
  • Note: The action of deleting the overLIBScripts directory or excluding it from the project or deleting the overLIBLocation from the <appSettings> will not be automatically re-added with an OverlibPopupAnchor. This is due to the fact that the OverlibPopupAnchor only looks for the appSettings key and file folder location during the creation of the control.
  • The OverlibPopupAnchor is really only designed for smaller implementations on a page, where there is predominately a lot of text present. For a more robust implementation where there are controls, an OverlibPageControl would be more suited for development.

Thanks

My deepest thanks go to the Code Project authors that provided serious timesaving steps and helped me muddle through some of the more distressing parts of this implementation. Other thanks and nods go to Erik Bosrup and his helpers for coming up with a well received and highly used piece of JavaScript and allowing me to wrap their code. Thanks also goes to Rob Battle for hitting me in the head a few times to drive me in the right direction during some of the seemingly hard portions of this code.

Legal

All overLIB JavaScript code is copyright of Erik Bosrup and Robert Boughner.

All other code is copyright to their respective developers.

At no time during the development of this code was intentional infringement conducted.

History

2005-02-16 -- Initial writing of this article.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead Avanade, Inc
United States United States
A software developer for a medium sized company with a Microsoft product core development strategy.

Comments and Discussions

 
GeneralJust what I needed Pin
djechelon11-May-08 10:10
djechelon11-May-08 10:10 
GeneralRe: Just what I needed Pin
ThaddParker18-May-08 8:11
ThaddParker18-May-08 8:11 
GeneralRe: Just what I needed Pin
djechelon19-Jun-08 10:44
djechelon19-Jun-08 10:44 
QuestionGetting OverLibWrapper to work with a master page Pin
AMAM224-Jan-07 0:44
AMAM224-Jan-07 0:44 
QuestionRe: Getting OverLibWrapper to work with a master page Pin
paleFro5-Mar-07 11:38
paleFro5-Mar-07 11:38 
AnswerRe: Getting OverLibWrapper to work with a master page Pin
AMAM25-Mar-07 20:40
AMAM25-Mar-07 20:40 
QuestionCLOSECLICK Pin
ChrisNickel26-May-06 4:43
ChrisNickel26-May-06 4:43 
AnswerRe: CLOSECLICK Pin
ThaddParker31-May-06 4:32
ThaddParker31-May-06 4:32 
AnswerRe: CLOSECLICK Pin
ThaddParker31-May-06 10:05
ThaddParker31-May-06 10:05 
GeneralWeb User Controls Pin
Yao Xi26-Oct-05 1:14
Yao Xi26-Oct-05 1:14 
GeneralRe: Web User Controls Pin
ThaddParker28-Oct-05 14:04
ThaddParker28-Oct-05 14:04 
GeneralRe: Web User Controls Pin
Yao Xi29-Oct-05 7:37
Yao Xi29-Oct-05 7:37 
GeneralRe: Web User Controls Pin
ThaddParker7-Dec-05 5:09
ThaddParker7-Dec-05 5:09 
Question.resx files missing from source code? Pin
neilck19-Sep-05 10:14
neilck19-Sep-05 10:14 
AnswerRe: .resx files missing from source code? Pin
ThaddParker19-Sep-05 17:09
ThaddParker19-Sep-05 17:09 
GeneralRe: .resx files missing from source code? Pin
neilck20-Sep-05 4:57
neilck20-Sep-05 4:57 
AnswerRe: .resx files missing from source code? Pin
ThaddParker22-Sep-05 15:33
ThaddParker22-Sep-05 15:33 
Question.Net 2.0 Version? Pin
Anonymous4-Apr-05 20:05
Anonymous4-Apr-05 20:05 
AnswerRe: .Net 2.0 Version? Pin
ThaddParker6-Apr-05 3:47
ThaddParker6-Apr-05 3:47 
GeneralRe: .Net 2.0 Version? Works. Pin
Anonymous7-Apr-05 7:45
Anonymous7-Apr-05 7:45 
GeneralRe: .Net 2.0 Version? Works. Pin
ThaddParker8-Apr-05 3:57
ThaddParker8-Apr-05 3:57 
GeneralRe: .Net 2.0 Version? Works. Pin
gigaty7-Dec-05 3:49
gigaty7-Dec-05 3:49 
GeneralRe: .Net 2.0 Version? Works. Pin
ThaddParker7-Dec-05 4:57
ThaddParker7-Dec-05 4:57 
GeneralRe: .Net 2.0 Version? Works. Pin
gigaty8-Dec-05 12:17
gigaty8-Dec-05 12:17 
GeneralRe: .Net 2.0 Version? Works. Pin
jonavi24-May-06 15:00
jonavi24-May-06 15:00 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.