Vista Gadgets Part 2 – Script, Settings and Events Too!

by David 6/12/2008 2:33:00 PM

In Part 1 we made the simplest gadget one can imagine to demonstrate the basic moving parts.  In Part 2, we’re going to keep things simple and build on the code from Part 1 to demonstrate how to introduce some script and settings.

When it comes to functionality you’re going to deliver that using JavaScript, what’s more you get access to a gadget API (again via JavaScript) that gives you access to a multitude of functionality and system properties such as file, network and OS information – it’s the ability to build on top of this API that gives most gadgets purpose.

To demonstrate how to incorporate JavaScript and settings, we’re going to create a settings fly out that allows the end user to specify what message to display, lets start by writing the code that get’s our message displayed dynamically.

  1. Open Windows Explorer and browse to: C:\Users\ [User] \AppData\Local\Microsoft\Windows Sidebar\Gadgets\jacksTest.gadget that we created in Part 1

  2. Open jacksTest.html and add an empty DIV within the <body></body> tags:

    <body>
        <div id="messageDiv"></div>
    </body>

     
    This gives us a container to target, in which we can place our message.

  3. Create a directory called scripts.

  4. In the new directory, create a file called jacksTest.js

  5. Add the following content:

    function OnInit()
    {
        messageDiv.innerHTML = "Coolio";
    }

     
    This is basic JavaScript, but notice we can refer to our DIV without needing to use the document.getElementById() function.

  6. Return to jacksTest.html and add a reference to our script file within the <head></head> tags:

    <script type="text/javascript" language="javascript" src="scripts/jacksTest.js"></script>

  7. Now hook-up the OnInit() event handler to the onload event in the <body> tag:

    <body onload="OnInit()">

    Save everything and try re-adding the gadget, all being well it should now say “Coolio” instead of “Hey Jack!” – this being the case our message is now being set via code.  Eventually we'll be able to pull the value from a setting, so let’s move onto creating our settings fly out.

  8. At the same level as jacksTest.html, create a new file called jacksTestSettings.html – this is the UI host for the settings panel.

    This is going to follow the same pattern as jacksTest.html with it’s own style sheet and JavaScript file, with that in mind we can go ahead and put in the references to these files, which we’ll create in a minute and hook-up the onload event.

    <html>
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=Unicode" />
            <link type="text/css" rel="stylesheet" href="css/jacksTestSettings.css" />
            <script type="text/javascript" language="javascript" src="scripts/jacksTestSettings.js"></script>
        </head>
        <body onload="OnInit()">
            Message:<br />
            <input type="text" id="messageTextBox" />
        </body>
    </html>


  9. Create a file called jacksTestSettings.css in the css directory with the following content:

    body
    {
        width: 300px;
        height: 80px;
    }

    #messageTextBox
    {
        width: 200px;
    }

     
  10. Create a file called jacksTestSettings.js in the scripts directory with the following boilerplate code:

    function OnInit()
    {
    }


    We now have all our components, we just need to tell our gadget which file to use for the settings panel.  It would seem logical that this went in the manifest, but it doesn’t.  Instead you have to assign it to a static property in the API when your gadget loads.

  11. Open jacksTest.js and add the following line to the top of the OnInit() event handler:

    System.Gadget.settingsUI = "jacksTestSettings.html";

    Save everything and try re-adding the gadget.  Hover the mouse over the gadget and you should now get a spanner icon underneath the close x; click the spanner and the settings panel we just created will fly out.



    Typing something into the message text box doesn’t accomplish anything at this point, we need to write the code that will persist values entered in this box and also retrieve them to display in the main gadget.

  12. Gadget settings are basic name/value pairs written/read via the gadget API.  They are always stored and returned as strings.

    Return to jacksTestSettings.js in your editor.
    The gadget API exposes an onSettingsClosing event which we can hook an event handler up to.  In this event handler we can manage the saving of any alterations to the settings.

    In the OnInit() event handler, add the following line:

    System.Gadget.onSettingsClosing = SettingsClosing;

  13. Now let’s create the SettingsClosing event handler, add the following function bellow the OnInit() handler:

    function SettingsClosing(event)
    {
        if (event.closeAction == event.Action.commit)
        {
            System.Gadget.Settings.writeString("message", messageTextBox.value);
        }

        event.cancel = false
    }


    This code will take care of storing the value entered in our textbox if the user presses OK.

  14. Return to jacksTest.js where we’ll handle retrieving the settings value and display it in our gadget.  We need to handle two events to accomplish this; the initial load, which we’re already doing with the code in the OnInit() event handler, albeit hard-coded at the moment.  Secondly a new event triggered when the settings fly-out closes where we can pick up any setting changes.  Essentially these two events will be doing the same thing, pulling a stored setting value and displaying it, so we’ll refactor our jacksTest.js code to look like the following:

    function OnInit()
    {
        System.Gadget.settingsUI = "jacksTestSettings.html";
        System.Gadget.onSettingsClosed = DisplayContent;
       
        DisplayContent();
    }

    function DisplayContent()
    {
        messageDiv.innerHTML = System.Gadget.Settings.readString("message");
    }


    We’ve created a DisplayContent() function which we hooked-up to the onSettingsClosed event and also call within OnInit.  Within DisplayContent() we’re retrieving the “message” settings value via the gadget API.

    At this point you can now control what message is displayed in the gadget via the settings fly-out.

  15. You will notice that when you bring up the settings fly-out, you still get an empty textbox rather than the current message being displayed.  To tidy this up simply return to jacksTestSettings.js and add the following line to the bottom of the OnInit() event handler:

    messageTextBox.value = System.Gadget.Settings.readString("message");

