Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / XML

Developing Gadgets Using ASP.NET AJAX Extensions

4.48/5 (12 votes)
16 Aug 20073 min read 1   888  
How to develop sidebar gadgets using a base class developed with ASP.NET AJAX Extensions
Screenshot - a_gadget.jpg

Introduction

What you will get from this article:

  • An overview of developing gadgets using a base class with built in support for displaying loaded, loading, and connection error states

What you will not get from this article:

  • An introduction to gadget development
  • An introduction to ASP.NET AJAX Extensions

Background

Most gadgets that deal with remote data have three basic states: loading, loaded, and connection error. For the sake of simplicity I have intentionally ignored docked and undocked states.

Screenshot - a_states.gif

When I set out to develop my first gadget, I was unhappy with how much code I needed to write to support displaying states. The code I had written seemed messy and more functional than object oriented. To solve this problem I created a base class that provides support for rendering display modes and encapsulates some of the basic gadget API.

Using the Code

Creating the HTML for your Gadget

Be sure to reference the MicrosoftAjax.js and Dowds.Gadgets.js files first in your gadget's HTML file.

ASP.NET
<head>
    <script type="text/javascript" src="Scripts/MicrosoftAjax.debug.js">
    </script>
    <script type="text/javascript" src="Scripts/Dowds.Gadgets.js">
    </script>
    <script type="text/javascript" 
        src="Scripts/##You_Gadgets_Javasctipt_File##.js"></script>
</head>

Instead of dynamically generating the HTML for each state the Dowds.Gadgets.Gadget class takes a simpler approach. It expects the gadget HTML file to have a DIV element for each state. They must have the following ids:

  • dataLoadedDisplay, for the div to show when the data is successfully loaded
  • dataLoadingDisplay, for the div to show while the data is loading
  • dataNotAvailableDisplay, for the div to show when there is a connection error

Each DIV should be absolutely positioned and have its CSS visibility set to hidden.

ASP.NET
<body>
    <div id="dataLoadedDisplay" style="position:absolute;visibility:hidden">
        <table id="movieListings">
            <tr><td class="percent"></td><td class="title"><div><a></a></div>
        </td></tr>
            ...
        </table>
    </div>
    <div id="dataLoadingDisplay" style="position:absolute;visibility:hidden">
        <img src="Images/Icon_Spinner.gif" /> Getting Data…
    </div>
    <div id="dataNotAvailableDisplay" 
        style="position:absolute;visibility:hidden">
        <img src="Images/Icon_Info.png" /> Service Not Available
    </div>
</body>

Creating the JavaScript for Your Gadget

Create a new class using ASP.NET AJAX Extensions. Use the registerClass method to make it inherit from Dowds.Gadget.Gadget

JavaScript
Dowds.Gadgets.Movies = function()
{
    Dowds.Gadgets.Movies.initializeBase(this);
    this._data = null;
};
Dowds.Gadgets.Movies.registerClass("Dowds.Gadgets.Movies", 
                        Dowds.Gadgets.Gadget);

Accessing remote data such as an XML file or a web service can easily be accomplished using the Sys.Net.WebRequest class provided by ASP.NET AJAX Extensions.

JavaScript
Dowds.Gadgets.Movies.prototype =
{
    _requestData: function()
    {
        // Use ASP.NET Extensions to access the remote XML or web service
        var wRequest = new Sys.Net.WebRequest();
        wRequest.set_url
        ("http://i.rottentomatoes.com/syndication/rss/top_movies.xml");
        wRequest.add_completed(Function.createDelegate
                    (this, this._processData));
        wRequest.invoke();
    }
}

Once the data is returned you'll need to call the _updateDisplay method of the Dowds.Gadgets.Gadget class. It does almost all the work to update the gadgets state. It updates the display based on the values of the _dataNotAvailable and _dataLoaded flags.

_dataNotAvailable _dataLoadedDIV Displayed
truetruedataNotAvailableDisplay
truefalsedataNotAvailableDisplay
falsetruedataLoadedDisplay
falsefalsedataLoadingDisplay

Before calling the _updateDisplay method be sure to update the _dataNotAvailable and _dataLoaded flags based on the success of your request.

JavaScript
Dowds.Gadgets.Movies.prototype =
{
    ...
    _processData: function(executor)
    {
        if (executor.get_responseAvailable())
        {     // The data returned
            var movieDoc = executor.get_xml();
            this._dataLoaded = true;
            this._dataNotAvailable = false;
            this._data = Dowds.Gadgets.MovieInfo.ParseFromDoc(movieDoc);
            // Update the display HTML for the loaded state
            this._bindTable(this._data);
        }
        else
        {    // There was an error connecting to the data
            this._dataLoaded = false;
            this._dataNotAvailable = true;
        }
        // Refresh the data in 4 hours
        setTimeout(Function.createDelegate(this, this._requestData), 
                            (4 * 3600000));
        this._updateDisplay();
    }
}

The _updateDisplay method should be called whenever the state flags change. You'll also need to add custom logic to update the UI with the data that is returned. In the example above I call _bindTable(this.data) to update the table in the dataLoadedDisplay DIV with the movie review data that was returned.

Opening a Flyout

If you open a flyout that is already open it loses focus and becomes grayed out. To avoid this, check and see if the flyout is already open and if it is, just refresh the data.

JavaScript
_link_onclick: function(e)
{
    ...
    if(System.Gadget.Flyout.show)
    {
        this._updateFlyout();
    }
    else
    {
        System.Gadget.Flyout.show = true;
    }
    ...
},
_updateFlyout: function()
{
    var flyoutWindow = System.Gadget.Flyout.document.parentWindow;
    flyoutWindow.moviesFlyout.reload(this._selectedMovieInfo);
}

Final Thoughts

It's very important that you avoid making your gadget look like something a developer designed. Try thinking of an object or metaphor you could use to visually represent your gadget. For example, I created a movie review gadget so a clap board is a fitting backdrop.

Additional Resources

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here