Kendo UI window – A modal dialog with Kendo Grid, MVC controller action, Partial View and AJAX calls to refresh data

Posted: December 12, 2014 in All, ASP.Net MVC
Tags: , , , , , , ,

Introduction:

In this article I would like to discuss about displaying a modal dialog or popup using Kendo UI Window.  There are tons of articles on net on similar topic, however here I would like to do it using ASP.Net MVC so we use MVC partial view to render contents on Kendo Window.  We also use Kendo Grid to populate the data dynamically.   We would also cover how to refresh the Grid data using AJAX calls and how to pass a MVC model from Java script/client to MVC server controller action.

Here are the things we would like to do for the demo purposes:

Displaying a search button on a view.  Upon clicking on search button, a modal dialog will be displayed with two input fields for First and Last Names.  When user clicks on Search button after entering the data in the text boxes, we would display matching records in a grid on the same window.

Capture3

Install Kendo UI

First step to install Kendo UI.  Follow the steps as mentioned in below article:

http://docs.telerik.com/kendo-ui/aspnet-mvc/asp-net-mvc-5

Note: The above instructions talk about installing Kendo UI separately and then integrating it with our application.  If you had installed Kendo UI code using Nuget package and then used Telerik upgrade wizard visual studio extension to upgrade to professional version then you may have to do couple of changes in BundleConfig.cs to work Kendo UI properly.

bundles.Add(new ScriptBundle("~/bundles/kendo").Include(
			"~/Scripts/kendo/2014.3.1119/kendo.all.min.js",
				// "~/Scripts/kendo/kendo.timezones.min.js", // uncomment if using the Scheduler
			"~/Scripts/kendo/2014.3.1119/kendo.aspnetmvc.min.js"));

bundles.Add(new StyleBundle("~/Content/kendo/2014.3.1119/css").Include(
			"~/Content/kendo/2014.3.1119/kendo.common-bootstrap.min.css",
			"~/Content/kendo/2014.3.1119/kendo.bootstrap.min.css"));

Observe that there is a version number folder2014.3.11 in the path.  This is basically the kendo UI version you had installed.  Make sure to add correct version number and path.

Kendo Window

We use Kendo HtmlHelper extension for creating the modal window.  The kendo window is assigned with a name “window” and with a caption “Search Names”.   We use LoadContentFrom method to load the contents by calling MVC controller action.  The first parameter is action name and the second one is controller name.  We also set Modal as true so that the dialog would be a modal dialog.  HtmlAttributes method is used for styling purposes.   An OnClose event handler is attached to the window.   Here is the code snippet:

<div id="UserForm">
    <span id="SearchButton" class="k-button">Search Names</span>
</div>

<div >
    @(Html.Kendo().Window()
          .Name("window")
          .Title("Search Names")
          .LoadContentFrom("Search", "Home")
          .Draggable()
          .Actions(actions => actions.Close())
          .Modal(true).Visible(false)
          .HtmlAttributes(new { style = "margin: 10px" })
          .Events(ev => ev.Close("onClose"))
          )
</div>

We also need to add a reference to Kendo MVC UI.

@using Kendo.Mvc.UI

In java script, subscribe to search button click event handler.   Inside click method open kendo window and place it in the center.   We have also added kendoValidation so that we can validate model state before opening modal window.

<script>
    $(document).ready(function () {
        var validator = $("#UserForm").kendoValidator().data("kendoValidator");

        $("#SearchButton").bind("click", function () {

            if (validator.validate()) {
                $("#window").data("kendoWindow").open().center(true);
            }
        });
    });
</script>

In the Controller, add an action for Search functionality.  Define a class called UserDetails with First Name and Last Name fields.  Add a partial view with UserDetails model and select “Create Scaffold template” option to display First Name and Last Name fields.

[HttpGet]
public ActionResult Search()
{
	return PartialView();
}

public class UserDetails
{
	public string FirstName { get; set; }

	public string LastName { get; set; }
}

The Serach partial view code looks like below:

@using ExchangeAdda.Models
@model ExchangeAdda.Models.UserDetails

@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()
    
    <div class="form-horizontal">
        <h4>UserDetails</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.LastName, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input id ="FindBtn" type="submit" value="Search" class="btn btn-default" />
            </div>
        </div>
    </div>
}

Kendo Grid

Now we need add a kendo grid to the Search view which displays the search results.  Bind the Grid to UserDetails model and add columns for First and Last names.

<div>
    <div>
        @(Html.Kendo().Grid<UserDetails>()
              .Name("AssociateSearch")
              .HtmlAttributes(new { style = "max-height: 50px; border:0px" })
              .Columns(columns =>
              {
                  columns.Bound(x => x.FirstName);
                  columns.Bound(x => x.LastName);
              })
              .Selectable()
              .Resizable(resizing => resizing.Columns(true))
              .DataSource(dataSource => dataSource
                  .Ajax())
        )

    </div>
</div>

Now, add a click event in java script to make an AJAX request to load the data.  Here, we are creating client side model which is equal to server side UserDetails model.  The properties are populated using document getElementById method.  Specify the action name as Url.  Make sure to add content type as application/json.  The data parameter is assigned with earlier created model.  Add an event handler for success and refresh grid data upon success.

<script>
    $('#FindBtn').click(function (e) {
        e.preventDefault();
        var UserDetails =
        {
            "FirstName": document.getElementById('FirstName').value,
            "LastName": document.getElementById('LastName').value,
        };
        $.ajax({
            url: "SearchJsonRequest",
            type: 'POST',
            contentType: "application/json;charset=utf-8",
            data: JSON.stringify(UserDetails),
            dataType: "json",
            success: function (data) {
                var grid = $('#AssociateSearch').getKendoGrid();
                grid.dataSource.data(data);
                grid.refresh();
            }
        });
        return false;
    });
</script>

The final step is to add an action in the controller for search functionality. I have added some dummy data to create a collection and return to the client for demo purpose. In reality there might be another service/BLL/DB call to fetch data based on search criteria.  The important thing to note is the method should return JsonResult.  The method accepts the UserDetails model data which is a better way for passing data from client to server.

[HttpPost]
public JsonResult SearchJsonRequest(UserDetails details)
{
	//Implement your search logic here

	var list = new List<UserDetails>()
	{
		new UserDetails{ FirstName = "Test 1 First Name", LastName = "Test 1 Last Name" },
		new UserDetails{ FirstName = "Test 2 First Name", LastName = "Test 2 Last Name" },
		new UserDetails{ FirstName = "Test 3 First Name", LastName = "Test 3 Last Name" },
	};

	return Json(list);
}

Advertisements
Comments
  1. german says:

    can you bring the source code? I´ve trying to do the same, but a create view page

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s