Saturday, July 5, 2014

Working with Knockoutjs in MVC C# - Create, delete and update the data.

        You need some Knockoutjs basics to understand this article. I have already posted the Knockoutjs basics. And this tutorial explains you about the create, delete and update the grid data in KnockoutJs with MVC. Firstly, create your new MVC project with Web Api.

Watch sample output video:




Wep Api:

       After creating Entity data model, repositories in the project then you need to create a new Api Controller called "UserApiController". By default, you will get Get, Post, Put and Delete http methods. Follow the methods code below.

Get:
      It is used to get the list of records/single record. It is used only to retrieve the data. Follow the Get Method below. First one is to get all the list. Another to get the specific user information.
       
     // GET api for User list.
        [Route("v1/GetUsers")]
    public IQueryable<User> GetUsers()
    {
      return db.Users;
    }

       // GET api for particular User
        [Route("v1/GetUser/{id}")]
    [ResponseType(typeof(User))]
     public IHttpActionResult GetUser(long id)
        {
            User user = db.Users.Find(id);
            if (user == null)
            {
                return NotFound();
            }

            return Ok(user);
        }


Post:
    It is used to create new record. It have no restrictions on data length. Follow the POST method below. You have to post along with user entity model.

       // POST api/User
    [Route("v1/PostUser")]
    [ResponseType(typeof(User))]
     public IHttpActionResult PostUser(User user)
      {
        if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

      db.Users.Add(user);
      db.SaveChanges();
      return StatusCode(HttpStatusCode.NoContent);
       }

Delete:
It used to delete the records in the database.

      // DELETE api/User/5
    [Route("v1/DeleteUser/{id}")]
    [ResponseType(typeof(User))]
     public IHttpActionResult DeleteUser(long id)
       {
         User user = db.Users.Find(id);
         if (user == null)
          {
            return NotFound();
           }

       db.Users.Remove(user);
       db.SaveChanges();

       return Ok(user);
       }

Put:
It mainly used to update the data or records in the server. Following code will update the user details in the server if user exists.

        // PUT api/User/5
    [Route("v1/PutUser}")]
     public IHttpActionResult PutUser( User user)
     {
        
         db.Entry(user).State = EntityState.Modified;
         db.SaveChanges();
        
        return StatusCode(HttpStatusCode.NoContent);
      }

ViewModel:

        It is a pure-code representation of data and operations on a UI. It doesn't have any concept of buttons and styles. It is pure JavaScript object.
Then create a new JavaScript file as "UserViewModel" or place the script in the VIEW. Follow the code below.

