pass Grid view model data to Editor template
1 Answer 1323 Views
Yuhua
Top achievements
Rank 1
Yuhua asked on 05 Jun 2013, 07:55 PM
I am trying to implement a Grid with a Dropdownlist as custom Editor Template. The list items in Dropdownlist should be based on value from Grid row.

My Grid is like this.

@(Html.Kendo().Grid<GridViewModel>()
                    .Name("grid-results")
                    .Sortable()
                    .Groupable()
                    .Columns(columns =>
                    {
                        columns.Bound(p => p.Id).Hidden().Groupable(false);
                        columns.Bound(p => p.Total)
                            .ClientFooterTemplate("Grand Total: #=kendo.toString(sum, 'C4')#")
                            .FooterHtmlAttributes(new { style = "font-weight:bold; text-align:right;" })
                            .HtmlAttributes(new { style = "text-align:right" });
                        columns.Bound(p => p.StatusId ).Title("Resolution Status")
                            .ClientTemplate("#=StatusName#")
============> .EditorViewData(new { statusId = "#=StatusId #" })
                            .EditorTemplateName("StatusList"); // file name
                        columns.Bound(p => p.User);
                    })
                    .Pageable(paging => paging
                      .Info(false)
                      .Input(true)
                      .Numeric(false)
                      .PageSizes(new Int32[] { 5, 10, 20 })
                      )
                    .Editable(editable =>
                    {
                        editable.Mode(GridEditMode.InCell);
                    })
                    .Resizable(configurator => configurator.Columns(true))
                    .DataSource(dataSource => dataSource
                        .Ajax()
                        .ServerOperation(true)
                        .Read(read =>
                        {
                            read.Action("GetResults", "Home").Data("onFilterSelection");
                        })
                        .PageSize(10)
                        .Model(model =>
                        {
                            model.Id(p => p.PoId);
                            model.Field(p => p.Total).Editable(false);
                            model.Field(p => p.StatusId ).Editable(true);
                            model.Field(p => p.User).Editable(false);
                        })
                        .Aggregates(aggregates =>
                        {
                            aggregates.Add(p => p.Total).Sum();
                        })
                    )
                )

editor template is like
@(Html.Kendo().DropDownList()
        .Name(ViewData.TemplateInfo.GetFullHtmlFieldName(string.Empty))
        .DataValueField("ListStatusId")
        .DataTextField("ListStatusName")
        .DataSource(dataSource =>
            {
                dataSource.Read(read =>
                    {
                        read.Action("GetStatusList", "Home", new { statusId = ViewData["statusId"] });
                    });
            })
)
Controller Action:
public JsonResult GetCustomizeResolutionStatusList(string statusId)
        {
            List<StatusModel> status = new List<StatusModel>();

           // code to get list of StatusModel based on statusId

            return status ;
        }
GridViewModel
public class GridViewModel
    {
        public int Id { get; set; }
        public decimal Total { get; set; }
        public short StatusId { get; set; }
        public string StatusName { get; set; }
        public string User{ get; set; }
}

StatusModel
public class StatusModel
    {
        public int ListStatusId { get; set; }
        public String ListStatusName { get; set; }
    }

I tried to use .EditorViewData(new { statusId = "#=StatusId #" }) to pass GridViewModel.StatusId to dropdownlist editor template. But it doesn't work.
I can't use Model.StatusId since the page level view model is different from Grid view model.
Can someone please help me with this?

Thanks.

1 Answer, 1 is accepted

Sort by
0
Vladimir Iliev
Telerik team
answered on 07 Jun 2013, 12:32 PM
Hi Yuhua,

 
Please note note that the editor templates are get from the server on Grid initialization (only once) - that why when the EditorTemplate is generated the passed "StatusID" is null. Possible solution to pass the current record ID to the editor is to use external JavaScript function: 

EditorTemplate: 

@model object
 
@(Html.Kendo().DropDownListFor(m => m)
    .DataValueField("ListStatusId")
    .DataTextField("ListStatusName")
    .DataSource(d =>
        //get the additional data using function in the main view
        d.Read(r => r.Action("GetStatusList", "Home").Data("getParentID()"))
     
    )
)

getParentID function: 
function getParentID() {
    var row = $(event.srcElement).closest("tr");
    var grid = $(event.srcElement).closest("[data-role=grid]").data("kendoGrid");
    var dataItem = grid.dataItem(row);
    //where the OrderID is the model ID
    return { statusId: dataItem.StatusId }
}
Kind Regards,
Vladimir Iliev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
I have tried this exactly as you have described and it doesn't work. The value of "grid" is null. I have a dropdownlist in a grid column and I'm trying to find a way to past the grid item's model Id to the method that populates the drop down list. I'm having a hard time believing there is no support for doing this fairly basic functionality.
- by
Bryan
Top achievements
Rank 1
on 14 Jul 2014, 03:37 AM
Hi Bryan,

