Over the last several years web developers have moved more and more code to the browser in an effort to improve the overall user experience. This code is usually in the form of JavaScript libraries which provide advanced functionality and improved performance. With the widespread adoption of AJAX developers are pushing our JavaScript skills to the limits. Even with this increased reliance on JavaScript running in the browser, there is still a need for server side application code. While the split in application logic has brought some improvements in our user experience, it has brought its own set of challenges as well. Having application code in two locations often requires us to pass values from the server side to our client-side JavaScript and for the JavaScript to be able to pass those values back to the server.
Jon Galloway
discussed this issue and provided a generic ASP.Net solution in Getting JavaScript and ASP.Net talking (outside of AJAX). Rick Strahl
followed this up with his own solutions in Embedding ASP.Net Server Variables in Client JavaScript Part 1 and Part 2. Both of these solutions work just fine for generic ASP.Net development. The downside to both of these techniques is that they require you to load one more component into your application or to dig into how to implement the necessary IScriptControl interface, which Jon points out “it's a little tough to set up”.
As a DotNetNuke developer we have another solution that is already built into the framework. Long before Microsoft announced Atlas, which subsequently became ASP.Net AJAX, Jon Henning
had added the ClientAPI framework to DotNetNuke. The ClientAPI was first added in 2004 and made it’s big debut in DotNetNuke 3.0, almost a full year before Microsoft announced Atlas..
One of the most basic functions of the ClientAPI was the ability to pass values back and forth between the client and server. On the server side, the ClientAPI provided an API for accessing the client variables and their values. On the client side, the ClientAPI provided a set of JavaScript functions for getting and setting the client variables which would then be passed back to the server on any subsequent postback – whether it was an AJAX postback or a regular page postback. In other words, the ClientAPI provided a solution to the problem Jon and Rick outlined in their blogs, and it provided a solution almost 4 years before Jon and Rick first wrote about the issue. Clearly Jon Henning is a bit of a forward thinker.
The ClientAPI includes several server side methods for working with Client Variables:
Public Shared Sub RegisterClientVariable(_
ByVal objPage As Page, _
ByVal strVar As String, _
ByVal strValue As String, _
ByVal blnOverwrite As Boolean)
Public Shared Function GetClientVariable(_
ByVal objPage As Page, _
ByVal strVar As String) As String
Public Shared Function GetClientVariable(_
ByVal objPage As Page, _
ByVal strVar As String, _
ByVal strDefaultValue As String) As String
There are a corresponding set of client side JavaScript functions:
getVar: function(sKey)
setVar: function(sKey, sVal)
I used this feature in DotNetNuke 4.9 and 5.0 for the updated Search skin object. The Search skin object includes the ability to use the native DotNetNuke search or to use Google to search the site. For each search type we wished to provide a pseudo dropdown list to allow the user to select the search type. Each search type includes a simple icon to designate the currently active search, similar to the UI for both IE and FireFox.
We use JavaScript to render the dropdown list and record the users selection. This information is then provided to the server when the user clicks the search button. You can see in the code below that we register the URLs for each of the icons and that we register the default dropdown value.
ClientAPI.RegisterClientVariable(_
Page, _
"SearchIconWebUrl",_
String.Format("url({0})", ResolveUrl(WebIconURL)), _
True)
ClientAPI.RegisterClientVariable(_
Page, _
"SearchIconSiteUrl", _
String.Format("url({0})", ResolveUrl(SiteIconURL)), _
True)
' We are going to use a dnn client variable to store which search option (web/site) is selected.
ClientAPI.RegisterClientVariable(_
Page, _
"SearchIconSelected", _
"S", _
True)
Those values will be stored in a hidden form field when the page is rendered. The great part about the API is that I don’t need to know anything about the hidden field. In my JavaScript I can easily read the values using the ClientAPI functions. The following JavaScript shows how I read the values to set the image for my selected search type:
// SearchIcon is the div that will display our currently selected search type
var searchIcon = $get('SearchIcon');
if (dnn.getVar('SearchIconSelected') == 'S')
{
searchIcon.style.backgroundImage=dnn.getVar('SearchIconSiteUrl');
}
else
{
searchIcon.style.backgroundImage=dnn.getVar('SearchIconWebUrl');
}
When the user changes their search type we can update the UI and save their choice for posting back to the server.
if (eventElement.target.id.indexOf("Web") > 0)
{
dnn.setVar('SearchIconSelected', 'W');
}
else
{
dnn.setVar('SearchIconSelected', 'S');
}
Once the user selects their search type, enters their search text and presses the submit button we can use server side code to retrieve the Client Variable value that tells us which search type to use:
ClientAPI.GetClientVariable(Page, "SearchIconSelected")
As you can see, the ClientAPI provides a nice simple answer to the problem that Jon and Rick discussed in their posts. The nice part of this solution is that it will work for any version of DotNetNuke that has been published in the last 4 years. You don’t need to add any additional components or implement any new interfaces since it is an integral part of the core. So if you haven’t already done so, I highly recommend that you explore the ClientAPI to see what other gems may be hidden inside. Who knows, I may even blog about a few of them.