Whilst we still have a fairly useless and if we’re honest, a far from great looking gadget, we have covered 3 fundamental steps in developing gadgets; the introduction of script, hooking up to events in the gadget API and the use of settings.

There are few other titbits of information to take note of too:

  • Unlike the main gadget, if you’re working on files within the AppData folder you don’t need to re-add the gadget to the sidebar to test changes to your settings UI.
  • All settings are stored as strings, in fact they’re stored as plain text in the following file: C:\Users\ [User] \AppData\Local\Microsoft\Windows Sidebar\Settings.ini
    If you add our test gadget, add a display message of “Test”, then open the above ini file and scroll to the bottom you should see message=”Test” at the bottom of the file.
  • Naming – we’ve kept our naming convention so jacksTest.html, jacksTest.css and now jacksTest.js all clearly relate to each other.
  • Folder structure – we’re keeping things tidy by creating a scripts directory for all out script files.

You can download the files for this example here:  jacksTest Gadget Part 2.zip (3.27 kb)

In Part 3 we'll either look at making our gadget look more respectable or refactor reading/writing settings values into an abstracted SettingsManager JavaScript object. 

IETester - Multiple versions of IE in one place

by David 6/10/2008 11:32:00 AM

Testing your site in the various different flavours of browser is by far one of the most tedious and hit or miss experiences every web developer will face.  This is probably truer of IE than most.  The only real way to test properly is to have multiple machines (or VMs) with original installs of each version.

For quick testing as you develop however, wouldn’t it be great if you had a desktop app that emulated all the different versions?  Well this is what IETester claims to do.  I’ll admit that I’ve not tested it a lot, but a quick browse through some sites that I know have IE 5.5 issues seems to suggest it’s doing it’s job.  IETester claims to emulate not only the rendering engines of IE8 beta 1, IE7, IE6 and IE5.5 but also their JavaScript engines.  It’s currently only in Alpha but if they manage to pull of what they’re claiming this is a killer web dev tool.

On a similar theme another impressive, but slightly less useful testing tool can be found in http://browsershots.org/ - given a URL it will produce screenshots of the site on a dizzying number of browser versions and platforms.  There’s no emulation here, but rather a network of physical machines each installed with a different browser version.  Whilst impressive, it has drawbacks; you only get a screenshot of one page in your site, that page has to be public and it can take a while to process.  It’s still a cool project though.

Powered by BlogEngine.NET 1.3.0.0
Theme by Mads Kristensen