Showing posts with label JSON. Show all posts
Showing posts with label JSON. Show all posts

Tuesday, 24 February 2015

CRUD & Validation in Knockout Grid

In this article we will see how to create a dynamic grid using knockout js and how to add a row wise validation by using knockout validation. We also look how add, insert and delete a row in a grid.

What we will achieve at final:

1)      Dynamically adding and inserting a row in grid and also deletion of row from grid.

2)      Validation by using Knockout Validation api.

3)      Generating  json of records.

Our final output should be something like below:

1)      If you click on Insert, it will add new record above the selected row likewise excels.

2)      If you click on Add New Row, it will add new row at the bottom of the grid.

3)      Now when you press Save it will validate all the row and notify by highlighting the border of the controls and if all the data validation is success it will generate json for you.

Now follow me step by step to achieve the above output:

1)      Reference the following script files:

a)      Jquery

b)      Knockoutjs

c)       Knockout validation

d)      Bootstrap (optional)

 

    <script src="Scripts/jquery-2.1.3.min.js" type="text/javascript"></script>

    <script src="Scripts/knockout-3.2.0.js" type="text/javascript"></script>

    <script src="Scripts/knockout.validation.min.js" type="text/javascript"></script>

    <link href="Content/bootstrap.min.css" rel="stylesheet" type="text/css" />

 

2)      Add this style part for highlighting the border of controls in case of validation failed:

<style>

            .required-field

            {

                border:2px solid red;

            }

    </style>

 

3)      Now create a script file or script section in a page and replace the script with the below given script:

<script>

 

        $(function () {

            var vm = function () {

 

                var self = this;

 

                // contains the list of row

                self.list = ko.observableArray();

 

                // for identifying the current added or inserted row

                self.current = ko.observable();

 

                // contains the list of countries

                self.countries = ko.observableArray([{

                        id: 1,

                        name: "India"

                    },{

                        id: 2,

                        name: "Australlia"

                    }

                ]);

 

                // contains the list of states

                self.states = ko.observableArray([{

                        id: 1,

                        countryid: 1,

                        name: "Uttar Pradesh"

                    },{

                        id: 2,

                        countryid: 1,

                        name: "Delhi"

                    },{

                        id: 3,

                        countryid: 2,

                        name: "Sydney"

                    },{

                        id: 4,

                        countryid: 2,

                        name: "Melbourne"

                    }

                ]);

 

                // will set when error need to show

                self.showErrors = ko.observable(false);

 

                // function for adding a new row in a table

                self.addRow = function(order) {

                   

                    var obj = {

                        Order: ko.observable(order),

                        FirstName:  ko.observable().extend({ required: true }),

                        LastName: ko.observable().extend({ required: true }),

                        Country: ko.observable().extend({ required: true }),

                        State: ko.observable().extend({ required: true }),

                        ContactNo: ko.observable().extend({ required: true }),

                        Designation: ko.observable().extend({ required: true }),

                        Countries: self.countries()

                    };

 

                    // return list of errors from an object

                    obj.errors = ko.validation.group(obj);

 

                    // display an error for each fields of an object

                    obj.showerror = function (item) {

                       

                        if (!item.isValid() && obj.showErrors()) {

                            return true;

                        }

                        else {

                            return false;

                        }

                    };

 

                    // computed function return filtered stated on the basis of country choosen

                    obj.States = ko.computed(function() {

 

                        if(obj.Country()) {

                           

                           var list = ko.utils.arrayFilter(self.states(), function(item) {

                           

                                return (item.countryid == obj.Country());

                           });

 

                           return list;

                        }

 

                        return [];

                    });

 

                    self.list.push(obj);

                    self.current(obj);

                };

 

                //calls on click of Add New Row

                self.addNew = function () {

 

                    self.addRow((self.list().length + 1));

                }

 

                //calls on click of Insert

                self.insert = function (obj) {

                   

                    self.addRow(obj.Order());

 

                    // arranging list after inserting row in between of a grid

                    obj.Order(obj.Order() + 1);

 

                    $.each(self.list(), function(i, item) {

                       

                        if(item.Order() >= obj.Order() && obj != item) {

                          

                            item.Order(item.Order() + 1);

                        }

                    });

                };

 

                // calls on click of Delete

                self.delete = function (obj) {

                   

                    self.list.remove(obj);

 

                    // arranging list after deleting row from in between of a grid

                    $.each(self.list(), function(i, item) {

                       

                        if(item.Order() >= obj.Order()) {

                          

                            item.Order(item.Order() - 1);

                        }

                    });

                };

 

                // return sorted list on the basis of Order field

                self.sortedlist = ko.computed(function() {

                   return self.list().sort(function (left, right) {

                        return left.Order() == right.Order() ? 0 : left.Order() < right.Order() ? -1 : 1

                    });

                });

 

                // calls on click of save

                self.save = function() {

                   

                    var isValid = true;

                    self.showErrors(true);

 

                    $.each(self.list(), function(i, item) {

                      

                        if(item.errors().length > 0) {

                            isValid = false;

                        }

                    });

 

                    if(isValid) {

                        //generating json of records

                        alert(ko.toJSON(self.sortedlist));

                    }

                    else {

                        //setting focus in required field

                        $(".required-field").first().focus();

                    }

                };

            };

 

            //initializing knockout validation

            ko.validation.init({

               

                registerExtenders: true,

                messagesOnModified: true,

                insertMessages: false

            });

 

            var viewModel = new vm();

            ko.applyBindings(viewModel);

        });

 

    </script>

 

