Click here to Skip to main content
15,498,570 members
Articles / Web Development / ASP.NET
Article
Posted 25 Sep 2014

Stats

68.4K views
1.6K downloads
33 bookmarked

Create a Responsive HTML Table using FooTable and Apply Client Side Binding using Handlebars.Js

Rate me:
Please Sign up or sign in to vote.
4.50/5 (21 votes)
25 Sep 2014CPOL6 min read
In this article, we are going to create responsive HTML table using FooTable Plug-In and a hint of client side data binding using Handlebars.js library.

Idea

Our main idea is to eliminate server side grid controls and its associated view state using html table elements and improve the page performance. Also, we are going to add responsive behavior to our table to fit in all devices.

Summary

In this article, we are going to create responsive HTML Table using FooTable Plug-in and update the client side binding logic using Handlebars.js templating library. This is an extension to the project created using article Create an ASP.NET Web Forms Application using Bootstrap and Web API.

Process

  1. Create HTML table and bind the data retrieved using Web API
  2. Add responsive behavior to HTML table using FooTable plug-in
  3. Update client side data binding logic with Handlebars.js library

A) Create HTML Table and Bind the Data Retrieved using Web API

First and foremost, we need to create a Model folder to the existing project where we can have our “Member” entity.

Image 1

Go ahead and create a new Member.cs class with all required properties.

C#
public class Member
{
   public int MemberId { get; set; }
   public string FirstName { get; set; }
   public string MiddleName { get; set; }
   public string LastName { get; set; }
   public string EmailId { get; set; }
   public string NickName { get; set; }
   public int Age { get; set; }
   public string IsActive { get; set; }
   public DateTime CreatedDate { get; set; }
   public string Company { get; set; }
}

Next, we are going to create a Repository.cs class to fetch predefined list of members.

Note: Replace the Model and Repository with your existing business logic entities and data access.

C#
public class Repository
{
   public List<Member> GetMembers()
   {
      return new List<Member> {
         new Member
         {
            MemberId = 1, FirstName = "Jeffrey", MiddleName = "Preston", 
            LastName = "Jorgensen", EmailId = "abc1@xyz.com",NickName = "Jeff Bezos", 
            Age=50, IsActive = "Active", CreatedDate = new DateTime(2014,9,9), Company ="Amazon"
         },
         new Member
         {
            MemberId = 2, FirstName = "Satyanarayana", MiddleName = "", 
            LastName = "Nadella", EmailId = "abc2@xyz.com",NickName = "Satya Nadella", 
            Age = 46,IsActive = "Active", CreatedDate = new DateTime(2014,9,9), Company="Microsoft"
         },
         new Member
         {
            MemberId = 3, FirstName = "Adele", MiddleName = "Laurie Blue", 
            LastName = "Adkins", EmailId = "abc3@xyz.com",NickName = "Adele", 
            Age = 26,IsActive = "Active", CreatedDate = new DateTime(2014,9,9), Company="Singer"
         },
         new Member
         {
            MemberId = 4, FirstName = "David" ,MiddleName = "Robert Joseph",
            LastName = "Beckham", EmailId = "abc4@xyz.com",NickName = "Beckham", 
            Age = 39,IsActive = "Inactive", CreatedDate = new DateTime(2014,9,9), Company="Soccer Player"
         }
      };
   }  
}

Now, we need to create a Controller to access data related to member. Select an Empty Web API 2 Controller with the name MemberController.cs to our controller folder and add an action method GetMembers to list all members.

C#
public class MemberController : ApiController
{
   Repository _repository = new Repository();

   [HttpGet]
   [ActionName("GetMembers")]
   public string GetMembers()
   {
      List<Member> members = _repository.GetMembers();
      return JsonConvert.SerializeObject(members);
   }
}

Note: Get appropriate references to Model and Newtosoft Json within the Controller class.

Now, our solution looks like this:

Image 2

Build and run the application to check if we can access member controller at the URL.

http://localhost:2469/api/Member/GetMembers

Image 3

Alright, now we can see list of members in JSON format. Go ahead and create a new Content Page MemberList.aspx to the existing Master page to display the list of members in table format.

Image 4

Note: We have three <div> elements in the content page. First <div> to hold the page header, second <div> to hold the actual table (gvMembers) with data and the last a hidden <div> (BodyStructure) to hold the row structure.

We have a table with thead section with all required column headers and tbody section with a warning message “No records found!”. To view the page, set the new content page as start up page and run the application.