$(document).ready(function () {
 //Create new function called 'userViewmodel'.
    function userViewmodel() {

//Converting 'this' into another variable (traditionally called 'self').It can be used throughout the ViewModel. Because 'self is' captured in the function closure, it remains available and consistent in any nested functions, such as KO.
 
 
        var self = this;
     //Declaring all required attributes...
 
        self.UserId = ko.observable("");
        self.FullName = ko.observable("");
        self.FirstName = ko.observable("");
        self.LastName = ko.observable("");
        self.Email = ko.observable("");
        self.Phone = ko.observable("");
        self.Address = ko.observable("");
        self.City = ko.observable("");
        self.State = ko.observable("");
        self.Gender = ko.observable("");
        self.UserGroup = ko.observable("");
        self.Status = ko.observable(true);
       
     //Creating an array object.

        var user = {
            UserId: self.UserId,
            FullName: self.FullName,
            FirstName: self.FirstName,
            LastName: self.LastName,
            Email: self.Email,
            Address: self.Address,
            City: self.City,
            State: self.State,
            Phone: self.Phone,
            Gender: self.Gender,
            Status: self.Status,
            UserGroup: self.UserGroup

        }
     
        self.user = ko.observable();
        self.users = ko.observableArray(); 
       
        //Enabling 'Add New User' button by default.
          self.CreateNewUserButton = ko.observable(true);
        //Disabling 'Create new user' Div by default.
          self.NewUserDiv = ko.observable(false);
        //Disabling 'Edit user' Div.
          self.EditUserDiv = ko.observable(false);
        //Enabling Edit Button.
          self.EditButton = ko.observable(true);

//////Getting users list///////

      //Calling 'getUsersList' function on document load.
        getUsersList();
     
        function getUsersList() {
            $.getJSON("/v1/GetUsers")
            .done(function (data) {
              //Applying JSON data to KO array.
                self.users(data);
            });
        }

//////Add new user////////
 
     //Add new Button function       
        self.CreateUserbtn = function () {
            self.CreateNewUserButton(false);//Disabling 'Add User User' button.
            self.NewUserDiv(true);         //Enabling NewUser Div here.
            self.user(null);              //Making 'user' array object to null. 
        }
        
     //Create new user ajax post function.
        self.createUser = function () {
            if (user.FullName().trim() == "" ) {
                    toastr.error('Please enter Name!', '')
                    return false;
                }
                  $.ajax({
                    url: '/v1/PostUser',
                    cache: false,
                    type: 'POST',
                    contentType: 'application/json; charset=utf-8',
                    data: ko.toJSON(user),
                    success: function (data) {
                    //If user added successfully then below msg will be shown!
                    toastr.success('New account added successfully!', '');
                       
                    getUsersList();

                    }
                }).fail(
                         function (xhr, textStatus, err) {
                            //Failed to create new user!
                             toastr.error(err, 'Error')
                         });
            }
       
      //Add User: Cancel button function 
          self.CancelSave = function () {
                self.NewUserDiv(false);
                self.CreateNewUserButton(true);
            }


/////Edit User/////
        
      //Edit Button Funtion
        self.EditBtn = function (user) {
            self.user(user);
            self.NewUserDiv(false);
            self.CreateNewUserButton(true);
        }

      //Ajax post for update user details    
        self.UpdateUserInfo= function ()
        {
           
            var user = self.user();
           
            $.ajax({
                url: 'v1/PutUser',
                cache: false,
                type: 'PUT',
                contentType: 'application/json; charset=utf-8',
                data: ko.toJSON(user),
                success: function (data) {
                 toastr.success('Profile updated successfully!', '');

                 getUsersList();

                }
            }).fail(
                         function (xhr, textStatus, err) {
                             toastr.error(err, 'Error')
                         });
        }

     //Edit User: Cancel Button Function
        self.EditCancelBtn = function ()
        {
            self.user(null);
        }

 /////Delete user/////

       //Deleting the user record in the server using ajax post.
          self.DeleteUser = function (user)
           {
            var userId = user.UserId;
            
            $.ajax({
                url: '/v1/DeleteUser/'+userId,
                type: 'DELETE',
                success: function (data) {
                toastr.success('User deleted successfully!', '');
                getUsersList();
                }
            }).fail(
                        function (xhr, textStatus, err) {
                          toastr.error(err, 'Error')
                    });
        }


    };

    ko.applyBindings(new userViewmodel());

});


View:

       Now, open your view "Index". Add required scripts in the view.
    
   <script src="~/Scripts/knockout-3.1.0.js" type="text/javascript"></script>
   <script src="~/KOViewModels/UserViewModel.js" type="text/javascript"></script>

 
And if you want toastr messages then add below script and styles. Otherwise skip the below scripts.
  
 <script src="~/Scripts/toastr.min.js" type="text/javascript"></script>
  <link href="~/Content/toastr.min.css" rel="stylesheet" />


I have adding, updating and deleting the list of records using KO. We can do add, update and delete the records in single view without refreshing the page. This is wonderful feature we have in KO.