I had explained a use of every object and function by commenting above of each. Please read it, I hope u got it easily.

4)      Now in the body section of html create a table and a paragraph by using following script:

    <table class="table table-bordered">

        <thead>

            <tr>

                <th>

                    S. No.

                </th>

                <th>

                    First Name

                </th>

                <th>

                    Last Name

                </th>

                <th>

                    Country

                </th>

                <th>

                    State

                </th>

                <th>

                    Contact No

                </th>

                <th>

                    Designation

                </th>

                <th>

                </th>

            </tr>

        </thead>

        <tbody data-bind="foreach: { data: sortedlist, as: 'row' }">

            <tr data-bind="style: { backgroundColor: row == $parent.current() ? '#E5E5E5': '' }">

                <td data-bind="text:Order">

                </td>

                <td>

                    <input type="text" data-bind="value:FirstName, css:{'required-field':row.showerror(row.FirstName)}, valueUpdate: 'afterkeydown'" />

                </td>

                <td>

                    <input type="text" data-bind="value:LastName, css:{'required-field':row.showerror(row.LastName)}" />

                </td>

                <td>

                    <select data-bind="options:Countries,

                                       optionsText: 'name',

                                       optionsValue: 'id',

                                       value:Country,

                                       optionsCaption: '--Select Country--',

                                       css:{'required-field':row.showerror(row.Country)}">

                    </select>

                </td>

                <td>

                    <select type="text" data-bind="options:States,

                                                   optionsText: 'name',

                                                   optionsValue: 'id',

                                                   value: State,

                                                   optionsCaption: '--Select State--',

                                                   css:{'required-field':row.showerror(row.State)}">

                    </select>

                </td>

                <td>

                    <input type="text" data-bind="value:ContactNo,css:{'required-field':row.showerror(row.ContactNo)}" />

                </td>

                <td>

                    <input type="text" data-bind="value:Designation,css:{'required-field':row.showerror(row.Designation)}" />

                </td>

                <td>

                    <input type="button" data-bind="event: { click: $parent.insert }" value="Insert" />

                    <input type="button" data-bind="event: { click: $parent.delete }" value="Delete" />

                </td>

            </tr>

        </tbody>

        <tfoot>

            <tr>

                <td colspan="8" align="right">

                    <input type="button" data-bind="event: { click: addNew }" value="Add New Row" />

                </td>

            </tr>

        </tfoot>

    </table>

    <p class="text-right col-md-12">

        <input type="submit" data-bind="event: { click: save }" value="Save" />

    </p>

 

Now you can browse the page and see the output. I hope it will give same output as I shown in above two screenshots.

Thanks for reading this article. If you have any doubts or suggestion, please enter by using comment box.

Thursday, 6 February 2014

CRUD Operation using JQuery and Http handler (.ashx) in ASP.Net

