dnntipsandtricks In late 2007, Nik Kalyani created what I think is one of the coolest new DotNetNuke features to arrive in quit a while – DotNetNuke Widgets.  Nik recently started work on a multi-part blog series on Widgets.  As he explains, DotNetNuke Widgets are a powerful client-side counterpart to the server based extension model exemplified by DotNetNuke Modules.  Where a module generally consists of code that is executed on the server, a widget primarily consists of JavaScript to be executed in the browser.  This is not to say that a module can’t include rich client functionality or that widgets can’t include server-side code:  indeed both options are certainly possible.   With widgets the focus is on building functionality that is easily added through custom object tags.  You can emit these tags from a Module, in a Skin or directly in an HTML module.  Anywhere you can add HTML to the page output, is a place you can add a widget.

With any new technology there is always the question of why someone would use it.  Why would someone not just add custom JavaScript or use an existing widget framework (there certainly are a lot to choose from)?  I have used a number of widgets and scripts on my pages and in general I don’t find that they are particularly geared for use by many of the non-technical users who ultimately edit and maintain DotNetNuke websites.  Most widgets and scripts require a certain level of technical knowledge by the end user, and in many cases, they impose some dependency on a third party website.  DotNetNuke Widgets attempt to resolve these issues and many others.  Since widgets are first class citizens in the DotNetNuke extensibility model, they can be packaged, versioned and installed just like any other DotNetNuke extension.  This eliminates any dependency on a third party website since many widgets are fully self-contained.  Also, because the widget is created on the page with a simple Object tag, they are much easier for a non-programmer to understand and add to the page (there is still some room for improvement which I hope to address in 2010).

Phil Haack recently discussed how he uses jQuery to create a Hide/Close link.  Typically you would see this where you have a panel and you want to show it or hide it based on user clicking a link or a button.  In Phil’s case, the code is pretty specialized and not very flexible.  If you have a slightly different use case, you would need to modify the JavaScript which ruins the reusability of the solution.  With the DotNetNuke VisibilityWidget we can avoid this problem since it provides quite a bit of flexibility out of the box.  The code to add the widget to a page looks something like this:

<object id="Toolbox" codetype="dotnetnuke/client" codebase="VisibilityWidget" declare="declare">
    <param name="expandClassName" value="Layout-Masthead-InfoBar-ToolBoxIcon-Expanded" />
    <param name="collapseClassName" value="Layout-Masthead-InfoBar-ToolBoxIcon-Collapsed" />
    <param name="targetElementId" value="Layout-ToolBox" />
    <param name="title" value="Toolbox" />
</object>

In this case, the widget will generate a button and use the expand/collapse classes to style the button.  You can see this in action in the Extropy skin which was shipped with early betas of DotNetNuke 5.0.  You can find an updated version of this skin on CodePlex.  As we finalized the DotNetNuke 5.0 release, we added the ability to define a source element as well as a target element.

<object id="Toggle" codetype="dotnetnuke/client" codebase="VisibilityWidget" declare="declare" style="display: none">
    <param name="eventSourceElementId" value="mybutton" />
    <param name="targetElementId" value="helloworld" />
</object>

<a id="mybutton" href="#">Click Me</a>
<div id="helloworld">Hello World!</div>

In this example I can now link up two distinct page elements and I don’t even have to use any JavaScript – that is all taken care of for me by the widget.

Well, that is great.  Unfortunately, the widget as originally coded simply toggled the visibility of the target element.  Given the power of jQuery, which is shipped with DotNetNuke, it seems somewhat limiting to only allow the user to show/hide an element.  It would be better if the widget supported custom animations or other jQuery effects like slides and fades.

Being on vacation gave me a few extra hours to update the widget to allow the user to call their own custom animation functions.  While I was at it, I also converted the widget to take advantage of jQuery.  Since the widget framework already uses jQuery, I am guaranteed that it will already be loaded on the page.  With my updated widget code in place, I am now free to do something like this:

<object id="Toggle" codetype="dotnetnuke/client" codebase="VisibilityWidget" declare="declare" style="display: none;">
    <param name="eventSourceElementId" value="mybutton" />
    <param name="targetElementId" value="helloworld" />
    <param name="toggleFunction" value="customToggle" />
</object>

<a id="mybutton" href="#">Click Me</a>
<div id="helloworld">Hello World!</div>

Instead of using a simple jQuery toggle method to show/hide my hello world element, I am now calling a custom JavaScript function defined below:

function customToggle(e) {
  if (e.data.targetElement.is(":visible")){
    e.data.targetElement.css("border","1px solid blue");
  }
  else
  {
    e.data.targetElement.css("border","none");
  }
  e.data.targetElement.slideToggle("slow");
}

You can download the latest version of the VisibilityWidget from the DotNetNuke sourcecode on CodePlex.  The widget is stored in the /Website/Resources/Widgets/DNN folder and will be included in the 5.2.2 release of DotNetNuke that will be available mid January.

While the visibility widget is not the flashiest widget around, I found it pretty cool that I could easily solve Phil’s initial challenge without needing to add any JavaScript whatsoever.  I also was not constrained by the name of my page elements or the type of page elements.  All of this was included with DotNetNuke out of the box.  Over the coming months I hope to see more developers embrace the widget framework and start creating some great widgets for everyone to use and enjoy like this great example that Nik posted earlier today.