Tuesday, May 22, 2012

Single Page Application packages and samples

Single Page Application packages and samples:
This post is for you if you saw my ASP.NET Single Page Applications presentation at recent conferences and would like to try out the code for yourself.

Getting the post-beta tools update, and running the scaffolder

First, make sure you have ASP.NET MVC 4 Beta. Then if you want to scaffold up a simple data-editing SPA,
  • Create a new MVC 4 project. Choose the Single Page Application subtemplate.
  • Once you’ve created the new project, pop open NuGet package console (View > Other Windows > Package Manager Console), and install the latest scaffolder templates as folllows:

Install-Package SinglePageApplication.CSharp

Or, if you’re using Visual Basic instead of C#, install the VB package instead:

Install-Package SinglePageApplication.VisualBasic

Don’t skip this step, otherwise you’ll be using the old beta SPA templates and the result will be much less interesting.
Note that Visual Studio may give a false compiler error (“The type or namespace name ‘MvcTextTemplateHost’ could not be found”) – you can either just ignore it, or restart Visual Studio to make it go away. This is an unfortunate limitation of the way we’re packaging this post-beta update, and won’t affect the final tooling.
  • Now you can follow the on-screen instructions in /Models/TodoItem.cs to scaffold a simple data-editing SPA. Use the Add Controller dialog as explained in the comments on that file, remembering to build the solution first, and then you can run the app and browse to http://localhost:whateverport/Tasks.
image
If you want to learn what the point of all this is, see http://www.asp.net/single-page-application or watch this presentation.

Getting the DeliveryTracker sample

If you want to see a slightly bigger and more fun app built with the same libraries and architecture, you can get hold of the DeliveryTracker app that I built during the SPA presentation. If you want to see the mobile UI, you’ll want to either use a real mobile to view it, or fake your useragent (instructions for IE or Chrome or Firefox).
image
Note that the source on GitHub doesn’t include the offline support, as that’s still very early in development – the design and functionality is still likely to change significantly.

Metro: Creating a Master/Detail View with a WinJS ListView Control

Metro: Creating a Master/Detail View with a WinJS ListView Control:
The goal of this blog entry is to explain how you can create a simple master/detail view by using the WinJS ListView and Template controls. In particular, I explain how you can use a ListView control to display a list of movies and how you can use a Template control to display the details of the selected movie.

clip_image002

Creating a master/detail view requires completing the following four steps:
  1. Create the data source – The data source contains the list of movies.

  2. Declare the ListView control – The ListView control displays the entire list of movies. It is the master part of the master/detail view.

  3. Declare the Details Template control – The Details Template control displays the details for the selected movie. It is the details part of the master/detail view.

  4. Handle the selectionchanged event – You handle the selectionchanged event to display the details for a movie when a new movie is selected.

Creating the Data Source

There is nothing special about our data source. We initialize a WinJS.Binding.List object to represent a list of movies:

(function () {
    "use strict";

    var movies = new WinJS.Binding.List([
        { title: "Star Wars", director: "Lucas"},
        { title: "Shrek", director: "Adamson" },
        { title: "Star Trek", director: "Abrams" },
        { title: "Spiderman", director: "Raimi" },
        { title: "Memento", director: "Nolan" },
        { title: "Minority Report", director: "Spielberg" }
    ]);

    // Expose the data source
    WinJS.Namespace.define("ListViewDemos", {
        movies: movies
    });

})();
The data source is exposed to the rest of our application with the name ListViewDemos.movies.

Declaring the ListView Control

The ListView control is declared with the following markup:

<div id="movieList"
    data-win-control="WinJS.UI.ListView"
    data-win-options="{
        itemDataSource: ListViewDemos.movies.dataSource,
        itemTemplate: select('#masterItemTemplate'),
        tapBehavior: 'directSelect',
        selectionMode: 'single',
        layout: { type: WinJS.UI.ListLayout }
    }">
</div>
The data-win-options attribute is used to set the following properties of the ListView control:
  • itemDataSource – The ListView is bound to the list of movies which we created in the previous section. Notice that the ListView is bound to ListViewDemos.movies.dataSource and not just ListViewDemos.movies.
  • itemTemplate – The item template contains the template used for rendering each item in the ListView. The markup for this template is included below.
  • tabBehavior – This enumeration determines what happens when you tap or click on an item in the ListView. The possible values are directSelect, toggleSelect, invokeOnly, none. Because we want to handle the selectionchanged event, we set tapBehavior to the value directSelect.
  • selectionMode – This enumeration determines whether you can select multiple items or only a single item. The possible values are none, single, multi. In the code above, this property is set to the value single.
  • layout – You can use ListLayout or GridLayout with a ListView. If you want to display a vertical ListView, then you should select ListLayout.
You must associate a ListView with an item template if you want to render anything interesting. The ListView above is associated with an item template named #masterItemTemplate. Here’s the markup for the masterItemTemplate:

<div id="masterItemTemplate" data-win-control="WinJS.Binding.Template">
    <div class="movie">
        <span data-win-bind="innerText:title"></span>
    </div>
</div>
This template simply renders the title of each movie.

Declaring the Details Template Control

The details part of the master/detail view is created with the help of a Template control. Here’s the markup used to declare the Details Template control:

