May 2013

Volume 28 Number 05

Leading LightSwitch - Hello, Colors

By Jan Van der Haegen | May 2013

Ah, spring. The birds are singing, the bees are buzzing and trees are blossoming in numerous colors. It’s an excellent time of year to devote an episode of the second Leading LightSwitch season to putting some color in a mobile app. From complete branding to CSS tricks to JQuery Widgets, welcome to your one-stop-getting-started-with-colors-in-your-HTML-apps shop.

Novice: Getting Started

In my April “Hello, Mobile!” article, I introduced some of the enhanced LightSwitch features available in the second update to Visual Studio 2012. In this article, I’ll explain how to make your LightSwitch mobile application more visually appealing.

That means I’ll be skipping the long version of creating a new application with a single entity named MenuItemCategory that has a string property Name and a string property Color; adding a client; adding a new screen using the Browse Data screen; and selecting the list and binding the tap action to EditSelected, which will set you up to create a new screen using the Edit Details template. Some of you might notice that I just altered Program Manager Steve Lasker’s AmazingPie database to get some quick and free sample data.

If you’re absolutely new to LightSwitch and the preceding paragraph didn’t make sense to you, visit the LightSwitch development center. LightSwitch has an extremely shallow learning curve, so you’ll be back in no time to follow the rest of this article.

Apprentice: Branding and Theming

LightSwitch ships with two themes, as illustrated in Figure 1. The “light” theme is active by default but can be swapped out for the “dark” one by modifying a single line in the default.html Web page.

The light and dark LightSwitch themes
Figure 1 The light and dark LightSwitch themes

Or you can create your own using a CSS editor like the online JQuery theme roller (for mobile). The LightSwitch HTML applications are basically JavaScript SPAs (Single Page Applications) that use the Model-View-ViewModel (MVVM) design pattern. The team used an existing touch-optimized JavaScript library called JQuery Mobile to empower their View layer. Hence, anything that works for JQuery mobile in general works for LightSwitch mobile.

I won’t go over the roll-your-own option in this article because LightSwitch program manager Andy Kung already has an excellent post that provides a detailed step-by-step explanation of this process. After reading it, you’ll definitely agree that this kind of theming is a breeze—especially considering that you need to be an advanced developer to understand the documentation on how to create a custom shell for Silverlight.

Journeyman: Using the Screen Designer

Equally easy to learn yet extremely powerful and thus definitely worth mentioning is the LightSwitch screen designer. Figure 2 shows how a screen that was created using the Browse Data template initially looks in the screen designer and then when run.

A default Browse Data screen
Figure 2 A default Browse Data screen (screen editor on the left, real application on the right)

By default, a collection of entities such as Menu Item Categories is shown as a simple list. “Simple” is definitely a euphemism here because the list is completely virtualized and shows only the first couple of items while asynchronously loading the remaining ones, which appear as the user scrolls down. From a design perspective, a list is a simple vertical enumeration—but simple doesn’t have to mean visually uninteresting. Making lists more appealing in LightSwitch is really easy.

First, select the list you want in the screen designer and use the drop-down to select Tile View. Then select the first node under Tile List (Rows Layout) and press F4 to open the Properties window. Now change both the height and the width of each tile to a fixed size of 100. Notice how the properties by default allow you to “Adjust Tile width dynamically,” which is part of the LightSwitch strategy for responsive design: changing the user interface based on the size and orientation of the screen.

Next, select the Name node and from the Properties window set Text Alignment to Center. Simply showing the Name property is enough for now, so in the screen designer, select the second node that was automatically added, which represents the TextBlock control that would show the Color property, and remove it.

Finally, press Save in the screen designer and refresh your browser to see the result, which is shown in Figure 3.

Before and after a simple three-step operation in the screen designer
Figure 3 Before and after a simple three-step operation in the screen designer

List and Tile List are the two built-in options to visualize a collection. LightSwitch also has layout controls, supports tabs and popups, and depending on the type of a property, a number of other controls you can select in the screen designer. Furthermore, third- party vendors are quickly jumping on the LightSwitch train to provide additional design options.

Adept: Edit PostRender Code—What?

When the user navigates to a particular screen in the HTML application, the LightSwitch JavaScript framework dynamically creates the necessary HTML at run time. Technically, this means that the framework adds HTML objects to the Document Object Model (DOM) based on what the designer has specified in the screen designer. If you want to conjure some additional visual magic, you can select any control in the screen designer and from the Properties window click the Edit PostRender Code link. When you do, a JavaScript method stub is generated.

