Showing posts with label Kendo UI Grid. Show all posts
Showing posts with label Kendo UI Grid. Show all posts

Tuesday, September 29, 2015

Kendo UI Popup with Partial View rendering

Kendo UI Popup with Partial View rendering

Requirement: Show a list of Web Users in Kendo UI Grid with a view button. When users click view button, a popup containing selected web user’s info is displayed.
Assuming you already have an MVC website created with references added for Kendo.Mvc.

Step 1: Create model, name it as “WebUser”, and code all the properties for the model as shown:
 using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
 
namespace MVCBasics.Models
{
    public class WebUser
    {
       
        [DisplayName("User Id")]
        public int? UserId getset; }
      
        [Required(ErrorMessage = "*")]
        [DisplayName("First Name")]
        public string FName { getset; }
       
        [DisplayName("Middle Name")]
        public string MName { getset; }
      
        [Required(ErrorMessage = "*")]
        [DisplayName("Last Name")]
        public string LName { getset; }
        
        [DisplayName("User Name")]
        public string UserName { getset; }
       
    }
}

Step 2: Create controller, name it as “WebUserController”. 
using Kendo.Mvc.Extensions;
using Kendo.Mvc.UI;
using MVCBasics.Models;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
 
namespace MVCBasics.Controllers
{
    public class WebUserController : Controller
    {
       /// <summary>
        /// Returns default view for Manage Users
        /// </summary>
        /// <returns></returns>
        public ActionResult Index()
        {
            return View();
        }
 
   }
}

Step 2.1: Create a function to interact with DB to get list of users (I am constructing user’s list to make things simple). Name the function as “GetWebUsers
/// <summary>
/// Constructing Users, in real world get from database
/// </summary>
/// <returns></returns>
private List<WebUserGetWebUsers()
{
    var lstUsers = new List<WebUser>();
    lstUsers.Add(new WebUser() { UserId = 1001, FName = "John", LName = "Estama", UserName = "john.esta@company.com" });
    lstUsers.Add(new WebUser() { UserId = 1002, FName = "Alex", LName = "Smotritsky", UserName = "alex.smot@company.com" });
    lstUsers.Add(new WebUser() { UserId = 1003, FName = "Boris", LName = "Konstevich", UserName = "boris.konst@company.com" });
    lstUsers.Add(new WebUser() { UserId = 1004, FName = "Nathan", LName = "Merrill", UserName = "nathan.merri@company.com" });
 
    return lstUsers;
}

