Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Telerik MVC Grid Master Detail Cascading Dropdowns

I am using a master-detail Telerik MVC Grid on two levels.

  • The first level contains a drop-down of Customers and some misc data.
  • The second level contains a drop-down of Cars that are linked to the customer on the first level and some misc data.

I am now using a foreign key column to show the dropdowns of cars and clients. How can the second dropdown be filtered by the customer on the first level?

Code:

@(Html.Telerik().Grid<Models.ClientsModel>()
        .Name("Grid")
        .ToolBar(commands => commands.Insert().ButtonType(GridButtonType.ImageAndText))
        .DataKeys(keys => keys.Add(c => c.ClientLineID))
        .Columns(columns =>
        {
            columns.ForeignKey(o => o.ClientID, (System.Collections.IEnumerable)ViewBag.Client, "ClientID", "Name")
                                                   .Width(330)
                                                   .Title("Client");
            columns.Command(commands =>
                {
                    commands.Edit().ButtonType(GridButtonType.ImageAndText);
                    commands.Delete().ButtonType(GridButtonType.ImageAndText);
                }).Width(250);
        })
        .DetailView(car => car.ClientTemplate(

            Html.Telerik().Grid<Delta.Models.CarModel>()
                        .Name("Car_<#= ClientID #>")
                        .DataKeys(keys => keys.Add(c => c.LineID))
                        .ToolBar(commands => commands.Insert().ButtonType(GridButtonType.ImageAndText))
                        .DataBinding(dataBinding =>
                        {
                            dataBinding.Ajax()
                                .Select("_CarLineIndex", "Client", new { id = "<#= ClientID #>" })
                                .Insert("_CarLineCreate", "Client", new { id = "<#= ClientID #>" })
                                .Update("_CarLineUpdate", "Client")
                                .Delete("_CarLineDelete", "Client");
                        })
                        .Columns(columns =>
                                {
                                    columns.ForeignKey(o => o.CarID, (System.Collections.IEnumerable)ViewBag.Cars,
                                    "CarID", "No")
                                                   .Width(500)
                                                   .Title("Car");
                                    columns.Command(commands =>
                                    {
                                        commands.Edit().ButtonType(GridButtonType.ImageAndText);
                                        commands.Delete().ButtonType(GridButtonType.ImageAndText);
                                    }).Width(200);
                                })
                        .Editable(editing => editing => editing.Mode(GridEditMode.InLine))
                        .Scrollable(c => c.Height("auto"))
                        .Resizable(resizing => resizing.Columns(true))
                        .Reorderable(reorder => reorder.Columns(true))
                        .KeyboardNavigation()
                        .Footer(false)
                        .ToHtmlString()
            ))
        .DataBinding(dataBinding =>
        {
            dataBinding.Ajax()
                .Select("_ClientIndex", "Client")
                .Insert("_ClientCreate", "Client")
                .Update("_ClientUpdate", "Client")
                .Delete("_ClientDelete", "Client");
        })
        .Scrollable(c => c.Height("auto"))
        .Editable(editing => editing.Mode(GridEditMode.InLine))
        .Pageable(o => o.PageSize(50))
        .Filterable()
        .KeyboardNavigation()
        .Groupable())

I am thinking that the code might involve some javascript on the OnDetailViewExpand event, but I can't figure out what. The only solution I have now is to split the grid into separate views and build cascasing comboboxes there.

like image 524
Ovi Avatar asked Nov 03 '22 23:11

Ovi


1 Answers

Unfortunately I cannot comment on posts yet to clarify some facts about your question. I'll make some assumptions in my answer so that we can work out the exact nature of the problem. You have two model classes one for each grid ClientsModel and CarModel. You are filtering the CarModel (second)grid with fields from the ClientsModel (first)grid.

You are not restricted to just one(<= ClientID =>) parameter in your select binding. You can use other fields from the ClientsModel class the same way as ClientID.

Sample Code:

dataBinding.Ajax().Select("_CarLineIndex", "Client", new { id = "<#= ClientID #>", city = "<#= City #>" })

Here is a working example with mock data that illustrates the method mentioned above:

Client Class

public class Client
{
    public int ClientId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string City { get; set; }
}

Car Class

public class Car
{
    public string Make { get; set; }
    public string Model { get; set; }
    public int Year { get; set; }
    public string Color { get; set; }
}

HomeController

[GridAction]
public ActionResult _Index()
{
    Client c1 = new Client() { ClientId = 1, City = "Boston", FirstName = "Ted", LastName = "Boder" };
    Client c2 = new Client() { ClientId = 2, City = "New York", FirstName = "Chris", LastName = "Tobb" };
    Client[] clients = {c1, c2};
    return View(new GridModel(clients));
}

[GridAction]
public ActionResult _Cars(int ClientId, string City)
{
    Car c1 = new Car() { Color = "Yellow", Make = "Ford", Model = "Mustang", Year = 2012 };
    Car c2 = new Car() { Color = "Black", Make = "Toyota", Model = "Camry", Year = 2010 };
    Car[] cars = { c1, c2 };
    return View(new GridModel(cars));
}

View

@(Html.Telerik().Grid<Client>()
    .Name("Clients")
    .Columns(columns =>
    {
        columns.Bound(o => o.FirstName);
        columns.Bound(o => o.LastName);
        columns.Bound(o => o.City);
    })
    .DetailView(clientDetailView => clientDetailView.ClientTemplate(
         Html.Telerik().Grid<Car>()
         .Name("ClientDetails_<#= ClientId #>")
         .Columns(columns =>
         {
             columns.Bound(c => c.Make);
             columns.Bound(c => c.Model);
             columns.Bound(c => c.Year);
             columns.Bound(c => c.Color);
          })
          .DataBinding(db2 => db2.Ajax().Select("_Cars", "Home", new { ClientID = "<#= ClientId #>", City = "<#= City #>" }))
          .Pageable()
          .Sortable()
          .ToHtmlString()
    ))
    .DataBinding(db1 => db1.Ajax().Select("_Index", "Home"))
    .Pageable()
    .Sortable()
    .Filterable()
)

As you can see from the example I'm also passing a City parameter as well as a ClientId when binding the grid.

Let me know if I missed something.

like image 137
Igorrious Avatar answered Nov 15 '22 05:11

Igorrious