You are here:   Blog
Register   |  Login

 

Dec 18

Written by: Michael Washington
12/18/2016 9:17 PM  RssIcon

You can implement an advanced Angular 2 data grid using the Wijmo FlexGrid control. In this example, we will use the control to implement a simple data grid that allows users to add, edit, and delete Products. The code required will be significantly less than the code required to implement the exact same functionality in previous articles.

The Wijmo FlexGrid control is part of a suite of Angular 2 controls that cost money. However, you get what you pay for, and what you get is quality software and personal support.

In this tutorial we will walk through using the free trial version that you can download at this link.

image

First, make sure you have all the software indicated in the following article:

Hello World! in Angular 2 using Visual Studio 2015 and ASP.NET 4

For this tutorial, we will start with the code created in the tutorial: Tutorial: Creating An Angular 2 CRUD Application Using MVC 5 and OData 4.

Download the code for this article, from the downloads page on this site, and unzip it into a directory.

Install Wijmo

image

First, we need to install Wijmo.

To install Wijmo, download the free Wijmo trial version at this link, and unzip it.

Copy the directory at:

..\Wijmo-Enterprise-Eval.{version number}\C1Wijmo-Enterprise-Eval_.{version number}\NpmImages\wijmo-system-min

image

Paste it into the same directory that you put the source code for: Tutorial: Creating An Angular 2 CRUD Application Using MVC 5 and OData 4 (paste it into the same directory that the Angualr2QuickStart.sln file is in).

image

Double-click on the Angualr2QuickStart.sln file to open the project in Visual Studio 2015 (or higher).

