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

Fill child grid from parent on Edit event (new)

5 Answers 1111 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Zoinky
Top achievements
Rank 1
Zoinky asked on 10 Jan 2014, 06:03 PM
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

5 Answers, 1 is accepted

Sort by
0
Alexander Popov
Telerik team
answered on 13 Jan 2014, 02:50 PM
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!
0
Zoinky
Top achievements
Rank 1
answered on 13 Jan 2014, 03:29 PM
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>
0
Alexander Popov
Telerik team
answered on 15 Jan 2014, 02:18 PM
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!
0
Ezequiel
Top achievements
Rank 2
answered on 13 Oct 2015, 02:34 PM

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

 â€‹

 

 

0
Alexander Popov
Telerik team
answered on 15 Oct 2015, 08:42 AM
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
Tags
Grid
Asked by
Zoinky
Top achievements
Rank 1
Answers by
Alexander Popov
Telerik team
Zoinky
Top achievements
Rank 1
Ezequiel
Top achievements
Rank 2
Share this question
or