Image 5

Next, we will add our JavaScript logic within the page ScriptSection to fetch data from our API.

Good Practice: Place all your logically related script within JavaScript Container not to leak JavaScript variables as global variables into the page. Container is similar to a C# class where we encapsulate members. This is what our Container looks like:

Image 6

Note: As you can see from the success callback/promise method getMembersSuccess, we are looping through the data to clone the row structure and assign values to each column. And finally appending the new row to the table tbody section.

We are going to add our Service API link to the WebConfig appSettings so that it can be accessed from client side.

HTML
<appSettings>
   <add key="ApiPath" value="http://localhost:2469/api/"/>
</appSettings>

Also, add an IIFE (Immediately Invoked Function Expression) JavaScript statement to fetch data as soon as page loads.

JavaScript
$(function () {
   MembersList.getMembers();
})();

(or) you can also use jQuery ready method.

JavaScript
$(document).ready(function () {
   MembersList.getMembers();
});

Now, our ScriptSection looks like this:

Image 7

Build and run the application to view the page:

Image 8

As you can see, this is just a normal HTML table with no formatting and doesn’t fit well over various devices. Particularly, when looking in small devices like mobile and tablets.

Image 9

B) Add Responsive Behavior to HTML Table using FooTable Plug-In

FooTable plug-in is a jQuery plugin that aims to make HTML tables on smaller devices look awesome - No matter how many columns of data you may have in them. As per the instructions, lets add required .css, .js and font files to our solution and it will look like this:

Image 10

Now, we need to add style and script references to our content page. Footable Core Footable.core.css in the StyleSection, footable.js in the ScriptSection and wrap the table element with footable method in the ContentSection.

Image 11

Build and run the updated code to check if the HTML table is responsive or not. Surprisingly, it isn't.

Image 12

Why because, we have not taken advantage of the FooTable Break Points. Break Point is the predefined device width configured at FooTable to fix the table in mobile and tablet layouts. So we will add necessary data attributes to the table thead section.

HTML
<thead>
   <tr>
      <th data-toggle="true">Member Id</th>
      <th data-hide="phone" >First Name</th>
      <th data-hide="tablet,phone">Middle Name</th>
      <th data-hide="phone">Last Name</th>
      <th data-hide="tablet,phone">Email Id</th>
      <th>Nickname</th>
      <th data-hide="tablet,phone">Age</th>
      <th data-hide="tablet,phone">Status</th>
      <th data-hide="tablet,phone">Created On</th>
      <th>Company</th>
      <th data-hide="tablet,phone">Action</th>
   </tr>
</thead>

Note: Data-hide is used to hide columns off break-point limits. Data-toggle is used to show expand & collapse when in responsive mode.

Run the application again and check the table in Desktop, Tablet and Mobile layouts.

Tablet View

Image 13

Mobile View

Image 14

C) Update Client Side Data Binding Logic with Handlebars.js Library

Handlebars.js is a templating library effectively used to simplify data binding logic at client side. It is largely compatible with Mustache templates.

If you notice the success callback getMembersSuccess method, we are doing typical jQuery operations to fetch HTML table, parse the response and loop through the data to clone the dummy row and append it to the table body section.

This is absolutely fine doing this way. But there is an optimal way to bind the template using client side data binding technique with libraries such as Mistache, HandlebarsJs, Closures, UnderscoreJs, etc. In this article, we are focusing on Handlebarsjs.

To use Handlebarjs, we will create a new content page MemberListTemplate.aspx with the same content as we have in MembersList.aspx. As we are using handlebar template, go ahead and remove the div BodyStructure.

Next, we need to add Handlebarsjs JavaScript library to our project. You can either use NuGet Package Manager to search and download “Handlebars.js” or go to their website and download latest Version 2.0.0.

Image 15

Add reference to the js file in ScriptSection just below the FooTable.js. Now, we will place our HTML template with in JavaScript which is of type “text/x-handlebars-template”. We can also use “text/html” apart from any other JavaScript type here. The idea here is that the browser should not parse the template as regular JavaScript block.