(Note: you can download the free Visual Studio 2015 Community Edition from: https://www.visualstudio.com/downloads/download-visual-studio-vs)

image

Add the following line to the top of the dependencies section of the package.json file:

 

"wijmo": "../wijmo-system-min",

 

image

Save the file, then right-click on the package.json file and select Restore Packages.

image

When you look in the file manager (outside of Visual Studio), and navigate to:

..\Angular2QuickStart_Wijmo\Angular2QuickStart\node_modules

You will see that Wijmo has been installed.

image

Next, open the systemjs.config.js file and add the following lines to the map section:

 

      // WIJMO
      'wijmo': 'npm:wijmo',

 

Add the following lines to the packages section:

 

      ,
      wijmo: {
          defaultExtension: 'js'
      }

 

Save the file.

image

Copy the file from:

…\Wijmo-Enterprise-Eval.{version number}\C1Wijmo-Enterprise-Eval_.{version number}\Dist\styles\wijmo.min.css

 

image

Paste it into the Visual Studio project in the Content directory.

image

Add the following lines to the file at Views/Shared/_Layout.cshtml:

 

    <!-- Wijmo -->
    <link href="~/Content/wijmo.min.css" rel="stylesheet" />

 

Create The Angular 2 Code

image

We need to register the Wijmo components with the application.

Add the following import statements to the app.module.ts file:

 

// ** WIJMO **
import { WjGridModule } from 'wijmo/wijmo.angular2.grid';
import { WjInputModule } from 'wijmo/wijmo.angular2.input';

 

Add the following import references to the imports section of the module:

 

// ** WIJMO **
WjInputModule, WjGridModule,

 

image

Open the product.component.html file, and replace all the code with the following code:

 

<!-- Error (if any) -->
<div class='panel panel-danger' *ngIf="errorMessage">
    <alert type="info">{{ errorMessage }}</alert>
</div>
<button class='btn btn-danger'
        (click)="saveData()"
        *ngIf='showProductList'>
    Save Data
</button><br /><br />
<div *ngIf='showProductList && products'>
    <wj-flex-grid class="grid"
                  #flex
                  [selectionMode]="'Row'"
                  [itemsSource]="flexGridData"
                  [allowAddNew]="true"
                  [allowDelete]="true">
    </wj-flex-grid>
    <br /><br />
</div><br />

 

This creates a div to display any potential errors, a button to save any data and a declaration for a Wijmo FlexGrid control that will be bound to data assigned to a property called flexGridData.

 

image

Open the product.component.ts file and replace all the code with the following code:

 

import {
    Component, OnInit, OnDestroy, Input, Output,
    ViewContainerRef, EventEmitter, ViewChild, trigger
} from '@angular/core';
import {
    Router, ActivatedRoute
} from '@angular/router';
import {
    Subscription
} from 'rxjs/Subscription';
import {
    IProduct
} from './product';
import {
    ProductService
} from './product.service';
import {
    IUser
} from '../user/user';
import {
    UserService
} from '../user/user.service';
import {
    ModalDirective
} from 'ng2-bootstrap/ng2-bootstrap';
// WIJMO
import { WjGridModule } from 'wijmo/wijmo.angular2.grid';
import { WjInputModule } from 'wijmo/wijmo.angular2.input';
import * as wjcCore from 'wijmo/wijmo';
import * as wjcGrid from 'wijmo/wijmo.grid';
@Component({
    moduleId: module.id,
    selector: 'product-form',
    templateUrl: 'product.component.html'
})
export class ProductComponent implements OnInit {
    // ** WIJMO **
    flexGridData: wjcCore.CollectionView;
    @ViewChild('flex') flex: wjcGrid.FlexGrid;
    // The current User
    user: IUser;
    // The list of Products
    products: IProduct[];
    // Any error messages
    errorMessage: string;
    // Controls if the Product list is to be shown
    showProductList: boolean = false;
    // Constructor is called when the class is created
    constructor(
        private _productService: ProductService,
        private _userService: UserService) {
        // Set ProductList to be hidden
        // Only show is user is logged in
        this.showProductList = false;
    }
}

 

This sets up the base for the code page and registers the Wijmo components.

Now add the following method to the ProductComponent class:

 

    // Handle data related tasks in ngOnInit
    ngOnInit() {
        // Call the Current User method
        this.getCurrentUser();
    }

 

This will be called after the class is instantiated but before any other method.

In it, we are calling the getCurrentUser() method.

Paste the following code to implement that method:

 

    getCurrentUser() {
        // Call the getCurrentUser service
        this._userService.getCurrentUser().subscribe(
            user => {
                // Assign the user
                this.user = user;
                // See if we are logged in and have a user
                if (this.user.UserName != "[Not Logged in]") {
                    // Get the Products
                    this.getProducts();
                }
            },
            error => this.errorMessage = <any>error);
    }

 

Here we are calling the _userService.getCurrentUser() service to determine if the user is logged in, and if they are, to get their UserName.

If they are logged in, the getProducts() method will be called.

Paste the following code in to implement that method:

 

    // ** Calls the service to retrieve all the Products **
    getProducts() {
        // Call the service
        this._productService.getProducts()
            .subscribe((products) => {
                // Set the products collection to the 
                // Products returned
                this.products = products;
                // ** WIJMO **
                // Set the source for flexGridData
                // flexGridData is the data the Wijmo FlexGrid is bound to
                // Any further updates to the data 
                // will be made to 'this.flexGridData'
                this.flexGridData = new wjcCore.CollectionView(this.products);
                this.flexGridData.trackChanges = true;
                // Handle if there are no Products
                if (this.products.length == 0) {
                    // If there are no Products, create one
                    let newProduct: IProduct = {
                        Id: 0,
                        ProductName: 'Product One',
                        ProductPrice: '100.00',
                    }
                    // Add Product to the Grid
                    this.products.push(newProduct);
                    // Save the new Product
                    this.insertProduct(newProduct);
                }
            },
            error => this.errorMessage = <any>error);
        // Show the Products list
        this.showProductList = true;
    }

 

Here we are calling the _productService.getProducts() service to get the Products.

We set the Products returned to the this.Products property then set that property to the source of the CollectionView that this.flexGridData is bound to.

The FlexGrid control is bound to this.flexGridData.

Notice that .trackChanges is set to true.

This means that the FlexGrid will automatically keep track of all changes to the FlexGrid. We only need to retrieve the changes when we are ready to save the data.

image

At this point the Products will display on the Grid with a blank row at the bottom to add a new Product.

image

When the Save button is pressed, the following method is invoked, paste the code in now:

 

    // *** Called when the Save button is pressed ***
    saveData() {
        // Insert Product(s)
        if (this.flexGridData.itemsAdded.length > 0) {
            for (var i = 0; i < this.flexGridData.itemsAdded.length; i++) {
                var ProductToInsert: IProduct = this.flexGridData.itemsAdded[i];
                this.insertProduct(ProductToInsert);
            }
        };
        // Update Product(s)
        if (this.flexGridData.itemsEdited.length > 0) {
            for (var i = 0; i < this.flexGridData.itemsEdited.length; i++) {
                var ProductToUpdate: IProduct = this.flexGridData.itemsEdited[i];
                this.updateProduct(ProductToUpdate);
            }
        };
        // Delete Product(s)
        if (this.flexGridData.itemsRemoved.length > 0) {
            for (var i = 0; i < this.flexGridData.itemsRemoved.length; i++) {
                var ProductToDelete: IProduct = this.flexGridData.itemsRemoved[i];
                this.deleteProduct(ProductToDelete);
            }
        };
        // Reset the change tracking 
        this.flexGridData.clearChanges();
        // Notify of Save
        alert('Saved');
    }

 

This method loops through the tracked changes and calls the appropriate method to insert, update, or delete the data.

Finally, paste the following code in to implement the methods:

 

    // ** Add a Product **
    insertProduct(paramProduct: IProduct) {
        // Call the service to Insert the Product
        this._productService.createProduct(paramProduct)
            .subscribe((createdProduct) => {
                // Set ProductId
                // We need the ProductId
                // in case a further edit is needed
                paramProduct.Id = createdProduct.Id;
                this.flexGridData.editItem(paramProduct);
                this.flexGridData.endUpdate();
            },
            error => this.errorMessage = <any>error);
    }
    // ** Update a Product **
    updateProduct(paramProduct: IProduct) {
        // Call the service to update the Product
        this._productService.updateProduct(paramProduct)
            .subscribe(() => { },
            error => this.errorMessage = <any>error);
    }
    // ** Delete a Product **
    deleteProduct(paramProduct: IProduct) {
        // Call the service to delete the Product
        this._productService.deleteProduct(paramProduct.Id)
            .subscribe(() => { },
            error => this.errorMessage = <any>error);
    }

 

image

The image above shows the flow of the change tracking.

Wijmo FlexGrid Links:

Getting Started with Wijmo FlexGrid using Angular 2 (Video)
https://vimeo.com/159534284

The First Complete Collection of Angular 2 Components
http://wijmo.com/angular2/

Setup of Wijmo Angular 2 Components
http://wijmo.com/5/docs/static/angular2Components.html

FlexGrid 101
http://demos.wijmo.com/5/Angular2/FlexGridIntro/FlexGridIntro/

CollectionView 101
http://demos.wijmo.com/5/Angular/CollectionViewIntro/CollectionViewIntro/

Angular 2 Tutorial Series

  1. Hello World! in Angular 2 using Visual Studio 2015 and ASP.NET 4
  2. Implement ASP.NET 4 MVC Application Security in Angular 2 Using OData 4
  3. Tutorial: Creating An Angular 2 CRUD Application Using MVC 5 and OData 4
  4. Tutorial: An End-To-End Angular 2 Application Using MVC 5 and OData 4

Resources to Learn Angular 2

Angular 2: Getting Started (Pluralsight – Paid)

Introduction to Angular 2.0 (Microsoft Virtual Academy – Free)

Getting Started with npm in Visual Studio

Using EcmaScript 2015 Modules in TypeScript with SystemJS

Download

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

You must have Visual Studio 2015 Update 3 (or higher) and TypeScript 2.0 (or higher) installed to run the code.

Microsoft Visual Studio is a registered trademark of Microsoft Corporation / LightSwitch is a registered trademark of Microsoft Corporation