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:




No comments:

Post a Comment