As from the provided information is not clear for us what is the exact scenario that you have - could you please open new support thread / forum post and provide the following additional information:

  • Grid code
  • Grid Model definition
  • Custom EditorTemplate that is used

Regards,
Vladimir Iliev
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
- by
Vladimir Iliev
Telerik team
on 14 Jul 2014, 08:52 AM

where you declare getParentID ?

In some of grid events?

try to declare in in EditorTemplate, in View with grid - all wrong

- by
Dina
Top achievements
Rank 1
on 31 Mar 2017, 09:09 AM
Hi Dima,

My colleague has suggested declaring getParentID() as an external JavaScript function.

Could you try placing the function in a <script> tag above or below the Kendo UI Grid initialization in the Razor view?

<script>
function getParentID() {
  var row = $(event.srcElement).closest("tr");
  var grid = $(event.srcElement).closest("[data-role=grid]").data("kendoGrid");
  var dataItem = grid.dataItem(row);
  //where the OrderID is the model ID
  return { statusId: dataItem.StatusId }
}
</script>
 
@(Html.Kendo().Grid<GridViewModel>()
 <!––  grid declaration here ––>
)

Let me know how you get on.

Regards,
Alex Hajigeorgieva
Telerik by Progress
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data (charts) and form elements.
- by
Alex Hajigeorgieva
Telerik team
on 04 Apr 2017, 06:54 AM
event.srcElement I believe is non-standard and will not work in FireFox.
- by
Waz
Top achievements
Rank 1
on 18 Apr 2017, 04:26 AM
Hello Waz,

Thank you for noting that the event srcElement is non-standard.

Event.target should be the preferred option indeed:
https://developer.mozilla.org/en-US/docs/Web/API/Event/target

Kind Regards,
Alex Hajigeorgieva
Telerik by Progress
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data (charts) and form elements.
- by
Alex Hajigeorgieva
Telerik team
on 19 Apr 2017, 09:48 AM

For some reason grid.dataItem(row) in undefined in make case

<script>
    function getMeterId() {
        var row = $(event.target).closest("tr");
        var grid = $(event.target).closest("[data-role=grid]").data("kendoGrid");
        var dataItem = grid.dataItem(row);

        return { meterId: dataItem.MeterId }
    }
</script>

- by
Dina
Top achievements
Rank 1
on 26 Apr 2017, 12:48 AM
Hi Dima,

Could you console.log(row) and console.log(grid)?

To be able to help you with this, could you please provide more information - sample code for the templates, grid and data source configurations and possibly a dummy dataItem so I can review the project setup locally and make concrete suggestions?

Regards,
Alex Hajigeorgieva
Telerik by Progress
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data (charts) and form elements.
- by
Alex Hajigeorgieva
Telerik team
on 27 Apr 2017, 12:05 PM

Hi,

From an ongoing support ticket I thought I would share some code:  This gets the data item of the currently editing cell (you can call this from your dropdownlist etc)

 

<script>
    function getDataItem() {
        var dataItem = $(".k-edit-cell").closest(".k-grid").data("kendoGrid").dataItem($(".k-edit-cell").closest("tr"));
        alert(dataItem.myID);
    }
</script>

- by
Waz
Top achievements
Rank 1
on 30 Apr 2017, 10:20 PM

many thks

is my final

    function AdditionalData() {
        var uid = '#=uid#';
        var selector = kendo.format("tr[data-uid='{0}']", uid);
        var currentGridElement = $(selector).closest("[data-role=grid]");
        var parentRow = currentGridElement.closest(".k-detail-row").prev();
        var parentGrid = parentRow.closest("[data-role=grid]").data("kendoGrid");
        var parentModel = parentGrid.dataItem(parentRow);
        return {
            Id: parentModel.id
        };
    }

- by
Dina
Top achievements
Rank 1
on 30 Apr 2017, 10:43 PM

var uid is giving me a literal value. I am getting exactly '#=uid#' as string. 

Where are you passing this variable. the code below Is not working for me :S.

Can you please help me with this?

 

Thanks.

 

- by
Francisco
Top achievements
Rank 1
on 20 Jun 2017, 04:57 PM
Hi Francisco,

Could you please try the following approach instead:
<input type="hidden" name="uid"/>
<script>
    function AdditionalData() {
        var uid = $("[name='uid']").val();
        //...
    }