In this article I am going to explain how can we achieve simple crud operation (create, read, update and delete) using Jquery and Http handler in asp.net without using asp.net heavy controls on web page.

This article will demonstrate step-by-step, how to create a basic application of CRUD (Create, Read, Update, Delete) Operations using HttpHandler in ASP.Net and JQuery Ajax API. We will also see how can we use jquery.ui modal dialog and datepicker and for database we will use entity framework code first approach that will automatically generate database and required tables according to our DbContext class.

Let’s follow the steps in order to create an application:

1)      Open Microsoft Visual Studio

2)      Select New Project

3)      Select Web from the Installed Templates

4)      Select ASP.NET Empty Web Application

5)      Enter the project name CRUDOperationUsingASHX in the Name textbox

6)      Click OK.

7)      Add a web form in an application (EmployeeForm.aspx)

8)      Now add some required libraries through Package Manager Console.

a)      Go to Tools

b)      Select Library Package Manager

c)       Select Package Manager Console

To Install JQuery type the following command:

 install-package jquery

To install jquery.ui type the flowing command:

Install-package jquery.ui.combined

To install entity framework type the following command:

Install-package entityframework

To install Json package type the following command:

Install-package Newtonsoft.Json

9)      Add a generic hander in a project (EmployeeDetails.ashx)

10)   Add a class JsonResponse in a project:

namespace CRUDOperationUsingASHX

{

    public class JsonResponse

    {

        public bool IsSuccess { get; set; }

        public string Message { get; set; }

        public object Data { get; set; }

        public string CallBack { get; set; }

    }

}

11)   Add another class Employee in a project:

using System;

 

namespace CRUDOperationUsingASHX

{

    public class Employee

    {

        public int Id { get; set; }

        public string FirstName { get; set; }

        public string LastName { get; set; }

        public DateTime Dob { get; set; }

        public string Country { get; set; }

        public string Address { get; set; }

    }

}

12)   Add one more class in a project EmployeeDbContext:

using System.Data.Entity;

 

namespace CRUDOperationUsingASHX

{

    public class EmployeeDbContext: DbContext

    {

        public DbSet<Employee> Employees { get; set; }

    }

}

13)   You also have to configure your web.config file for the implementation of this project. Add the connectionStrings element under configuration tag:

  <connectionStrings>

    <add name="EmployeeDbContext" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=EmployeeDb;Integrated Security=true;" providerName="System.Data.SqlClient" />

  </connectionStrings>

 

14)   Add a java script file for an application (app.js)

After adding above libraries and project files the solution explorer should something like below:

Now we will cover coding part in our application.

15)   Enter the html and css in EmployeeForm.aspx page given below:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="EmployeeForm.aspx.cs" Inherits="CRUDOperationUsingASHX.EmployeeForm" %>

 

<!DOCTYPE html>

 

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

    <title></title>

    <link href="Content/themes/base/minified/jquery-ui.min.css" rel="stylesheet" />

    <script src="Scripts/jquery-2.0.3.js"></script>

    <script src="Scripts/jquery-ui-1.10.3.js"></script>

    <script src="Scripts/app.js"></script>

    <style type="text/css">

        body

        {

            font-family: Georgia, Verdana;

            font-size: .9em;

        }

 

        #div-employee-form div {

            padding-bottom:10px;

        }

        #div-employee-form div span{

            display:inline-block;

            width:130px;

        }

        .grid {

            margin-top:10px;

            border: 1px solid black;

            display:table;

           

        }

        .grid .header {

            display:table-row;

            border: 1px solid black;

        }

        .grid .header span {

            font-weight:bold;

            display:table-cell;

            padding:10px;

            border-bottom:1px solid black;

            border-right:1px solid black;

        }

        .grid .content {

            display:table-cell;

            padding:10px;

        }

    </style>

</head>