Display a KO List:
     First, we are applying the JSON array data to 'users' KO array. Then loop the array. Follow the below HTML code to display list of records.

 <div class="col-md-6" style="padding-top:10px">

     <div class="table-responsive">
       <span style="color:blue; float:left"><b>Users</b></span>

         <button type="submit" style="float:right" class="btn btn-primary btn-xs" data-bind="click: $root.CreateUserbtn, visible: CreateNewUserButton()">Add New User</button>
                
            
            <table id="user" data-bind="visible: users().length > 0" class="table table-hover" width="500">
                <thead>
                    <tr>
                        <th style="display:none;">
                            No.
                        </th>
                        <th>
                            Name
                        </th>

                        <th>
                            Email
                        </th>

                        <th>
                            City
                        </th>

                        <th>
                            State
                        </th>
                        <th></th>

                    </tr>
                </thead>
                <tbody data-bind="foreach: users">
                    <tr>
                      <td data-bind="text:UserId,uniqueName:true" style="display:none;"></td>
                      <td data-bind="text: FullName, uniqueName:true"></td>
                      <td data-bind="text: Email, uniqueName:true"></td>
                      <td data-bind="text: City, uniqueName:true"></td>
                      <td data-bind="text: State, uniqueName:true"></td>

                      <td><button class="btn btn-primary btn-xs btn-mini" data-bind="click: $root.EditBtn">Edit</button>
                            <button class="btn btn-primary btn-xs btn-mini" data-bind="click: $root.DeleteUser">Delete</button>
                        </td>

                    </tr>
                </tbody>
            </table>
        </div>
    </div>





Create new record:
      Get the required fields for adding a new record. The data binded to respected object automatically when textbox is filled. Then data will be sent to the server. Follow the HTML code for creating a new record.

<div class="col-md-6">
  <div data-bind="visible: NewUserDiv()">
    <div>
      <div class="caption" style="padding-top: 10px; text-align: center">
           <span style="color:blue;text-decoration:underline">
            <b>Create New User</b></span>
       </div>
     </div>
   <div>
    <form role="form">
       <div class="form-group">
        <label for="FullName" class="col-md-3 control-label">User Name</label>
          <div class="col-md-9">
             <input type="text" class="form-control" data-bind="value:FullName" placeholder="Enter user name" required>
               <span class="help-block"></span>
          </div>
        </div>

         <div class="form-group">
           <label for="FirstName" class="col-md-3 control-label">First Name</label>
              <div class="col-md-9">
                 <input type="text" class="form-control" data-bind="value:FirstName" placeholder="Enter first name" required>
                     <span class="help-block"></span>
               </div>
         </div>
         <div class="form-group">
           <label for="lastName" class="col-md-3 control-label">Last Name</label>

             <div class="col-md-9">
               <input type="text" class="form-control" data-bind="value:LastName" placeholder="Enter last name" required data-content="last name">
                <span class="help-block"></span>
             </div>
         </div>

         <div class="form-group">
           <label for="email" class="col-md-3 control-label">Email</label>
             <div class="col-md-9">
                 <input type="text" class="form-control" data-bind="value:Email" placeholder="Enter email" required>
                      <span class="help-block"></span>
              </div>
         </div>

         <div class="form-group">
            <label for="phone" class="col-md-3 control-label">Phone</label>
               <div class="col-md-9">
                  <input type="text" class="form-control" data-bind="value:Phone" placeholder="Enter Phone Number">
                      <span class="help-block"></span>
               </div>
         </div>

         <div class="form-group">
            <label for="Address" class="col-md-3 control-label">Address</label>
               <div class="col-md-9">
                  <input type="text" class="form-control" data-bind="value:Address" placeholder="Enter Address">
                      <span class="help-block"></span>
               </div>
         </div>

         <div class="form-group">
           <label for="City" class="col-md-3 control-label">City</label>
              <div class="col-md-9">
                 <input type="text" class="form-control" data-bind="value:City" placeholder="Enter City">
                     <span class="help-block"></span>
               </div>
          </div>

         <div class="form-group">
           <label for="State" class="col-md-3 control-label">State</label>
              <div class="col-md-9">
                 <input type="text" class="form-control" data-bind="value:State" placeholder="Enter State">
                     <span class="help-block"></span>
               </div>
          </div>
       
         <div class="form-group">
            <div style="text-align:center">
                <button type="submit" class="btn btn-success" data-bind="click: $root.createUser" title="Save">Add</button>

                 <button type="submit" class="btn btn-danger" data-bind="click: $root.CancelSave" title="Cancel">Cancel</button>
            </div>
         </div>


        </form>
      </div>
   </div>
