Reputation: 2750
I am using a master-detail Telerik MVC Grid on two levels.
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.
Upvotes: 5
Views: 2865
Reputation: 911
Nothing to complex, create client event onEdit, you can found sample on telerik demo, than after once created client write down dropedown selection change event code that will filter data for you car dropdown. to do this I would suggest you to call ajax and insert HTml for dropdown. If you have still doubt than let me know I will explain it in detail. If you you really find this answer best or appropriate please vote it.. it will help...
Upvotes: 0
Reputation: 1293
You are correct that you will need to do this with javascript, and it is a matter of being able to filter cars by customers. Telerik allows you to add additional parameters using the "e.data" argument for most of their controls. So for example if you wanted to filter a city list based on a select state the CSHTML would look like this:
<td valign="top">
@(Html.Telerik().DropDownListFor(m => m.State)
.Name("State")
.ClientEvents(events => events.OnChange("State_Change"))
.BindTo(new SelectList(Model.GetStates()))
.HtmlAttributes(new { style = string.Format("width:{0}px", 160) })
)
</td>
<td valign="top">
@(Html.Telerik().AutoCompleteFor(m => m.City)
.Name("City")
.Encode(false)
.ClientEvents(events => {
events.OnDataBinding("City_AutoComplete");
})
.DataBinding(a => a.Ajax().Select("CityList", "Location"))
.AutoFill(true)
.HighlightFirstMatch(true)
.HtmlAttributes(new { style = string.Format("height: 17px; width:{0}px", 250) })
)
</td>
The javascript would look like this:
function City_AutoComplete(e) {
//pass state as an additional parameter here to filter
//this would be your customer for cars list
e.data = $.extend({}, e.data, { state: $("#State").val() });
}
function State_Change(e) {
//reset when the parent list selection changes
$('#City').data('tAutoComplete').text('');
$('#City').data('tAutoComplete').value('');
}
Upvotes: 1
Reputation: 1618
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.
Upvotes: 1