Kendo UI Grid and AngularJS: Formatting and Filtering JSON Dates and other tricks

I want to go over some more advanced Kendo UI Grid settings when using Angular and when receiving a list of records in a JSON format.  For some examples of setting up a simpler/basic Kendo Grid with Angular.js check out this blog post.

One of the best things about the Kendo UI Grid is how customization it is.  But with great flexibility comes some complication.  I’ve found it easiest to split my angular grid variables into 2 separate pieces:

  • The Kendo Data Source
  • The Kendo Grid Options

The HTML

<div kendo-grid k-options="kendoGridOptions" k-data-source="kendoGridDataSource"></div>

Defining the Kendo Data Source

Add the following to your angular controller.  You will see that we are dealing with an array of JSON objects.  By default, the JSON object is treating each field as a string and so we will need to tell the data source which fields to define as numbers and dates.

//Set up grid data source and schema
$scope.kendoGridDataSource = new kendo.data.DataSource({
    data: jsonArrayHere,
    pageSize: 15,
    schema: {
        model: {
            fields: {
                Created_Date: {
                    type: "date",
                    parse: function (data) { if (data == null) return null; return new Date(data); }
                },
                Start_Date: {
                    type: "date",
                    parse: function (data) { if (data == null) return null; return new Date(data); }
                }
                Project_Count: { type: "number" },
                Record_ID: { type: "number" }
                }
              }
            }
});
 

Defining the Kendo Grid Options

//Set up grid options and properties
                   $scope.kendoGridOptions = {
                       toolbar: ["excel", "pdf"],
                       excel: {
                           fileName: "ExampleA.xlsx",
                           allPages: true,
                       },
                       pdf: {
                           fileName: "ExampleB.pdf",
                           allPages: true,
                       },
                       sortable: true,
                       groupable: true,
                       selectable: true,
                       resizable: true,
                       columnMenu: true,
                       pageable: {
                           pageSizes: [15, 25, 50, 100, 500]
                       },
                       filterable: {
                           extra: false,
                           operators: {
                               date: {
                                   gt: 'After',
                                   lt: 'Before',
                                   eq: 'Equal to'
                               },
                               string: {
                                   contains: "Contains",
                                   startswith: "Starts with",
                                   eq: "Is equal to",
                                   neq: "Is not equal to"
                               }
                           }
                       },
                       columns: [
                       { field: "Record_Name", title: "Name", template: "<a href=\"../team/details/#: Record_ID #\">#: Record_Name #</a>" },
                       { field: "Created_Date", title: "Date Created", template: "#if(Created_Date != null) {# <div>#= kendo.toString(kendo.parseDate(Created_Date), 'MM/dd/yyyy') #</div>#} #" },
                       { field: "Start_Date", title: "Date Started", template: "#if(Start_Date != null) {# <div>#= kendo.toString(kendo.parseDate(Start_Date), 'MM/dd/yyyy') #</div> #} #" },
                       { field: "LookupField", title: "Lookup Filter Example", filterable: { multi: true } },
                       { field: "Project_Count", title: "Count" },
                       { field: "Record_ID", title: "ID", hidden: true },
                       { field: "Hidden_Field", title: "Hidden Example", hidden: true }
                       ]
                   };

What did we just do?

4.PNG

Capture.PNG

 

toolbar: [“excel”,”pdf”]: Here I am adding two buttons to the top of the grid. One to export the grid data as a excel spreadsheet and the other as a PDF. Just below the “toolbar:” property I am setting the file name and page properties of each export.

columnMenu: true  – I like to have all of the search, sort, and filter actions tucked away inside a drop-down for every column.  To do this set the “columnMenu” property.

filterable: {}  – I only want to show a few filter options depending on the field type.  It is within here that I set those filter operators.

column links  –  To have text in a column show up in the grid as a link, check out the “Record_Name” template above.  This example displays the name, but creates a link based upon its “Record_ID”.

column dates  –  Check out the templates of “Created_Date” and “Start_Date” to see how to format dates javascript dates to ‘MM/dd/yyyy’.  You’ll notice that I have to first check for a null date value and then convert it into a string otherwise the grid would display unwanted date information.

columns [{filterable: { multi: true }}]  – This enables filtering via a checkbox list in the grid filter menu.  Pretty cool stuff.  More information and example of this.

columns [{hidden: true}]  –  Hide the column by default, but list it in the column menu dropdown so that the user can choose to add it to the data grid.

Creating your first AngularJS – ASP.NET Core 1.0 application

This post will work off a project I created in a previous post – Creating Your First ASP.NET Core 1.0 Application from Scratch – and it will get you set up with AngularJS, Grunt, and Bower.

Add an NPM Configuration File and install Grunt and Bower

1. Right click the project and select Add > New Item. Select NPM Configuration File and name it package.json

2. Open up package.json and add the following 4 dependencies

{
    "version": "1.0.0",
    "name": "ASP.NET",
    "private": true,
  "devDependencies": {
    "grunt": "0.4.5",
    "grunt-contrib-uglify": "0.11.0",
    "grunt-contrib-watch": "0.6.1",
    "bower": "1.7.2"
  }
}

