You are here:   Blog
Register   |  Login

 

Oct 26

Written by: Michael Washington
10/26/2014 7:48 AM  RssIcon

image

You can quickly and easily create AngularJS applications using Wijmo 5 controls and Visual Studio LightSwitch as your back-end OData source.

image

Records can be inserted.

image

Business rules are enforced.

image

Records can be updated.

image

Records can be deleted by simply clicking on a row and then clicking the delete button on your keyboard.

image

Clicking on column headers provides sorting.

image

Concurrency (provided by the LightSwitch back-end) is also enforced.

The Wijmo 5 Controls

image

Wijmo 5 is available at http://wijmo.com/products/wijmo-5/ and provides a full set of HTML 5 JavaScript controls. They ship and maintain AngularJS directives for all of the controls. 

Why would you want to use AngularJS and Wijmo 5 with LightSwitch?

  1. You need 100% control over the UI – The one disadvantage the LightSwitch HTML Client has is its dependence on JQuery Mobile. This is fine in most cases but you would have a hard time matching a pixel by pixel design specification using it.
  2. You need to implement security – Security must be implemented on the server-side. You cannot implement security inside AngularJS because it is a client-side technology. LightSwitch makes security easy as we will demonstrate in this example.
  3. You need Concurrency – When a user attempts to update a record that has been updated by another user or process since the user last retrieved the record, concurrency alerts the user. When LightSwitch is used as the back-end data source you get this feature automatically.
  4. You want to use LightSwitch for the Administration screens – There is no need to code all the screens in your application in AngularJS. As this example will demonstrate, you can mix AngularJS and LightSwitch screens in the same application.
  5. You want to build a OData service layer for use with other applications – LightSwitch is the easiest and most robust way to create an OData service.
  6. You want to speed up development – There is a lot less code to implement when you use LightSwitch as your back-end. This means faster development and fewer bugs.

The Example

image

We start with the code from Allow LightSwitch Users To Self-Register and Change Passwords Using MVC because it demonstrates how you can handle user registration and authentication in a pure MVC application (however the AngularJS page will be a normal .html page).

However, the code sample will work exactly the same in a normal non-MVC LightSwitch application.

The LightSwitch Business Layer

image

In the Server project, right-click on the Data Sources folder and select Add Table.

image

Create the ToDo table.

image

In the Write Code menu, select the Validate method.

Use the following code for the method:

 

        partial void ToDoes_Validate(ToDo entity, EntitySetValidationResultsBuilder results)
        {
            // Do not allow a task to be called {New Task]
            if (entity.TaskName == "[New Task]")
            {
                results.AddEntityError(
                    "Task cannot be named [New Task]"
                    );
            }
            // Do not allow more than 1 incomplete Task
            if (entity.IsComplete == false)
            {
                int intCountOfIncomplete =
                    this.DataWorkspace.ApplicationData.ToDoes
                    .Where(x => x.IsComplete == false)
                    .Where(x => x.Id != entity.Id).Count();
                if (intCountOfIncomplete > 0)
                {
                    results.AddEntityError(
                        "Cannot have more than 1 incomplete Task"
                        );
                }
            }
        }

 

Set-up The Wijmo Code

image

Download the trial Wijmo 5 sample from: http://wijmo.com/products/wijmo-5/

image

Unzip the Wijmo sample, locate the project at “..\Samples\JS\Angular\OData” and copy the vendor and styles directories to the scripts folder in the LightSwitch server project.

image

Create a wijmo.data directory in the LightSwitch server project, and download the ODataCollectionView.js file from the .zip file at: http://silverlight.adefwebserver.com/files/LightSwitch/ODataCollectionView_10262014.zip and place it in the directory.

Note: The ODataCollectionView class extends the CollectionView class in Wijmo to connect to OData services. The ODataCollectionView class loads data from LightSwitch OData service. When the user modifies the view, changes are automatically applied to the LightSwitch table.

Create The AngularJS Code

image

Create a app.js file in the scripts folder and use the following code:

 

// Tell AngularJS that your app depends on the Wijmo "wj" module:
var app = angular.module('app', ['wj']);

 

image

Create a controllers directory in the scripts folder.

Create a appCtrl.js controller file in the folder and use the following code:

 

'use strict';
var app = angular.module('app');
app.controller('appToDoCtrl', function appToDoCtrl($scope) {
    // define data service URL and data types for specific columns
    var oDataService = '/ApplicationData.svc', dataTypes = [];
    // load ToDos table
    $scope.cvToDo = new wijmo.data.ODataCollectionView(
        { serviceUrl: oDataService, entityName: 'ToDoes' },
        ['Id'],
        {
            serverSettings: {
                selects: ['Id', 'RowVersion', 'TaskName',
                    'IsComplete', 'Created', 'Modified']
            }
        },
        dataTypes, loaded, true);
    // Display any errors
    $scope.cvToDo.error.addHandler(function (sender, args) {
        alert(sender.errorMsg);
    });
    // tell scope when tables finish loading
    function loaded() {
        $scope.$apply();
    }
});

 