</div>




Update record:
Get the data and fill the fields. Its faster than others. Follow the HTML code for Update an record.

<div class="col-md-6">
    <div class="" data-bind="if: user">
        <div>
            <div class="caption" style="padding-top:10px; text-align:center">
                <span style="color:blue;text-decoration:underline">
                     <b>Update User Information</b></span>
            </div>

         </div>
    <div>
       <form role="form">
            <div class="form-group">
               <label for="FullName" class="col-md-3 control-label">User Name</label>
                    <div class="col-md-9">
                        <input type="text" class="form-control" data-bind="value:user().FullName" placeholder="Enter user name" required>
                             <span class="help-block"></span>
                     </div>
             </div>

            <div class="form-group">
                <label for="FirstName" class="col-md-3 control-label">First Name</label>
                <div class="col-md-9">
                   <input type="text" class="form-control" data-bind="value:user().FirstName" placeholder="Enter first name" required>
                        <span class="help-block"></span>
                 </div>
            </div>

            <div class="form-group">
               <label for="lastName" class="col-md-3 control-label">Last Name</label>
               <div class="col-md-9">
                  <input type="text" class="form-control" data-bind="value:user().LastName" placeholder="Enter last name" required data-content="last name">
                      <span class="help-block"> </span>
                </div>
             </div>

             <div class="form-group">
                <label for="email" class="col-md-3 control-label">Email</label>
                    <div class="col-md-9">
                       <input type="text" class="form-control" data-bind="value:user().Email" placeholder="Enter email" required>
                            <span class="help-block"></span>
                     </div>
              </div>

             <div class="form-group">
               <label for="phone" class="col-md-3 control-label">Phone</label>
                   <div class="col-md-9">
                     <input type="text" class="form-control" data-bind="value:user().Phone" placeholder="Enter Phone Number">
                         <span class="help-block"></span>
                   </div>
             </div>

             <div class="form-group">
                <label for="Address" class="col-md-3 control-label">Address</label>
                    <div class="col-md-9">
                       <input type="text" class="form-control" data-bind="value:user().Address" placeholder="Enter Address">
                            <span class="help-block"></span>
                    </div>
             </div>

             <div class="form-group">
                 <label for="City" class="col-md-3 control-label">City</label>
                      <div class="col-md-9">
                        <input type="text" class="form-control" data-bind="value:user().City" placeholder="Enter City">
                            <span class="help-block"></span>
                       </div>
              </div>

              <div class="form-group">
                  <label for="State" class="col-md-3 control-label">State</label>
                      <div class="col-md-9">
                         <input type="text" class="form-control" data-bind="value:user().State" placeholder="Enter State">
                               <span class="help-block"></span>
                       </div>
              </div>

                   
              <div class="form-group">
                  <div style="text-align:center">
                     <button type="submit" class="btn btn-success" data-bind="click: $root.UpdateUserInfo" title="Save">Update</button>

                     <button type="submit" class="btn btn-danger" data-bind="click: $root.EditCancelBtn" title="Cancel">Cancel</button>
                   </div>
               </div>


            </form>
         </div>
     </div>
 </div>


      We can easily display a list, create, update and delete an record using Knockoutjs in MVC. We need to work out few things in the start-up then it goes everything smoothly.

Have a nice day!!






1 comment:

  1. It is a nice post about working with MVC and KnockoutJs.
    Please share the source code if possible. My email is ms4hafiz@live.com

    ReplyDelete