This method has two arguments, element and contentItem. Element is a reference to the HTML object the LightSwitch JavaScript framework just added to the DOM; contentItem is a JavaScript object that represents what you specified in the screen designer.

Adept: Edit PostRender Code—Static CSS

Getting back to the example, in the screen designer, select the TextBox control bound to the Name property, and in the Properties window, click the Edit PostRender Code link so that you can paste some JavaScript code. This line uses a JQuery selector around the element reference to add a CSS class named visuallyAppealingTileContent.

myapp.BrowseMenuItemCategories.Name_postRender = 
  function (element, contentItem) {
    $(element).addClass("visuallyAppealingTileContent");
};

From Solution Explorer, click the button that puts the project in File view to see all the subfolders. In the Content subfolder, you’ll find a cascading style sheet file named user-customization.css. In this file, define the visuallyAppealingTileContent CSS class that will turn the font of the text block white and horizontally center the content (by making the text block exactly the same height as the containing tile).

.visuallyAppealingTileContent
{
    color : white;
    line-height : 100px ;
}

Wait, what? White text on an already white background?

Adept: Edit PostRender Code—Simple Business Rules

You use white text because black text is less readable on a brightly colored background, which is what we’ll add next. To keep the article concise, let’s not imagine any complex business rules but instead just paint the background of each tile in the color that the user gave to the Color property of the MenuItemCategory. In a real application, working with visual meta-data such as background colors or font size greatly determines the effectiveness of the application. For example, you should use colors to provide contextual cues: make an occupied seat red, an open table green and an urgent message big and bold.

In the screen designer, select the Rows Layout control data-bound to MenuItemCategory and click the Edit PostRender Code link that generates the JavaScript method. Because the contentItem argument represents what you did in the screen designer, you can access the MenuItemCategory instance at run time by accessing the contentItem.value property.

You can access the color of the MenuItemCategory and assign it to the background of the HTML element using this code:

myapp.BrowseMenuItemCategories.RowTemplate_postRender = 
  function (element, contentItem) {
   $(element).css("background", contentItem.value.Color);
};

Click Save in the screen designer, and refresh your browser. You’ll see the color arrangement shown in Figure 4.

Colored tiles after applying some static and some dynamic CSS
Figure 4 Colored tiles after applying some static and some dynamic CSS

The tiles look great, but they appear to have a small gray border. This border exists because we’re styling the HTML element inside the HTML list-item instead of in the actual list-item element. To go up one level in the DOM and find the actual list-item, you can use the JQuery .parent() method:

myapp.BrowseMenuItemCategories.RowTemplate_postRender = 
  function (element, contentItem) {  
        $(element).parent('li').css("background", contentItem.value.Color);
};

Adept: Edit PostRender Code—Data Binding

Although the implementation works, it’s still incomplete. If the user clicks on one of the tiles, a screen in which the MenuItemCategory can be edited is opened. If the user alters the Color property of the MenuItemCategory and then saves, the detail screen will close and without any re-rendering the tile list will be shown again. Put another way, if the user clicks on a tile with a green background, a screen in which this MenuItemCategory can be edited is opened. If the user then changes the assigned color to red and saves the changes, that screen will close, but the tile will still be green.  

Technically speaking, this means that instead of setting the background just once, you need a way to detect when the Color property on the data model changes, even if this change was done in another screen, and bind the code that sets the background to that event.

Sounds like an easy mission, and thanks to an ingeniously simple API, it is:

myapp.BrowseMenuItemCategories.RowTemplate_postRender = 
  function (element, contentItem) {  
    contentItem.dataBind("value.Color", function () {
        $(element).css("background", contentItem.value.Color);
    });
};

Before moving on, here’s a simple “English recap” of this JavaScript method. In the BrowseMenuItemCategories screen in myapp, after LightSwitch renders the RowTemplate, take the actual MenuItemCategory from the contentItem and bind the Color property to some code that takes the HTML element and sets the background to the value of the MenuItemCategory’s color.

Once you understand the basic concepts, even adept level LightSwitchin’ isn’t all that hard.

Master: Edit Render Code—What?

In any LightSwitch control, you can click the Edit PostRender Code link to generate a JavaScript method stub, which will be executed right after the LightSwitch JavaScript framework adds the element to the DOM. If you want to add visual enhancements that are more intrusive, you can override the LightSwitch default behavior completely and add elements to the DOM as you see fit.