<body>

    <form id="form1" runat="server">

        <div>

            <a href="#" class="openDialog" title="New Employee Form">Create New</a>

        </div>

        <div id="div-employee-list" class="grid">

 

        </div>

        <div id="div-employee-form" style="display: none;">

            <div>

                <span>First Name:</span>

                <input type="text" id="txtFirstName" />

            </div>

            <div>

                <span>Last Name:</span>

                <input type="text" id="txtLastName" />

            </div>

            <div>

                <span>Date of Birth:</span>

                <input type="text" id="txtDob" />

            </div>

            <div>

                <span>Country:</span>

                <select id="cmbCountry">

                    <option value="">Select Country</option>

                    <option value="India">India</option>

                    <option value="Newzeland">Newzeland</option>

                </select>

            </div>

            <div>

                <span style="vertical-align:top;">Address:</span>

                <textarea cols="20" rows="2" id="txtAddress"></textarea>

            </div>

        </div>

 

        <div id="div-confirm-dialog" style="display:none">

            <span>Are you sure want to delete this record?</span>

        </div>

    </form>

</body>

</html>

 

16)   EmployeeDetails.ashx contains the following code to insert, update, delete the data into the database and read the data from the database:

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using Newtonsoft.Json;

 

namespace CRUDOperationUsingASHX

{

    public class EmployeeDetails : IHttpHandler

    {

        string methodname = string.Empty;

        string callbackmethodname = string.Empty;

        string parameter = string.Empty;

 

        EmployeeDbContext dbEmployee = new EmployeeDbContext();

 

        public void ProcessRequest(HttpContext context)

        {

            context.Response.ContentType = "application/json";

            methodname = context.Request.Params["method"];

            parameter = context.Request.Params["param"];

            callbackmethodname = context.Request.Params["callbackmethod"];

 

            switch (methodname.ToLower())

            {

                case "getemployees":

                    context.Response.Write(GetEmployees());

                    break;

                case "getbyid":

                    context.Response.Write(GetById(int.Parse(context.Request.Params["Id"])));

                    break;

                case "insert":

                    context.Response.Write(Insert(context));

                    break;

                case "update":

                    context.Response.Write(Update(context));

                    break;

                case "delete":

                    context.Response.Write(Delete(int.Parse(context.Request.Params["Id"])));

                    break;

            }

        }

 

        public string Insert(HttpContext context)

        {

            JsonResponse response = new JsonResponse();

 

            try

            {

                Employee emp = new Employee

                {

                    FirstName = context.Request.Params["FirstName"],

                    LastName = context.Request.Params["LastName"],

                    Dob = Convert.ToDateTime(context.Request.Params["Dob"]),

                    Country = context.Request.Params["Country"],

                    Address = context.Request.Params["Address"]

                };

                dbEmployee.Employees.Add(emp);

                dbEmployee.SaveChanges();

 

                response.IsSuccess = true;

                response.Data = emp;

                response.Message = "Employee inserted successfully!";

                response.CallBack = callbackmethodname;

            }

            catch (Exception ex)

            {

                response.IsSuccess = false;

                response.Message = ex.Message;

            }

 

            return JsonConvert.SerializeObject(response);

        }

 

        public string Update(HttpContext context)

        {

            JsonResponse response = new JsonResponse();

 

            try

            {

                int id = int.Parse(context.Request.Params["Id"]);

 

                Employee emp = dbEmployee.Employees.FirstOrDefault(m => m.Id == id);

 

 

                emp.FirstName = context.Request.Params["FirstName"];

                emp.LastName = context.Request.Params["LastName"];

                emp.Dob = Convert.ToDateTime(context.Request.Params["Dob"]);

                emp.Country = context.Request.Params["Country"];

                emp.Address = context.Request.Params["Address"];

 

                dbEmployee.SaveChanges();

 

                response.IsSuccess = true;

                response.Data = emp;

                response.Message = "Employee updated successfully!";

                response.CallBack = callbackmethodname;

            }

            catch (Exception ex)

            {

                response.IsSuccess = false;

                response.Message = ex.Message;

            }

 

            return JsonConvert.SerializeObject(response);

        }

 

        public string Delete(int id)

        {

            JsonResponse response = new JsonResponse();

 

            try

            {

                Employee emp = dbEmployee.Employees.FirstOrDefault(m => m.Id == id);

                if (emp != null)

                {

                    dbEmployee.Employees.Remove(emp);

                    dbEmployee.SaveChanges();

                    response.IsSuccess = true;

                    response.CallBack = callbackmethodname;

                    response.Data = "Employee Deleted successfully!";

                    response.Message = "Employee Deleted successfully!";

                }

                else

                {

                    response.IsSuccess = false;

                    response.Message = "Employee not exist!";

                }

            }

            catch (Exception ex)

            {

                response.IsSuccess = false;

                response.Message = ex.Message;

            }

 

            return JsonConvert.SerializeObject(response);

        }

 

