I’ve just posted a fairly major update to the wwHoverPanel ASP.NET Ajax control. I’ve been working on a project where we needed lightweight client side callbacks and while ATLAS was on our radar early on we realized that it’s just too far off from release to be able to use it in this project.
I built the wwHoverPanel ASP.NET control quite a while back before ATLAS was around in the days of Script Callbacks during the beta of ASP.NET 2.0, as a light-weight control to handle a few common tasks with very little code. Over time the scope has crept a little as I've used more and more client side code and become - ahem, a little more proficient with JavaScript <s>. So this release is basically a major refactoring of the original functionality. For those of you that have used wwHoverPanel previously, this unfortunately means that this release won't be 100% backwards compatible. I decided to break this version in favor of a much cleaner and more reusable interface. The changes are relatively minor as the concepts stay the same, but some of the names have been changed to protect the innocent... To convert the demo code from the old to the new took about an hour, plus another half an hour to convert the ATLAS Chat sample to a wwCallbackMethod sample. This might give you an idea of what's involved. You can check out all that is new here.
As a recap, wwHoverPanel provides two specific features which in my use have been very common: HoverPanel popup windows that display content from the server with a number of options and small effects on how to display the content, and making method callbacks to the server. The idea behind these controls is to provide this functionality in a real simple manner so that most properties can be set up on the server control and that requests can be fired from the client with a single line of code. The original control provided this functionality but it was all rolled into a single control which made the interface a little less cluttered.
So this update provides some serious refactoring splitting out the wwHoverPanel control and a new wwCallbackMethod control and in the process creating a small reusable client library. The interfaces for the controls have been cleaned up, so this means that this version will not be 100% backwards compatible. The overall concept of how requests are called are the same but the syntax has changed primarily due to the fact that all client code now uses reusable objects rather than static functions. The client side library also adds some base control functionality that makes common tasks easier all while trying to keep the java-script size down (27k uncompressed).
This update splits out the wwHoverPanel control and the wwCallbackMethod control into separate controls which makes both of them easier and more logical to use. On the client side I’ve completely re-written the client side and have abstracted everything into classes rather than the previously used functions. The classes are now reusable and can be easily driven with just a few lines of client code. There are also a number of new client classes that borrow some core concepts from ATLAS – which is a wwControl, wwList and wwToolTip class as well as a wwHTTP wrapper for XmlHttp and a Debug object. Talking about ATLAS the syntax is similar and I was in fact able to back port my ATLAS Chat sample with just a few minor tweaks to a wwMethodCallback Chat sample <s>. The idea is that in the future the code should be able to migrate relatively easily to ATLAS since the concepts are similar.
The advantage with this control is that it’s much more lightweight (with a 27k uncompressed javascript footprint) but of course it also doesn’t nearly the amount of what ATLAS does, although the new library does some base functionality that in my work keeps coming up over and over again. So the client control classes do things like getting and setting location and bounds, setting opacity, showing and hiding controls, adding shadows and fades. For list controls there’s also code to help databind object arrays and datatables from the server.
wwCallbackMethod Control
The new separate control is a lot easier to use – typically you now just drop the wwCallbackMethod control on a form and write a single call like this:
CallbackControl.HelloWorld(Parm1,CallbackHandler,OnErrorHandler);
The control still has a number of options such like which Postback mode to use how to embed the JavaScript library etc. but by default this is all preset.
The control can now also call back into user and server controls or you can create a more efficient HTTP handler and subclass it from wwCallbackHandler. Both of these new features were actually the primary reason I started down this update path.
One of the big omissions in ATLAS at the moment is the lack of a decent mechanism for a custom server control to get callbacks back into the control code. ATLAS makes it easy to do page level callbacks, but there’s nothing for control developers short of using raw WebRequest callbacks and then managing a raw HTTP response in the control code. So wwCallbackMethod provides an alternative by allowing a control developer to host a wwCallbackMethod control and then routing the method callbacks into the server control. There’s a new TargetControlID property that can be set that makes this possible.
The HTTP Handler interface scenario also was important as it is more efficient than the page/control level callbacks. Using an HTTP Handler allows bypassing the page pipeline. This process is easy to use as well – you can create an .ASHX page (or a standard web.config linked handler as well) to simply implement your [CallbackMethod] attributed methods.
In an .ASHX file this looks like this:
<%@ WebHandler Language="C#" Class="Handler" %>
using System;
using System.Web;
using System.Web.SessionState;
using Westwind.Web.Controls;
public class Handler : Westwind.Web.Controls.wwCallbackHandler // , IRequiresSessionState
{
//public void ProcessRequest (HttpContext context)
//{
// base.ProcessRequest(context);
//}
//public bool IsReusable {
// get
// {
// return false;
// }
//}
[CallbackMethod]
public string HelloWorld(string Name)
{
return "Hello " + Name + "! Time is: " + DateTime.Now;
}
[CallbackMethod]
protected decimal AddNumbers(decimal x, decimal y)
{
return x + y;
}
}
The control requires two things for this to work: A server URL to the handler and a type reference to the handler class so a proxy can be generated.
this.CallbackHandler.ServerUrl = "Handler.ashx"; // can also be set on the control
// must be set in code
this.CallbackHandler.TargetCallbackType = typeof(Handler);
The wwCallbackHandler manages the callback scenario so all you do is implement your methods on the handler. The Chat Service Sample is an example of how this works (you can click on the code links on thte bottom to see this work).
None of the above is necessary for page level callbacks though – there you can just create the methods on the Page and the control will set up the rest on its own.
wwHoverPanel Control
There’s not much new here – the behavior is pretty much the same as previously although there’s been a bunch of tweaking since the last release to get placement formatting to work better and with different browsers. The main change for this control is that it can now be driven entirely through client code and that it uses the control library code to perform most of the locating and formatting which means these features have been exposed in a more general way.
Client Script Library
The client script library is nothing fancy but it does a few things that continue to come up over and over again, so it seems like a good idea to abstract away in client library. It borrows the base idea and syntax from ATLAS by providing a base Control class:
var Ctl = new wwControl("divLabel");
Ctl.setText("It’s way too early for a good time!");
Ctl.show();
Ctl.setLocation( {x: 10,y:10 } );
Ctl.showShadow(8,.35);
// Fadeout after a few seconds
setTimeout(function() { Ctl.fadeout.apply(this,[true,2]) ),5000);
There’s also a wwList control, which has a setData() method and dataTextField and dataValueField properties to do databinding to an object array or a DataTable returned from a callback method. With this databinding a result to a list becomes code like this:
function GetCustomerList_Callback(Result)
{
// *** Our Result here is a DataTable which is now
// *** an object that has an array of rows and properties
// *** for each of the column values.
var DataTable = Result;
// *** Use a list control to databind easily
var List = new wwList("lstCustomerList");
List.dataValueField = "CustomerId";
List.dataTextField = "CompanyName";
List.setData(DataTable);
}
Again this concept is shamelessly borrowed from ATLAS with roughly the same syntax, but this is too useful to pass up <g>. The idea is also to make the syntax as close to ATLAS as possible for client code so that it can eventually move with little more than renaming the classes.
There’s much more that’s been changed and added but these are some of the highlights. The control is available for free and comes with source code so you can see how it’s put together and tweak it if necessary. There’s also an extensive help file (unlike some other tools from the big house <g> - damn it MS give us some decent ATLAS documentation!!!) that has step by step examples on the functionality as well as a full class reference for the server and client side controls and classes.
It’s free but I would appreciate any feedback on changes that are made though – you can post comments here or for more detailed discussions on our message board.
Enjoy.