Search code examples
asp.net-mvckendo-uikendo-gridkendo-asp.net-mvc

How to open a modal using Kendo UI grid that has a list inside it


I am using Kendo UI in my asp.net mvc project.

I have an issue for displaying modal. In my grid, I want to add an extra column that has a button in it.

When the user clicks that button, I need to show a list from another table that has the ID of the current table, and show it in modal.

I would really appreciate if you could help me.

@(Html.Kendo().Grid<ClinicManagement.Models.Reagent>().Name("PersonGrid")
                            .Name("PersonGrid")
                            .Columns(columns =>
                            {
                                columns.Bound(p => p.Name).Filterable(ftb => ftb.Cell(cell => cell.Operator("contains").SuggestionOperator(FilterType.Contains))).Width(90);
                                columns.Bound(p => p.Family).Filterable(ftb => ftb.Cell(cell => cell.Operator("contains").SuggestionOperator(FilterType.Contains))).Width(90);
                                columns.Bound(p => p.CardNumber).Filterable(ftb => ftb.Cell(cell => cell.Operator("contains").SuggestionOperator(FilterType.Contains))).Width(90);
                                columns.Command(command => command.Custom("ViewDetails").Click("showDetails")).Width(150);
                            })
                           .DataSource(dataSource => dataSource
                               .Ajax()
                               .PageSize(20)
                               .Events(events => events.Error("error_handler"))
                               .Sort(sort => sort.Add(p => p.Name).Ascending())
                               .Model(model => model.Id(p => p.Id))
                               .Create(update => update.Action("Create", "Reagents"))
                               .Read(read => read.Action("ReadReagent", "Reagents"))
                               .Update(update => update.Action("Edit", "Reagents"))
                               .Destroy(destroy => destroy.Action("Delete", "Reagents"))
                  ))

Solution

  • OK, your code looks similar to the demo here. You just need to finish it up:

    First, create a modal on the page:

    @(Html.Kendo().Window().Name("Details")
        .Title("Customer Details")
        .Visible(false)
        .Modal(true)
        .Draggable(true)
        .Width(300)       
    )
    

    The sample uses a kendo template to display the details, so you could add a kendo list in there (you would need to use .ToHtmlString() since it is a nested control). I prefer a different approach where I can use a partial view with a view model:

    Create a view model with the list items and other properties to display:

    public class DetailsViewModel
    {
        public int PersonId { get; set; }
        public string Name { get; set; }
        ... etc
        public List<string> MyListItems;
    }
    

    Create a partial view for the details with a list (or grid) on it:

    @model DetailsViewModel
    <div>
    ... // Show fields, etc.
    @(Html.Kendo().ListBox()
        ... other list options
        .BindTo(Model.MyListItems)
        .Deferred()   // Need for nested control
    </div>
    

    Create a controller action to return the partial:

    public PartialViewResult GetDetailsView(int personId)
    {
        // fetch data
        // Fill the viewmodel 
        var vm = new DetailsViewModel
        {
            PersonId = data.PersonId,
            Name = data.Name,
            MyListItems = context.Items.Where(i => i.PersonId == personId).ToList()
        }
        return PartialView("_Details", vm);
    }
    

    The javascript code for the button click will open the window and tell it to load the partial view from controller action:

    <script type="text/javascript">
        function showDetails(personId) {
            var wnd = $("#Details").data("kendoWindow");
            wnd.refresh({
                url: '@Url.Action("GetDetailsView","Person", new { personId = "__personid__" })'
                            .replace("__personid__", personId )
                    });
            wnd.open();
        }
    </script>
    

    Finally, change the custom command to pass in the Id:

    .Click("showDetails(PersonId)")
    

    EDIT - or use a template for your button:

    columns.Template(t => { }).Width(150)
           .ClientTemplate(@"<a class='btn btn-info btn-xs' onclick="showDetails(PersonId)">Details</a>");