Step 2.2: Create JsonResult functions for GetAllUsers and GetUserInfo as shown below:
/// <summary>
/// Gets all users.
/// </summary>
/// <param name="request">The request.</param>
/// <returns></returns>
public JsonResult GetAllUsers([DataSourceRequestDataSourceRequest request)
{
    //Return Queryable list of users
    return Json(GetWebUsers().AsQueryable().ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
 
/// <summary>
/// Gets the user information by selected User Id.
/// </summary>
/// <param name="UserId">The user identifier.</param>
/// <returns></returns>
public JsonResult GetUserInfo(int UserId)
{
    //Filter Users list for selected User Id
    var userInfo = GetWebUsers().ToList().Where(a => a.UserId == UserId).FirstOrDefault();
 
    return Json(userInfoJsonRequestBehavior.AllowGet);
}

Step 2.3: Create PartialViewResult function for returning partial view containing user info:
/// <summary>
/// Returns partial view named partUserInfoView
/// </summary>
/// <param name="user">The user.</param>
/// <returns></returns>
public PartialViewResult partUserInfoView(WebUser user)
{
    //pass user info to Partial View and return it to client. The partial view will be rendered into modal popup.
    return PartialView(user);
 
}

This is how the final version of the controller looks:
using Kendo.Mvc.Extensions;
using Kendo.Mvc.UI;
using MVCBasics.Models;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
 
namespace MVCBasics.Controllers
{
    public class WebUserController : Controller
    {
 
        /// <summary>
        /// Returns default view for Manage Users
        /// </summary>
        /// <returns></returns>
        public ActionResult Index()
        {
            return View();
        }
 
 
        /// <summary>
        /// Gets all users.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns></returns>
        public JsonResult GetAllUsers([DataSourceRequestDataSourceRequest request)
        {
            //Return Queryable list of users
            return Json(GetWebUsers().AsQueryable().ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
        }
 
        /// <summary>
        /// Gets the user information by selected User Id.
        /// </summary>
        /// <param name="UserId">The user identifier.</param>
        /// <returns></returns>
        public JsonResult GetUserInfo(int UserId)
        {
            //Filter Users list for selected User Id
            var userInfo = GetWebUsers().ToList().Where(a => a.UserId == UserId).FirstOrDefault();
 
            return Json(userInfoJsonRequestBehavior.AllowGet);
        }
 
        /// <summary>
        /// Returns partial view named partUserInfoView
        /// </summary>
        /// <param name="user">The user.</param>
        /// <returns></returns>
        public PartialViewResult partUserInfoView(WebUser user)
        {
            //pass user info to Partial View and return it to client. The partial view will be rendered into modal popup.
            return PartialView(user);
 
        }
 
 
        /// <summary>
        /// Constructing Users, in real world get from database
        /// </summary>
        /// <returns></returns>
        private List<WebUserGetWebUsers()
        {
            var lstUsers = new List<WebUser>();
            lstUsers.Add(new WebUser() { UserId = 1001, FName = "John", LName = "Estama", UserName = "john.esta@company.com" });
            lstUsers.Add(new WebUser() { UserId = 1002, FName = "Alex", LName = "Smotritsky", UserName = "alex.smot@company.com" });
            lstUsers.Add(new WebUser() { UserId = 1003, FName = "Boris", LName = "Konstevich", UserName = "boris.konst@company.com" });
            lstUsers.Add(new WebUser() { UserId = 1004, FName = "Nathan", LName = "Merrill", UserName = "nathan.merri@company.com" });
 
            return lstUsers;
        }
 
 
    }
}

Step 3: Right click on “ActionResult Index()” select Add View. This will create a new view named “Index” under Views folder.

Step 4: Add Kendo UI Grid to show a list of all the users:
@(Html.Kendo().Grid<MVCBasics.Models.WebUser>()
            .Name("grdClients")
            .Columns(columns =>
            {
                columns.Bound(=> p.FName).Filterable(true).Width(150).HeaderTemplate("First Name");
                columns.Bound(=> p.LName).Filterable(true).Width(100).HeaderTemplate("Last Name");
                columns.Bound(=> p.UserId).Filterable(false).Width(40).ClientTemplate(
                    "<span style='white-space:nowrap !important; width:40px !important;'>"
                    + "<a class='btn btn-inform' title='Click to view user info.' onClick='ViewUser(\"#=UserId#\")' style='' ><i class='glyphicon glyphicon-eye-open'></i></a>&nbsp;"
                    + "</span>").HeaderTemplate(" ");
 
            })
            .Sortable()
            .Pageable(=> a.PageSizes(true))
            .Filterable()
            .NoRecords("")
            .DataSource(
                        dataSource => dataSource
                        .Ajax()
                        .Model(model =>
                        {
                            model.Id(=> p.UserId);
                        })
                        .Read(read => read.Action("GetAllUsers""WebUser"))
                        .PageSize(10)
                        )
)
The first two columns are straight forward but the third column; I wanted to show a view button. Clicking the view button will show modal popup rendering user’s info. I’ve placed an anchor tag that calls ViewUser(UserId) javascript fuction to render user info in a model popup.

Step 5: Add an empty div with id=”windowUser”, this will act as a placeholder for model popup.
<div id="windowUser"></div>

Step 6: Add script tag at the bottom of the page.

Step 7: Under script tag, initiate Kendo UI Window control inside $(document).ready function and map it to the empty div control. After this step, the div control is ready to be shown as a model popup.
$(document).ready(function () {
 
    $("#windowUser").kendoWindow({
        title: "User Info",
        modal: true,
        resizable: false,
        visible: false,
        width: "30%",
        actions: ["Close"],
        close: function (e) {
        }
    });
});

Step 8: Code for ViewUser function
function ViewUser(userId) {
 
       //Construct url for GetUserInfo action from WebUser Controller
       var urlGetUserInfo = '@Url.Action("GetUserInfo""WebUser")';
 
       //Make an AJAX call to send UserId to the above action and retreive UserInfo object containing data returned by the action.
       $.getJSON(urlGetUserInfo, { UserId: userId }, function (userInfo) {
 
           //Check User Info for no data 
           if (userInfo != null) {
               //Pass the User Info object to partUserInfoView (Partial View) and load it under the empty div "windowUser" we created earlier
               $("#windowUser").load("partUserInfoView", { user: userInfo });
           }
 
       });
 
       //Get the ref for kendo ui modal window object for windowUser
       var windowUser = $("#windowUser").data("kendoWindow");
       
       //Open the modal popup and position it to the center of the screen
       windowUser.center().open();
   }

The final version of the view looks like this:
@using Kendo.Mvc.UI
@{
    ViewBag.Title = "Index";
}
 
<h2>Manage Users</h2>
  
@(Html.Kendo().Grid<MVCBasics.Models.WebUser>()
            .Name("grdClients")
            .Columns(columns =>
            {
                columns.Bound(=> p.FName).Filterable(true).Width(150).HeaderTemplate("First Name");
                columns.Bound(=> p.LName).Filterable(true).Width(100).HeaderTemplate("Last Name");
                columns.Bound(=> p.UserId).Filterable(false).Width(40).ClientTemplate(
                    "<span style='white-space:nowrap !important; width:40px !important;'>"
                    + "<a class='btn btn-inform' title='Click to view user info.' onClick='ViewUser(\"#=UserId#\")' style='' ><i class='glyphicon glyphicon-eye-open'></i></a>&nbsp;"
                    + "</span>").HeaderTemplate(" ");
 
            })
            .Sortable()
            .Pageable(=> a.PageSizes(true))
            .Filterable()
            .NoRecords("")
            .DataSource(
                        dataSource => dataSource
                        .Ajax()
                        .Model(model =>
                        {
                            model.Id(=> p.UserId);
                        })
                        .Read(read => read.Action("GetAllUsers""WebUser"))
                        .PageSize(10)
                        )
)
 
 
<div id="windowUser"></div>
 
<script type="text/javascript">
 
    $(document).ready(function () {
         $("#windowUser").kendoWindow({
            title: "User Info",
            modal: true,
            resizable: false,
            visible: false,
            width: "30%",
            actions: ["Close"],
            close: function (e) {
            }
        });
    });
 
    function ViewUser(userId) {
 
        //Construct url for GetUserInfo action from WebUser Controller
        var urlGetUserInfo = '@Url.Action("GetUserInfo""WebUser")';
 
        //Make an AJAX call to send UserId to the above action and retreive UserInfo object containing data returned by the action.
        $.getJSON(urlGetUserInfo, { UserId: userId }, function (userInfo) {
 
            //Check User Info for no data 
            if (userInfo != null) {
                //Pass the User Info object to partUserInfoView (Partial View) and load it under the empty div "windowUser" we created earlier
                $("#windowUser").load("partUserInfoView", { user: userInfo });
            }
         });
 
        //Get the ref for kendo ui modal window object for windowUser
        var windowUser = $("#windowUser").data("kendoWindow");
        
        //Open the modal popup and position it to the center of the screen
        windowUser.center().open();
    }
 
</script>

Step 9: Going back to our controller, right click on partUserInfoView(WebUser user)” and click “Add View” to create partial view.

Step 10: Under partUserInfoView.cshtml, I am simply putting in markup to show a couple of labels rendering user info as shown below:
@model MVCBasics.Models.WebUser
 
<p><b>@Html.LabelFor(=> a.UserId) : </b>@Html.ValueFor(a => a.UserId)</p>
<p><b>@Html.LabelFor(=> a.FName) : </b>@Html.ValueFor(a => a.FName)</p>
<p><b>@Html.LabelFor(=> a.MName) : </b>@Html.ValueFor(a => a.MName)</p>
<p><b>@Html.LabelFor(=> a.LName) : </b>@Html.ValueFor(a => a.LName)</p>
<p><b>@Html.LabelFor(=> a.UserName) : </b>@Html.ValueFor(a => a.UserName)</p>

Finally run your website to get “Index” page showing a list of users in Kendo UI Grid as shown:



Click on a view button to get user’s information in modal popup: