Fill child grid from parent on Edit event (new)

6 posts, 0 answers
  1. Zoinky
    Zoinky avatar
    45 posts
    Member since:
    Sep 2007

    Posted 10 Jan 2014 Link to this post

    I have a nested grid that when I am adding a new child, I would like  the input for the new child to be filled based on a column from the parent.
    Basically I need to get reference to the data object for the parent of the child. I am not sure how to traverse the node structure to go all the way to the parent and get a column. (2 input columns and a mulltiselect column),

    the edit event has the following according to the docs

    http://docs.kendoui.com/api/web/grid#events-edit
  2. Alexander Popov
    Admin
    Alexander Popov avatar
    1416 posts

    Posted 13 Jan 2014 Link to this post

    Hello,

    I would recommend using the following approach:
    1. Specify an ID in the parent Grid's DataSource schema.model 
    2. Use the parent's ID as a default value for the child's id field 
    3. Once the edit event is triggered use the id to get the parent item  
    4. Set the new field values based on its parent 

    For convenience I prepared this example - I hope it helps.

    Regards,
    Alexander Popov
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  3. UI for ASP.NET MVC is VS 2017 Ready
  4. Zoinky
    Zoinky avatar
    45 posts
    Member since:
    Sep 2007

    Posted 13 Jan 2014 Link to this post

    could i get a working example in MVC razor, i tried doing what you said but i am getting parentGrid.dataSource as undefined, as well as e.model.RoomTypeID to be null, below is my code, also in the example could you add the following please and thank you

    1. set a multiselect values from parent item to child
    2. I have property on roomType (which are parent items, when binding i want this parameter to be passed on each create) called uniqueID, i would like this ID to be passed to the controller every time a new item is saved, however as you can see i have  on the create method
    or is there a prefered way of having a uniqueID passed to create items, (this will be like a username) that all roomtypes created will belong to that id, which is passed to the view that has these grids through form submit, but when binding rooms I just make uniqueID property of the item so its easier to bind to grid however blanks are passed oncreate

                .Create(create => create.Action("AddRoomType", "Property", new { uniqueID = "=#UniqueID#" }).Data("serialize"))
    but blank is passed.



    <script type="text/kendo" id="territoriesTemplate">
        <ul>
            #for(var i = 0; i< data.length; i++){#
            <li>#:data[i].text#</li>
            #}#
        </ul>
    </script>

    <script type="text/javascript">
        var territoriesTemplate = kendo.template($("#territoriesTemplate").html(), { useWithBlock: false });
    </script>
    @(Html.Kendo().Grid<RoomTypeModel>()
            .Name("gridRoomTypes")
            .Columns(columns =>
            {
                columns.Bound(e => e.Description).Width(250);
                columns.Bound(e => e.Rate).Width(120);
                columns.Bound(e => e.WeekendRate).Width(120);
                columns.Bound(e => e.AmenityList).ClientTemplate("#=territoriesTemplate(AmenityList)#");
                columns.Command(command =>
                {
                    command.Edit();
                    command.Destroy();
                }).Width(185);

            })
            .DataSource(dataSource => dataSource
                .Ajax()
                .Read(read => read.Action("LoadRoomTypes", "Property"))
                .Update(update => update.Action("UpdateRoomType", "Property").Data("serialize"))
                .Destroy(destroy => destroy.Action("DeleteRoomType", "Property"))
                .Create(create => create.Action("AddRoomType", "Property", new { uniqueID = "=#UniqueID#" }).Data("serialize"))
                .Model(model =>
                {
                    model.Id(m => m.RoomTypeID);
                    model.Field(e => e.AmenityList).DefaultValue(new List<AmenityItem>());

                })
            )
            .Events(events =>
                {

                    events.DataBound("gridDataBound");
                })
            .ToolBar(commands =>
            {

                commands.Create().Text("Add new room type");
            })
            .Sortable()

            .ClientDetailTemplateId("template")
    )

    <script id="template" type="text/kendo-tmpl">
        @(Html.Kendo().Grid<RoomModel>()
            .Name("gridRooms#=RoomTypeID#")
            .Columns(columns =>
            {
                columns.Bound(e => e.Description).Width(250);
                columns.Bound(e => e.Rate).Width(120);
                columns.Bound(e => e.WeekendRate).Width(120);
                columns.Bound(e => e.AmenityList).ClientTemplate("\\#=territoriesTemplate(AmenityList)\\#");
                columns.Command(command =>
                {
                    command.Edit();
                    command.Destroy();
                }).Width(185);
            })
            .DataSource(dataSource => dataSource
                .Ajax()
                .Read(read => read.Action("LoadRooms", "Property", new { roomTypeID = "#=RoomTypeID#" }))
                .Update(update => update.Action("UpdateRoom", "Property").Data("serialize"))
                .Destroy(destroy => destroy.Action("DeleteRoom", "Property"))
                .Create(create => create.Action("AddRoom", "Property", new { roomTypeID = "#=RoomTypeID#" }).Data("serialize"))
                .Model(model =>
                {
                    model.Id(m => m.RoomID);
                    model.Field(e => e.AmenityList).DefaultValue(new List<AmenityItem>());
                })
            )

            .ToolBar(commands =>
            {
                commands.Create().Text("Add new room");
            })
                     .Events(events =>
                        {
                            events.Edit("gridEdit");

                        })
            .Sortable()
            .ToClientTemplate()
        )
    </script>

    <script>
        function gridEdit(e) {

            if (e.model.isNew()) {
                var parentGrid = $("#gridRoomTypes").kendoGrid();
                debugger;

                var parentItem = parentGrid.dataSource.get(e.model.RoomTypeID);
                e.model.set("Rate", parentItem.Rate);
            }
        }
        function gridDataBound() {
            this.expandRow(this.tbody.find("tr.k-master-row").first());
        }
    </script>

    <script type="text/javascript">

        function serialize(data) {
            // debugger;
            for (var property in data) {
                if ($.isArray(data[property])) {
                    serializeArray(property, data[property], data);
                }
            }
        }

        function serializeArray(prefix, array, result) {
            for (var i = 0; i < array.length; i++) {
                if ($.isPlainObject(array[i])) {
                    for (var property in array[i]) {
                        result[prefix + "[" + i + "]." + property] = array[i][property];
                    }
                }
                else {
                    result[prefix + "[" + i + "]"] = array[i];
                }
            }
        }
    </script>
  5. Alexander Popov
    Admin
    Alexander Popov avatar
    1416 posts

    Posted 15 Jan 2014 Link to this post

    Hello again,

    In case you want to populate certain field only when adding new items I would suggest using Model fields' DefaultValue, for example: 
    .Model(model =>
    {
        model.Id(m => m.RoomID);
        model.Field(e => e.AmenityList).DefaultValue(new List<AmenityItem>());
        model.Field(e => e.Rate).DefaultValue('#=Rate#');
    })
    Getting the parent Grid's instance properly will solve the undefined issue, for example:  
    var parentGrid = $("#gridRoomTypes").data("kendoGrid");
    In case you would like to access the parent item values in the child Grid's edit event handler, you could do so by defining the function in the template. For example:  
    .Events(e=>e.Edit(@<text>function(){alert("#=RoomTypeID#")}</text>))
    That approach would also allow you to populate a field that has a Multiselect widget for an editor.

    Regarding your last question - the way you are trying to pass the uniqueID will work only in a template, so I would recommend using the Data method. For example: 
    .Create(create => create.Action("AddRoom", "Property"}).Data("onCreate"))
     
    <script type="text/javascript">
        function onCreate(data) {
            var uid = 123; //get the unique id from somewhere
            return {uniqueID: uid}
        }
    </script>
    On a side note, I would like to remind you that as a general practice it is accepted to ask different questions in separate support threads. 

    Regards,
    Alexander Popov
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  6. Ezequiel
    Ezequiel avatar
    36 posts
    Member since:
    Oct 2011

    Posted 13 Oct 2015 in reply to Alexander Popov Link to this post

    Hi Alexander.

     

    I'm trying but if I do this:

     

    1..Model(m =>
    2.{
    3.m.Id(id => id.Id);
    4.m.Field(f => f.Weight).Editable(false);
    5.m.Field(f => f.MasterId).DefaultValue('#=MasterId#');
    6.})

     my code keeps returning error saying that 'Too many characters in character literal'

    if I change to quotes

     

    1..Model(m =>
    2.{
    3.m.Id(id => id.Id);
    4.m.Field(f => f.Weight).Editable(false);
    5.m.Field(f => f.MasterId).DefaultValue("#=MasterId#");
    6.})

    I get the error on run time:

    System.ArgumentException: Object of type 'System.String' cannot be converted to type 'System.Int32'

     if I try this:

    1.m.Field(f => f.MasterId).DefaultValue(Convert.ToInt32("#=MasterId#"));
    I get this error on run time:

    System.FormatException: Input string was not in a correct format.

     MasterId is an int property in both classes.

     

    Thanks,

    Ezequiel

     ​

     

     

  7. Alexander Popov
    Admin
    Alexander Popov avatar
    1416 posts

    Posted 15 Oct 2015 Link to this post

    Hello Ezequiel,

    I am afraid this approach would not work in case the targeted field is not of type string. This is expected due to the strongly typed nature of C#. Converting the string to int would also not work, as the conversion is performed on the server, however the template is actually executed on the client. In the current scenario I would suggest using the detail Grid's edit event handler to add the value if the model is new.

    Regards,
    Alexander Popov
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top
UI for ASP.NET MVC is VS 2017 Ready