</script>

Hope this helps.


Regards,
Konstantin Dikov
Progress Telerik
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
- by
Konstantin Dikov
Telerik team
on 22 Jun 2017, 12:29 PM

Thanks for your earlier answer. it worked!!! :)

Have a great day.

 

- by
Francisco
Top achievements
Rank 1
on 22 Jun 2017, 08:20 PM

Hello,

Just a quick update, another approach that works well:

   function additionalData() {
            var gridElement = $(event.currentTarget);
            var row = gridElement.find(".k-grid-edit-row");
            var grid = gridElement.data("kendoGrid");
            var dataItem = grid.dataItem(row);
            return { orderId: dataItem.OrderID }
        }
@(Html.Kendo().ComboBoxFor(m => m) .Filter("contains") .DataTextField("CategoryName") .DataValueField("CategoryID") .Placeholder("Select Category...") .DataSource(source => { source.Ajax() .Read(r => r.Action("Categories_Read", "Grid").Data("additionalData()"));

Regards,
Alex Hajigeorgieva
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
- by
Alex Hajigeorgieva
Telerik team
on 14 May 2020, 08:30 AM

All the possible solutions in here could not solve my problem.

@(Html.Kendo().Grid<WishlistItem>()
    .Name("gridWishlist")
    .Columns(columns =>
    {
        columns.Bound(c => c.Kategorie.Name);
        // How can I give the Editortemplate this information?
        columns.Bound(c => c.Count).Width(100).EditorViewData(new { MaxCount = "# =WishlistItem_MaxCount#" });
        columns.Command(command =>
        {
            command.Destroy();
        }).Width(130);
    })
    .DataSource(dataSource => dataSource
        .Ajax()
        .AutoSync(true)
        .Events(ev => {
            ev.Error("gridError");
            ev.Sync("calculateKaution");
        })
        .Model(model =>
        {
            model.Id(m => m.Id);
            model.Field(m => m.Kategorie.Name).Editable(false);
        })
        .PageSize(100)
        // CRUD
        .Read(r => r.Action("GetKategorieWishlist", "Ausleihe"))
        .Destroy("DeleteKategorieInWishlist", "Ausleihe")
    )
    .Editable(editable => editable
        .Mode(GridEditMode.InCell)
    )
    .HtmlAttributes(new { style = KendoManager.Grid_GetHeight(5, false, true) })
    .Scrollable(scrollable => scrollable.Virtual(true))
    .Sortable()
)

 

My EditorTemplate is

@model double?
 
@(Html.Kendo().NumericTextBoxFor(m => m)
    .Decimals(0)
    .HtmlAttributes(new { style = "width:100%" })
    // Max-Value is coming from Grid-ViewModel.
    .Max(ViewData["MaxCount"] != null && ViewData["MaxCount"] is int ? (int)ViewData["MaxCount"] : 0)
    .Min(0)
)

 

In my page the user can add existing datasets from combobox into this grid I'll talk about.

The Grid ViewModel is carrying a property with a total count of exemplars of the dataset (WishlistItem_MaxCount). It should be passed into my EditorTemplate, that the NumericTextBox of the Property "Count" has this Max-Value in his settings.

All the solutions in this thread here are talking about comboboxes and dropdownboxes with a defined datasource, but not in my case with a NumericTextBox.

As far I unterstood I can't send the property WishlistItem_MaxCount to my EditorTemplate because the grid is only initialized once at the beginning. So all the dynamically added datasets of my grid can't be applied to this max-amount.

Is there any possible solution to my case?

- by
Daniel
Top achievements
Rank 1
on 08 Jun 2020, 11:02 AM

Hi, Daniel,

The EditorViewData method adds an item inside the ViewData dictionary on the server, it cannot pass a property that is evaluated on the client. If the WishlistItem_MaxCount is not available on the server by means of ViewData or the ViewModel of the page for example, then you could use the Edit() event handler, and change the max of the numeric textbox by getting its instance and calling the max() method:

function onEdit(e){
     if(e.container.find("[name='Count']").length){
            var numeric = e.container.find("input[name='Count']").data("kendoNumericTextBox");
            numeric.max(50);
     }
}

Kind Regards,
Alex Hajigeorgieva
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
- by
Alex Hajigeorgieva
Telerik team
on 10 Jun 2020, 09:44 AM
That's awesome, yes it's working now. Thank you!
- by
Daniel
Top achievements
Rank 1
on 10 Jun 2020, 11:11 AM
Tags
Grid
Asked by
Yuhua
Top achievements
Rank 1
Answers by
Vladimir Iliev
Telerik team
Share this question
or