Create The HTML Page

image

Create a page called ToDo.htm

Use the following code for the file (this just references the required JavaScript and .css files and sets up the ng-app (app.js) and ng-controller (appCtrl.js) for the page):

 

<!DOCTYPE html>
<html lang="en" ng-app="app" ng-controller="appToDoCtrl">
<head>
    <meta charset="utf-8" />
    <title>To DO</title>
    <!-- ensure IE uses the latest version of IE (yes, yes...) -->
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!-- jQuery/Angular/Bootstrap -->
    <script src="http://code.jquery.com/jquery-2.0.0.min.js" 
            type="text/javascript"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js" 
            type="text/javascript"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular-route.min.js" 
            type="text/javascript"></script>
    <script src="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js" 
            type="text/javascript"></script>
    <link rel="stylesheet" href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" 
          type="text/css" />
    <!-- Wijmo -->
    <script src="scripts/vendor/wijmo.min.js" type="text/javascript"></script>
    <script src="scripts/vendor/wijmo.input.min.js" type="text/javascript"></script>
    <script src="scripts/vendor/wijmo.grid.min.js" type="text/javascript"></script>
    <link href="styles/vendor/wijmo.min.css" rel="stylesheet" />
    <!-- app scripts -->
    <script src="scripts/wijmo.data/ODataCollectionView.js" type="text/javascript"></script>
    <script src="scripts/app.js" type="text/javascript"></script>
    <script src="scripts/controllers/appCtrl.js" type="text/javascript"></script>
    <!-- Wijmo-Angular interop -->
    <script src="scripts/vendor/wijmo.angular.min.js" type="text/javascript"></script>
    <!-- app styles -->
    <link href="styles/app.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <div class="header">
        <div class="container" style="position:relative">
            <h1>
                TO DO Example
            </h1>
        </div>
    </div>
</body>
</html>

 

Finally we add the code (to the <body> section) to display the Wijmo grid:

 

    <div class="container">
        <wj-flex-grid class="grid" 
                      allow-add-new="true" 
                      allow-delete="true" 
                      items-source="cvToDo">
            <wj-flex-grid-column 
                                 binding="TaskName" 
                                 width="300" 
                                 header="Task Name">
            </wj-flex-grid-column>
            <wj-flex-grid-column 
                                 binding="IsComplete" 
                                 datatype="Boolean" 
                                 width="200" 
                                 header="IsComplete">
            </wj-flex-grid-column>
        </wj-flex-grid>
    </div>

 

Special Thanks

This article would not be possible without assistance and code from Dale Morrison (@dale_mohttp://blog.ofanitguy.com) and Bernardo Castilho.

Links

Wijmo.com

CollectionView 101

Wijmo 5 and OData

Download Code

The LightSwitch project is available at http://lightswitchhelpwebsite.com/Downloads.aspx

(you must have Visual Studio 2013 (or higher) to run the code)

4 comment(s) so far...


Gravatar

Re: Using AngularJS Wijmo Grid With LightSwitch OData

Thank you Michael, most informative

By Bhuven on   10/27/2014 6:45 AM
Gravatar

Re: Using AngularJS Wijmo Grid With LightSwitch OData

@Bhuven - Thank you I hope you find it useful :)

By Michael Washington on   10/27/2014 7:35 AM
Gravatar

Re: Using AngularJS Wijmo Grid With LightSwitch OData

This is a nice technique and handy to extend the Wijmo oData connector to handle LightSwitch oData. Down-side might be if you wanted to use other 3rd party directives in your app as well... then maybe breeze would be a better option? BIG QUESTION: can the Wijmo oData grid handle data in related tables? This was a big shortcoming of the ComponentOne grid in my view...

Great series of posts, btw - tour de force!

Cheers,
Bruce

By Bruce on   10/30/2014 3:29 PM
Gravatar

Re: Using AngularJS Wijmo Grid With LightSwitch OData

@Bruce - The Wijmo grid can handle related tables, please see their site for an example. As far as using other 3rd party directives in your app, they may also handle that, I don't know, so make a post in the Wijmo forum, thanks!

By Michael Washington on   10/30/2014 3:30 PM
Microsoft Visual Studio is a registered trademark of Microsoft Corporation / LightSwitch is a registered trademark of Microsoft Corporation