<div id="detailsTemplate" data-win-control="WinJS.Binding.Template">
    <div>
        <div>
            Title:
            <span data-win-bind="innerText:title"></span>
        </div>
        <div>
            Director:
            <span data-win-bind="innerText:director"></span>
        </div>
    </div>
</div>
The Details Template control displays the movie title and director.
 image

Handling the selectionchanged Event

The ListView control can raise two types of events: the iteminvoked and selectionchanged events. The iteminvoked event is raised when you click on a ListView item. The selectionchanged event is raised when one or more ListView items are selected.
When you set the tapBehavior property of the ListView control to the value “directSelect” then tapping or clicking a list item raised both the iteminvoked and selectionchanged event. Tapping a list item causes the item to be selected and the item appears with a checkmark.
In our code, we handle the selectionchanged event to update the movie details Template when you select a new movie.
Here’s the code from the default.js file used to handle the selectionchanged event:

var movieList = document.getElementById("movieList");
var detailsTemplate = document.getElementById("detailsTemplate");
var movieDetails = document.getElementById("movieDetails");

// Setup selectionchanged handler
movieList.winControl.addEventListener("selectionchanged", function (evt) {
    if (movieList.winControl.selection.count() > 0) {
        movieList.winControl.selection.getItems().then(function (items) {
            // Clear the template container
            movieDetails.innerHTML = "";
            // Render the template
            detailsTemplate.winControl.render(items[0].data, movieDetails);
        });
    }
});
The code above sets up an event handler (listener) for the selectionchanged event. The event handler first verifies that an item has been selected in the ListView (selection.count() > 0). Next, the details for the movie are rendered using the movie details Template (we created this Template in the previous section).

The Complete Code

For the sake of completeness, I’ve included the complete code for the master/detail view below. I’ve included both the default.html, default.js, and movies.js files.
Here is the final code for the default.html file:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>ListViewMasterDetail</title>

    <!-- WinJS references -->
    <link href="//Microsoft.WinJS.0.6/css/ui-dark.css" rel="stylesheet">
    <script src="//Microsoft.WinJS.0.6/js/base.js"></script>
    <script src="//Microsoft.WinJS.0.6/js/ui.js"></script>

    <!-- ListViewMasterDetail references -->
    <link href="/css/default.css" rel="stylesheet">
    <script src="/js/default.js"></script>
    <script type="text/javascript" src="js/movies.js"></script>

    <style type="text/css">

        body {
            font-size:  xx-large;
        }

        .movie {
            padding: 5px;
        }

        #masterDetail {
            display: -ms-box;
        }

        #movieList {
            width:  300px;
            margin:  20px;
        }

        #movieDetails {
            margin:  20px;
        }

    </style>

</head>
<body>
    <!-- Templates -->
    <div id="masterItemTemplate" data-win-control="WinJS.Binding.Template">
        <div class="movie">
            <span data-win-bind="innerText:title"></span>
        </div>
    </div>

    <div id="detailsTemplate" data-win-control="WinJS.Binding.Template">
        <div>
            <div>
                Title:
                <span data-win-bind="innerText:title"></span>
            </div>
            <div>
                Director:
                <span data-win-bind="innerText:director"></span>
            </div>
        </div>
    </div>

    <!-- Master/Detail -->
    <div id="masterDetail">
        <!-- Master -->
        <div id="movieList"
            data-win-control="WinJS.UI.ListView"
            data-win-options="{
                itemDataSource: ListViewDemos.movies.dataSource,
                itemTemplate: select('#masterItemTemplate'),
                tapBehavior: 'directSelect',
                selectionMode: 'single',
                layout: { type: WinJS.UI.ListLayout }
            }">
        </div>

        <!-- Detail -->
        <div id="movieDetails"></div>
    </div>

</body>
</html>
Here is the default.js file:

(function () {
    "use strict";

    var app = WinJS.Application;

    app.onactivated = function (eventObject) {
        if (eventObject.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {
            WinJS.UI.processAll();

            var movieList = document.getElementById("movieList");
            var detailsTemplate = document.getElementById("detailsTemplate");
            var movieDetails = document.getElementById("movieDetails");

            // Setup selectionchanged handler
            movieList.winControl.addEventListener("selectionchanged", function (evt) {
                if (movieList.winControl.selection.count() > 0) {
                    movieList.winControl.selection.getItems().then(function (items) {
                        // Clear the template container
                        movieDetails.innerHTML = "";
                        // Render the template
                        detailsTemplate.winControl.render(items[0].data, movieDetails);
                    });
                }
            });

        }
    };

    app.start();
})();


Here is the movies.js file:

(function () {
    "use strict";

    var movies = new WinJS.Binding.List([
        { title: "Star Wars", director: "Lucas"},
        { title: "Shrek", director: "Adamson" },
        { title: "Star Trek", director: "Abrams" },
        { title: "Spiderman", director: "Raimi" },
        { title: "Memento", director: "Nolan" },
        { title: "Minority Report", director: "Spielberg" }
    ]);

    // Expose the data source
    WinJS.Namespace.define("ListViewDemos", {
        movies: movies
    });

})();



Summary

The purpose of this blog entry was to describe how to create a simple master/detail view by taking advantage of the WinJS ListView control. We handled the selectionchanged event of the ListView control to display movie details when you select a movie in the ListView.

Could not find a part of the path ... bin\roslyn\csc.exe

I am trying to run an ASP.NET MVC (model-view-controller) project retrieved from TFS (Team Foundation Server) source control. I have added a...