What did we just do?

In our package.json file, we’ve indicated that we need three NPM packages named grunt, grunt-contrib-uglify, and grunt-contrib-watch. After the name of each package, we’ve specified the version of the package that we need.  Grunt and Bower are now installed in our project!

 

Add a Grunt Configuration File

1. Right click the project and select Add > New Item. Select Grunt Configuration File and name it gruntfile.js

What is Grunt?

Grunt is an open-source tool that you can use to build all of the frontend resources for your project. For example, you can use Grunt to compile your Less or Sass files into CSS. You can also use Grunt to combine and minify CSS and JavaScript files.

2.  Open up gruntfile.js and load your plugins by adding the following.

grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');

3. Next add your configurations to the grunt file

grunt.initConfig({
    uglify: {
        my_target: {
            files: {
                'wwwroot/app.js': ['Scripts/app.js', 'Scripts/**/*.js']
            }
        }
    },
    watch: {
        scripts: {
            files: ['Scripts/**/*.js'],
            tasks: ['uglify']
        }
    }
});
grunt.registerTask('default', ['uglify', 'watch']);

4. Your gruntfile.js should now look like this

gruntfile.PNG

What did we just do?

We told Grunt to look for a javascript file named app.js and then, on build, we want it to minify (uglify) the app.js file and put it into our wwwroot  (we will create the app.js file later in this tutorial).

Add JQuery and Bootstrap to our project using Bower

What is Bower?

Bower is a package manager created by Twitter that is designed to support front-end development. You can use Bower to manage resources such as AngularJS, jQuery, and Bootstrap.

1. Right click the project and select Add > New Item. Select Bower Configuration File and name it bower.json

2. Open up bower.json and add JQuery and Bootstrap to its dependencies

{
    "name": "ASP.NET",
    "private": true,
  "dependencies": {
    "jquery": "2.2.0",
    "bootstrap": "3.3.6"
  }
}

3. Your bower.json file and projectfolder structure should now look like this:

bower.PNG

 

Wow, now we have Nuget, NPM, and Bower package managers in our project.  Why do we need all of them and what do they do?  Check out my blog post about that here – Nuget vs NPM vs Bower.

 

Installing AngularJS

1. Open up bower.json and add these AngularJS modules to its dependencies. For this project we will just be using the “angular package”, but I wanted to show here that “angular-resource” and “angular-route” are added in the same way.

{
  "name": "ASP.NET",
  "private": true,
  "dependencies": {
    "jquery": "2.2.0",
    "bootstrap": "3.3.6",
    "angular": "1.4.8",
    "angular-resource": "1.4.8",
    "angular-route": "1.4.8"
  }
}

2. Save and compile the project and you will see that the above modules were added to you wwwroot folder and your Bower folder.  Should look like this:

angularinstall.PNG

 

Add Scripts

1. Right click the project and select Add > New Folder.  Name it “Scripts”.

2. Right click the Scripts folder and select Add > New Item…  Select JavaScript File and name is app.js

3.  This is the same app.js file that we look for in our gruntfile.js code a few steps above.  The next thing we will do is initialize the angular application.  To do this, add the following to app.js

var app = angular.module("myApp", []);

4. To have Grunt uglify app.js and add it to our wwwroot folter, do the following. Open up Visual Studio’s Task Runner Explorer (View > Other Windows > Task Runner Explorer)

5. Refresh the Task Runner Explorer.  You should see your Gruntfile.js there.  Drill down into Alias Tasks. Right click and run default.  This will minify (uglify) your app.js file and add it to your wwwroot.

rungrunt.PNG

Use static files

1. You want to tell your app to use static files like app.js and the other angular and bootstrap files. To do this open up Startup.cs and add this to the Configure(IApplicationBuilder app) method.

app.UseStaticFiles();

2. The method Configure(IApplicationBuilder app) should now look like this:

staru.PNG

Writing some AngularJS!

1. Open up Views/Home/Index.cshtml

2. Replace what is in Index.cshtml with the following

<!DOCTYPE html>
<html ng-app="myApp">
<head>
    <meta name="viewport" content="width =device-width" />
    <title>AngularJS and ASP.NET 5 Example</title>
    
    @*add styles here*@
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
</head>
<body>
    <h2>Hello Home Index Page</h2>
    Name : <input type="text" ng-model="name">
    
    Hello {{name}}
    
    @*add javascript files here*@
    <script src="~/lib/angular/angular.js"></script>
    <script src="~/app.js"></script>
</body>
</html>

What did we just do?

In the above html we are loading Bootstrap, JQuery, AngularJS, and app.js.  We are then adding ng-app=”myApp” to the HTML tag. The ng-app directive defines an AngularJS application and its module is created in app.js.  If these angular terms are unfamiliar to you, please check out  http://www.w3schools.com/angular/angular_intro.asp for a more detailed explanation of the Angular code seen here.

Finished!

You now have a working ASP.NET Core 1 AngularJS Application.

Check it out on GitHub
https://github.com/JesseAH/JesseDotNet-ASPNET5WebApp