        public string GetEmployees()

        {

            JsonResponse response = new JsonResponse();

 

            try

            {

                IEnumerable<Employee> employees = dbEmployee.Employees.ToList();

                response.IsSuccess = true;

                response.CallBack = callbackmethodname;

                response.Data = employees;

            }

            catch (Exception ex)

            {

                response.Message = ex.Message;

                response.IsSuccess = false;

            }

 

            return JsonConvert.SerializeObject(response);

        }

 

        public string GetById(int id)

        {

            JsonResponse response = new JsonResponse();

 

            try

            {

                Employee emp = dbEmployee.Employees.FirstOrDefault(m => m.Id == id);

                response.IsSuccess = true;

                response.CallBack = callbackmethodname;

                response.Data = emp;

            }

            catch (Exception ex)

            {

                response.IsSuccess = false;

                response.Message = ex.Message;

            }

 

            return JsonConvert.SerializeObject(response);

        }

 

        public bool IsReusable

        {

            get

            {

                return false;

            }

        }

    }

}

 

17)   Client side script file (app.js) contains the following code in order to open modal dialog, creating datepicker, making ajax request and updating the ui (User Interface) dynamically by using jquery.

 

var employeeId = 0;

 

$(function () {

 

    $.ajaxSetup({ cache: false });

 

    $("a").button();

 

    $("#txtDob").datepicker();

 

 

    $(document).on('click', '.openDialog', function (event) {

 

        event.preventDefault(); //use this or return false

 

        var $title = $(this).attr("title");

        var data = $(this).attr("data-val");

        $("#div-employee-form").dialog({

            title: $title,

            autoOpen: false,

            resizable: false,

            height: 340,

            width: 380,

            show: { effect: 'drop', direction: "up" },

            modal: true,

            draggable: true,

            buttons: {

                "Save": function () {

                    saveEmployee();

                },

                "Cancel": function () {

                    $(this).dialog('close');

                }

            },

            open: function (ev, ui) {

                if (data) {

                    employeeId = data;

                    getEmployeeById(employeeId);

                }

            },

            close: function (ev, ui) {

            }

        });

 

        $("#div-employee-form").dialog('open');

        return false;

    });

 

    $(document).on("click", ".confirmDialog", function (event) {

 

        event.preventDefault();

        var data = $(this).attr("data-val");

 

        $("#div-confirm-dialog").dialog({

            title: 'Delete Employee',

            autoOpen: false,

            resizable: false,

            height: 170,

            width: 300,

            show: { effect: 'drop', direction: "up" },

            modal: true,

            draggable: true,

            buttons: {

                "Done": function () {

                    employeeId = data;

                    deleteEmployee(employeeId);

                },

                "Cancel": function () {

                    $(this).dialog('close');

                }

            },

        });

 

        $("#div-confirm-dialog").dialog('open');

        return false;

    });

 

    getEmployeeList();

});

 

function makeAjaxCall(parameter) {

 

    $.ajax({

        type: 'POST',

        url: "EmployeeDetails.ashx",

        data: parameter,

        dataType: 'json',

        success: function (response) {

            if (response.IsSuccess) {

                eval(response.CallBack + '(response.Data, response.Message)');

            }

            else {

 

            }

        },

        error: function () {

 

        }

    })

}

 

function getEmployeeList() {

 

    makeAjaxCall({ method: "getemployees", callbackmethod: "getEmployeeListOnSuccess" })

}

 

function getEmployeeListOnSuccess(data) {

 

    var html = "<div class='header'><span>First Name</span><span>Last Name</span><span>DOB</span><span>Country</span><span>Address</span></div>";

    $.each(data, function (i, val) {

 

        html += createRow(val);

    });

 

    $("#div-employee-list").html(html);

}

 

function getEmployeeById(id) {

    makeAjaxCall({ method: "getbyid", callbackmethod: "editEmployeeSuccess", Id: id });

}

 

