Custom foreign key editor not updating the Grid

2 posts, 0 answers
  1. Antonino
    Antonino avatar
    2 posts
    Member since:
    Oct 2019

    Posted 12 Nov 2019 Link to this post

    Hello,

    We have a Grid in which one of the fields - CategoryId - is a foreign key. Using the normal .ForeignKey(…) method works but it is not enough for this particular situation as the data do be displayed inside has a hierarchy to it.

    We are trying to, by means of a custom editor template, display that field as a DropDownTree.


    The contents of the DropDownTree are also dependant on another foreign key - SchemeId - which is filtered inside the editor template's DataSource.Read method.

    All of this works in terms of actually selecting the item in the DropDownTree - however the value is not stored / or is just stored on certain situations. i.e, as you select other column this one remains blank (no red triangle on corner).


    I should also point out that we are using the Grid in "InCell" edit mode and have the .Batch mode set to true (event though the same happens if it's not in Batch mode).


    I have tried many things, including tapping on to certain events and setting the dirty fileds property in the grid's data but with no success (also not sure if I should be meddling with it).



    How should we go about doing this?


    To make things more clear,  here are the contents of the files in question:



    Contents of Views\Items\List.cshtml
     
    @using Project.Web.Models
    @model ItemListViewModel
    @(Html.Kendo()
        .Grid<ListItem>(Model.Items)
        .Name("itemsGrid")
        .Columns(columns =>
        {
            columns.ForeignKey(i => i.SchemeId, Model.SchemesList, "Value", "Text").Filterable(ftb => ftb.Multi(true).Search(true));
            columns.ForeignKey(i => i.CategoryId, Model.Categories, "CategoryId", "Name")
                .EditorViewData(new { Categories = Model.Categories })
                .EditorTemplateName("CategoryDropdown").Filterable(ftb => ftb.Multi(true).Search(true));
            columns.Bound(i => i.Value);
            columns.Bound(i => i.Date).Title("Date").Format("{0:MM/yyyy}").Sortable(true).EditorTemplateName("CustomMonthPicker").Filterable(ftb => ftb.Multi(true).Search(true));
            columns.Command(command => { command.Destroy(); });
        })
        .ToolBar(toolbar => { toolbar.Create(); toolbar.Save(); })
        .Editable(editable => editable.Mode(GridEditMode.InCell))
        .DataSource(dataSource =>
            dataSource.Ajax()
            .Batch(true)
            .Model(model =>
            {
                model.Id(a => a.Key);
            })
            .Create(create => create.Action("SaveItems", "AssetData"))
            .Read(read => read.Action("ReadItems", "AssetData"))
            .Update(update => update.Action("SaveItems", "AssetData"))
            .Destroy(destroy => destroy.Action("DeleteItems", "AssetData"))
        )
    )
    <script>
        function filterCategories() {
            var grid = $("#itemsGrid").data("kendoGrid");
            
            var dataItem = grid.dataItem(grid.tbody.find("tr:has(.k-edit-cell)"));
            return {
                schemeId: dataItem.SchemeId
            };
        }
    </script>
     


    -----


    Contents of Views\Shared\EditorTemplates\CategoryDropdown.cshtml 


    @using Kendo.Mvc.UI;
    @model object
    @(Html.Kendo().DropDownTreeFor(m => m)
        .ValuePrimitive(true)
        .Filter("contains")
        .DataTextField("Text")
        .DataValueField("Value")
        .DataSource(dataSource =>
        {
            dataSource.Model(m => m.HasChildren("HasChildren").Children("Items"));
            dataSource.Read(read => read.Action("GetSchemeCategories", "Category").Data("filterCategories"));
        })
    )
     


    ----


    Thanks!
  2. Alex Hajigeorgieva
    Admin
    Alex Hajigeorgieva avatar
    1081 posts

    Posted 14 Nov 2019 Link to this post

    Hi, Antonio,

    I have already responded to you in the private thread that you have submitted but I will paste my response here in case anyone elese is looking or the same information.

    The reason for this behaviour is the lack of a valueMapper function. We have an issue logged that requests its implementation  and I have now increased its priority to the maximum possible level:

    https://github.com/telerik/kendo-ui-core/issues/4468

    In the context of the Kendo UI Grid, you could use the CellClose event to set the value to a new object that will map with the expected structure.
    // proposed workaround rom the issue while this is getting implemented
    function onCellClose(e) {
            var headerIndex = $("#grid th[data-field='Organization']").index(); // get the index of the header cell
              
            if (e.container.index() == headerIndex) { // execute the logic if the edited cell is in the Organization column
                var treeView = e.container.find("[data-role='dropdowntree']").getKendoDropDownTree().treeview; // get a reference to the internal TreeView widget
                var selectedRow = treeView.select(); // get the selected item
                var dataItem = treeView.dataItem(selectedRow); // get the selected data item
                var customObject = { id: dataItem.value, text: dataItem.text, hasChildren: dataItem.hasChildren }; // compose the custom object
     
                var gridRow = e.container.closest("tr"); // get a reference to the current row
                var gridDataItem = $("#grid").getKendoGrid().dataItem(gridRow); // get a reference to the data item of the row
                gridDataItem.set("Organization", customObject) // set the field to be the custom object
            }
        }

    Kind Regards,
    Alex Hajigeorgieva
    Progress Telerik

    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Back to Top