HTML
<script id="template1" type="text/x-handlebars-template">
   {{#each members}}
   <tr>
      <td>{{MemberId}}</td>
      <td>{{FirstName}}</td>
      <td>{{MiddleName}}</td>
      <td>{{LastName}}</td>
      <td>{{EmailId}}</td>
      <td>{{NickName}}</td>
      <td>{{Age}}</td>
      <td>{{IsActive}}</td>
      <td>{{CreatedDate}}</td>
      <td>{{Company}}</td>
      <td></td>
   </tr>
   {{/each}}
</script>

Note: The template will loop through members using #each handler to fetch appropriate items for binding.

Now, we will update our getMembersSuccess callback with the code given below:

JavaScript
getMembersSuccess: function (response) {
   var data = $.parseJSON(response);
   var table = $("#gvMembers");
   // Remove tbody within the table
   table.find("tbody").html("");
   // Get The Template HTML from the source
   var template = $("#template1").html();
   // Compile it
   var compiledCode = Handlebars.compile(template);
   // Then, process compiled code using data as an input
   var dynamicCode = compiledCode(data);
   // Assign the output to placeholder
   table.find("tbody").append(dynamicCode);
   $('#gvMembers').trigger('footable_redraw');
}

Warning: Compiling your handlebarsjs template is often a time consuming process and will affect performance if it huge and or nested within. There is a way to precompile your templates beforehand to save run time.

If you look at the code, we are accessing the template (#template) using jQuery selector. Then compile the HTML using Handlebar compile method (which will convert HTML in a JavaScript method). Later, we process the compiledCode with the data as parameter and append the same to the table tbody element.

To view the changes, make the new content page MemberListTemplate.aspx as start up, build and run the application.

Image 16

There are several ways to make HTML table responsive. However, I feel FooTable has done wonders in this area. It has several other features to Sorting, Filtering, and apply Theme along with Pagination.

There are several features included in Handlebarsjs with which you can do more complex operations. You can extend its behavior using adding Escaping, Expressions, Helpers and custom handlers, etc.

Check this article to Create Asp.Net Web Forms Application using Bootstrap and Web API

Click here to learn more about Whats New in ASP.NET 5 and C# 6

Check this article to start implementing basics on AngularJs and Implementing it in ASP.NET MVC with CRUD operations

Hope you had something new to learn from this article. Let me know if you have any suggestions or improvements.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionNice Article Pin
Ashish shri1-Dec-14 23:15
MemberAshish shri1-Dec-14 23:15 
AnswerRe: Nice Article Pin
Sreekanth Mothukuru2-Dec-14 3:03
MemberSreekanth Mothukuru2-Dec-14 3:03 
GeneralAbout article Pin
DINESHKUMAR E R26-Sep-14 8:01
professionalDINESHKUMAR E R26-Sep-14 8:01 
GeneralRe: About article Pin
Sreekanth Mothukuru26-Sep-14 20:10
MemberSreekanth Mothukuru26-Sep-14 20:10 
GeneralMy vote of 4 Pin
Lisa Shiphrah25-Sep-14 5:29
MemberLisa Shiphrah25-Sep-14 5:29 
GeneralRe: My vote of 4 Pin
Sreekanth Mothukuru25-Sep-14 20:45
MemberSreekanth Mothukuru25-Sep-14 20:45 
QuestionNo source code & no images... Pin
Dewey25-Sep-14 2:22
MemberDewey25-Sep-14 2:22 
AnswerRe: No source code & no images... Pin
Sreekanth Mothukuru25-Sep-14 2:25
MemberSreekanth Mothukuru25-Sep-14 2:25 
GeneralRe: No source code & no images... Pin
Dewey25-Sep-14 2:28
MemberDewey25-Sep-14 2:28 
GeneralRe: No source code & no images... Pin
Sreekanth Mothukuru25-Sep-14 2:31
MemberSreekanth Mothukuru25-Sep-14 2:31 
GeneralRe: No source code & no images... Pin
Dewey25-Sep-14 2:43
MemberDewey25-Sep-14 2:43 
Questionwhere are images Pin
sheikh zeeshan25-Sep-14 1:51
Membersheikh zeeshan25-Sep-14 1:51 
AnswerRe: where are images Pin
Sreekanth Mothukuru25-Sep-14 2:22
MemberSreekanth Mothukuru25-Sep-14 2:22 
QuestionImages are not loading. Pin
Karthik Harve25-Sep-14 1:24
professionalKarthik Harve25-Sep-14 1:24 
AnswerRe: Images are not loading. Pin
Sreekanth Mothukuru25-Sep-14 2:24
MemberSreekanth Mothukuru25-Sep-14 2:24 
AnswerRe: Images are not loading. Pin
Karthik Harve25-Sep-14 3:03
professionalKarthik Harve25-Sep-14 3:03 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.