This is a migrated thread and some comments may be shown as answers.

Kendo UI Grid Master Detail ForeignKey Column on Cascade to Master Id

4 Answers 369 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Taha
Top achievements
Rank 1
Taha asked on 25 Sep 2013, 02:07 PM
Hi,

I have a Master Detail Grid in Kendo UI

I want to add rows to Detail Grid with a Foriegn Key Column that is driven by Master Id, how do i accomplish this ?

I have highlighted the Foreign Key Column in bold

@(Html.Kendo().Grid<PackageModel>()
            .Name("RGrid")
            .Columns(col =>
            {
                col.Bound(c => c.Name).Visible(true);
                col.Bound(c => c.PackageName).Visible(true).Title("Package");                               
            })
            .DataSource(ds => ds
                .Ajax()
                .Events(e => e.RequestStart("onDataRequestStart"))
                .Model(m =>
                {
                    m.Id(c => c.OId);
                })
                .Read(read => read.Action("ReadPackages", "RGrid", new { area = "Recommendation", gridSettings = "##settings##" }))                
            )                        
            .ClientDetailTemplateId("recostemplate")
            .Navigatable()
            .Pageable(p => p.PageSizes(true))
            .Filterable()
            .Sortable()
            .Selectable(selectable => selectable.Mode(GridSelectionMode.Single))
        )



<script id="recostemplate" type="text/kendo-tmpl">
    @(Html.Kendo().Grid<SE.OrderBook.Web.Models.View.RecommendationModel>()
                .Name("RecosGrid#=Id#")
                .Columns(columns =>
                {
                    columns.Bound(o => o.Id).Title("Id").Visible(true);
                    columns.ForeignKey(o => o.DeliverableId, commonService.GetDeliverableDropList(), "Id", "Value");
                    columns.Bound(o => o.DeliverableName).Title("Deliverable").Visible(true);
                    columns.Bound(o => o.Included).Visible(true);
                    columns.Bound(o => o.ServiceStart).Format("{0:d}").Title("Service<br />Start");
                    columns.Bound(o => o.ServiceEnd).Format("{0:d}").Title("Service<br />End");                    
                    columns.Bound(o => o.Year1).Visible(true);
                    columns.Bound(o => o.Total).Visible(true);
                    columns.Bound(o => o.PackageId).Hidden(true);
                    columns.Command(cmd => { cmd.Edit().UpdateText("Save"); /*cmd.Destroy();*/ }).Visible(true).Width("10%");                    
                })
                .DataSource(ds => ds
                    .Ajax()
                    .PageSize(5)
                    .Model(m =>
                    {
                        m.Id(c => c.Id);
                        m.Field(c => c.PackageId).DefaultValue("#=Id#");
                    })
                    .Read(read => read.Action("Read", "Home", new { area = "Recommendation", id = "#=Id#" }))
                    .Create(update => update.Action("Create", "Recos", new { area = "Recommendation" }))
                    .Update(update => update.Action("Update", "Recos", new { area = "Recommendation" }))
                    .Destroy(delete => delete.Action("Delete", "Recos", new { area = "Recommendation" }))
                )
                .ToolBar(toolbar => { toolbar.Create(); })
                .Events(events =>
                {
                    events.Edit("onRecoDetailsEdit");
                    events.Save("onRecoDetailsSave");
                })
                .Editable(e => e.Mode(GridEditMode.PopUp))
                .Pageable()
                .Sortable()
                .ToClientTemplate())
</script>


I need to pass package Id into commonService.GetDeliverableDropList() but i am not sure how to accomplish this?

I think solution to this is only possible at run time through AJAX, if particular than is there an example how i can populate foriegn key colum dropdown list through AJAX ?

Waiting for Response,

Kind Regards,




4 Answers, 1 is accepted

Sort by
0
Daniel
Telerik team
answered on 27 Sep 2013, 11:46 AM
Hello,

The template expression will be evaluated on the client so the strongly typed expression overload of the DefaultValue method cannot be used unless the field is a string. You could use the overload that accepts the field name and type if the field is not a string:

m.Field("PackageId", typeof(int)).DefaultValue("#=Id#");
Regards,
Daniel
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Taha
Top achievements
Rank 1
answered on 27 Sep 2013, 12:05 PM
Hi,

Thanks for your reply,

I want to populate Deliverable Foreign Key Column on client side using Package Id how cam accomplish this ?

///Set default DropListItem to "Please Select"
        function onRecoDetailsEdit(e) {
               var packageId = e.grid.datasource.package Id
               
               var deliverables = $.ajax({
                type: "POST",
                url: '@Url.Action("GetDeliverables", "Home" })/' + packageId,

                success: function (response) {
                           // deliverables foreign key dropdown population  
                },
                
            });
   
         }
0
Daniel
Telerik team
answered on 30 Sep 2013, 06:13 PM
Hello again,

Sorry, I missed that the question was about populating the dropdownlist data based on the ID. The foreignkey column data can be set only on initialization so I can suggest to pass all the items initially and filter the dropdownlist data. With the approach that you are currently using you can get the ID from the row model if available in your scenario:

function onRecoDetailsEdit(e) {
    var packageId = e.model.PackageIdField;
or from the master row model:
function onRecoDetailsEdit(e) {
  var masterRow = this.element.closest(".k-detail-row").prev(),
      masterGrid = masterRow.closest("[data-role=grid]").data("kendoGrid"),
      item = masterGrid.dataItem(masterRow),
      packageId = item.MasterPackageIdField;
The data can be set to the dropdownlist after the requests has completed by using its dataSource data method:
success: function (response) {
      $("#DeliverableId").data("kendoDropDownList").dataSource.data(response);
},
Alternative approaches are to include the packageId field in the dropdownlist data and use the dataSource filter method in the edit event to filter the data on the client or configure the dropdownlist in the editor for remote binding and pass the ID as additional data.

Regards,
Daniel
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Accepted
Taha
Top achievements
Rank 1
answered on 01 Oct 2013, 07:55 AM
Hi, 

Thanks for your reply,

I have devised a solution based on first approach of filtering, deliverables for the package are stored in additional field as comma seprated string,  for any one interested here is the solution

Not the best of solution but works, initial go before improving with a more robust solution

///Set default DropListItem to "Please Select"
        function onRecoDetailsEdit(e) {
             $(".k-edit-form-container [data-role=dropdownlist]").each(function (index) {
                var ddl = $(this).data("kendoDropDownList");                
                // limit to package only
                if (ddl && this.id == "DeliverableId") {
                    var deliverables = e.model.PackageDeliverables.split(',');
                    var filterDeliverables = [];
                    // filter deliverables on package deliverables
                    for(var idx = 0; idx < deliverables.length; idx = idx + 1) {   //alert(parseInt(deliverables[idx]));
                        filterDeliverables.push({ "field": "Value", "operator": "eq", "value": deliverables[idx] });
                    }
                    var filtersString = {};
                    if (deliverables.length > 1)
                        filtersString = { "filters": filterDeliverables, "logic": "or" };
                    else
                        filtersString = filterDeliverables;
                    ddl.dataSource.filter(filtersString);
                    ddl.refresh();
                }
            });

            
        }
Tags
Grid
Asked by
Taha
Top achievements
Rank 1
Answers by
Daniel
Telerik team
Taha
Top achievements
Rank 1
Share this question
or