To do this, change your control in the screen designer to Custom Control, and from the Properties window, click the Edit Render Code link. A JavaScript method stub that is very similar to the PostRender method is generated, but the argument named element is a reference to the parent element (a placeholder) because LightSwitch hasn’t added any elements to the DOM itself.

Master: Edit Post Code—When?

Before finishing this article with an example, I want to mention one small detail that deserves a devoted paragraph: When is this render method called? Or, to rephrase the question, What happens after this method is called? Here’s what the documentation on the HTML client architecture says:

The concept of a “control” is not well defined in the HTML world. From the LightSwitch HTML client perspective, a control is implemented by a function that does two things: it adds elements to the browser DOM that represents the visualization of the control, and then it connects these elements to data through a data binding API. Once this is done, standard jQuery Mobile behavior takes over and expands the DOM into the actual set of elements to be displayed. The result may be significantly different from the original DOM if it referenced a jQuery Mobile control, or it may be left unchanged if the content is entirely custom elements.

To avoid confusion, bugs or visual glitches caused by the fact that “standard JQuery Mobile” behavior changes (expands) the elements you add in the render method or modify in the postRender method, LightSwitch developers often wrap some of their JavaScript code in a setTimeout function. The part that is wrapped is deferred until after standard JQuery Mobile behavior expands the elements.

Thanks to this setTimeout trick, the control-rendering flow goes like this: LightSwitch adds elements and the developer alters or adds elements using custom controls and the render method. JQuery Mobile then expands the DOM into a touch-optimized version. Any JavaScript code inside setTimeout functions is then executed.

This trick is particularly useful for interacting with the actual, final elements or for bypassing the JQuery mobile behavior completely, which is what we do in the next example.

Master: Edit PostRender—JQuery Widget

LightSwitch doesn’t have a color picker control, but you can use any third-party JavaScript library instead. I use an open source JQuery widget. The widget wasn’t written exclusively for mobile devices, which is why I add it using the setTimeout trick, which circumvents JQuery Mobile to alter the HTML input element that the widget interacts with.

To use this widget, download and add the required CSS and JS files to the LightSwitch project, and then link them from the default.html page so that they get loaded. Add a custom control in the screen designer, click the Edit Render Code link in the Properties window and paste in the code in Figure 5.

Figure 5 Adding a Color Picker control to the DOM

myapp.AddEditMenuItemCategory.Color1_render = 
  function (element, contentItem) {
    //setTimeout to bypass JQuery Mobile rendering of this element
    setTimeout(function () {
        //Add the control
        var colorPicker = $("<input id='cpFocus' value='" + 
          contentItem.value + "'  />");
        colorPicker.appendTo($(element));       
        colorPicker.colorpicker({ showOn: 'focus' })
            //Update the Model when the View changes
            //Read your widget's documentation
            .on('change.color', function (evt, color) {
                contentItem.value = color;
            });
        //Update the View when the Model changes
        //Standard LightSwitch API for databinding
        contentItem.dataBind("value", function () {
            colorPicker.colorpicker("val", contentItem.value);
        });
    }, 0);
};

Here’s what happens: In the AddEditMenuItemCategory screen in the application, after JQuery Mobile expands the DOM, an input element that the colorPicker widget renders is added. The color picker is notified when a new color is used so that the underlying MenuItemCategory can be updated. When the MenuItemCategory itself changes for any reason, the colorPicker shows the current Color.

Figure 6 shows the image that is rendered by the code in Figure 5.

Because a picture is worth a thousand words
Figure 6 Because a picture is worth a thousand words

Click Save and refresh your browser. When you click on a particular MenuItemCategory, the edit dialog box opens. There you use some JavaScript to render a custom JQuery widget under the default Color text box. When users clicks this control, they can select a new color. When changes are saved, the dialog box is closed and, thanks to the binding set up earlier (in the “Adept: Edit PostRender Code—Data Binding” section), the background of the tile is automatically updated.

In Conclusion

There’s nothing difficult about making your LightSwitch HTML application more colorful and visually appealing or simply easier to use. All you need is a good getting-started guide that explains the different techniques and a bit of practice. I hope this article can be that guide for you.


Jan Van der Haegen is a green geek who turns coffee into software. He’s a loving husband, .NET addict, LightSwitch lover, blogger, independent consultant and columnist for MSDN magazine online. He secretly dreams of becoming a professional goat herder one day.

Thanks to the following technical experts for reviewing this article: Beth Massi, Heinrich Wendel and Joe Binder.