function insertEmployeeSuccess(data, message) {

 

    alert(message);

    $("#div-employee-form").dialog('close');

    $("#div-employee-list").append(createRow(data));

}

 

function editEmployeeSuccess(data) {

 

    setValues(data);

}

 

function updateEmployeeSuccess(data, message) {

 

    var divToUpdate = $(".grid div[id=" + employeeId + "]");

    var rowHtml = createRow(data);

 

    var newDiv = $(rowHtml).filter("div[id=" + employeeId + "]");

    $(divToUpdate).html($(newDiv).html());

 

    alert(message);

    employeeId = 0;

    $("#div-employee-form").dialog('close');

}

 

function deleteEmployeeSuccess(message) {

 

    var divToUpdate = $(".grid div[id=" + employeeId + "]");

    $(divToUpdate).remove();

    alert(message);

    employeeId = 0;

    $("#div-confirm-dialog").dialog('close');

}

 

function saveEmployee() {

 

    var firstNameValue = $("#txtFirstName").val();

    var lastNameValue = $("#txtLastName").val();

    var dobValue = $("#txtDob").val();

    var countryValue = $("#cmbCountry").val();

    var addressValue = $("#txtAddress").val();

    if (employeeId == 0)

        makeAjaxCall({ method: "insert", callbackmethod: "insertEmployeeSuccess", FirstName: firstNameValue, LastName: lastNameValue, Dob: dobValue, Country: countryValue, Address: addressValue });

    else

        makeAjaxCall({ method: "update", callbackmethod: "updateEmployeeSuccess", Id: employeeId, FirstName: firstNameValue, LastName: lastNameValue, Dob: dobValue, Country: countryValue, Address: addressValue });

}

 

function deleteEmployee(id) {

    makeAjaxCall({ method: "delete", callbackmethod: "deleteEmployeeSuccess", Id: id });

}

 

function createRow(objEmployee) {

 

    var htmlRow = "";

 

    var dateValue = new Date(objEmployee.Dob);

    var dateValueAfterFormat = dateValue.getFullYear() + "-" + (dateValue.getMonth() + 1) + "-" + dateValue.getDate();

 

    htmlRow += "<div style='display:table-row' id=\"" + objEmployee.Id + "\">";

    htmlRow += "<span class='content'>" + objEmployee.FirstName + "</span>";

    htmlRow += "<span class='content'>" + objEmployee.LastName + "</span>";

    htmlRow += "<span class='content'>" + dateValueAfterFormat + "</span>";

    htmlRow += "<span class='content'>" + objEmployee.Country + "</span>";

    htmlRow += "<span class='content'>" + objEmployee.Address + "</span>";

    htmlRow += "<a class='content openDialog' href='#' data-val=\"" + objEmployee.Id + "\">Edit</a>";

    htmlRow += "<a class='content confirmDialog' href='#' data-val=\"" + objEmployee.Id + "\">Delete</a>";

    htmlRow += "</div>";

 

    return htmlRow;

}

 

function setValues(objEmployee) {

    $("#txtFirstName").val(objEmployee.FirstName);

    $("#txtLastName").val(objEmployee.LastName);

 

    //12/03/2013

    var dateValue = new Date(objEmployee.Dob);

    var dateValueAfterFormat = (dateValue.getMonth() + 1) + "/" + dateValue.getDate() + "/" + dateValue.getFullYear();

 

    $("#txtDob").val(dateValueAfterFormat);

    $("#cmbCountry").val(objEmployee.Country);

    $("#txtAddress").val(objEmployee.Address);

}

 

After the doing and understanding the above major stuff, let’s build and run an application, the ouput should be something like below figure:

In order to add or create a new employee, click on Create New button, it will show you a employee entry form in modal dialog.

You can fill the necessary details of employees provided in the form and save it into the database by using Save button.

 

After adding or updating the data will be reflected in the grid format in main application form i.e. EmployeeForm.aspx

You can also delete the employee record by using delete hyperlink in the employee record in the grid.

 

In the same way you can also edit the employee information.

Thanks for reading this article. I think this will help you a lot.

Please provide you valuable comments and suggestions.