pass Grid view model data to Editor template

1 Answer 6151 Views
Grid
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!
Bryan
Top achievements
Rank 1
commented on 14 Jul 2014, 03:37 AM

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.
Vladimir Iliev
Telerik team
commented on 14 Jul 2014, 08:52 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!
 
Dina
Top achievements
Rank 1
commented on 31 Mar 2017, 09:09 AM

where you declare getParentID ?

In some of grid events?

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

Alex Hajigeorgieva
Telerik team
commented on 04 Apr 2017, 06:54 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.
Waz
Top achievements
Rank 1
commented on 18 Apr 2017, 04:26 AM

event.srcElement I believe is non-standard and will not work in FireFox.
Alex Hajigeorgieva
Telerik team
commented on 19 Apr 2017, 09:48 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.
Dina
Top achievements
Rank 1
commented on 26 Apr 2017, 12: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>

Alex Hajigeorgieva
Telerik team
commented on 27 Apr 2017, 12:05 PM

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.
Waz
Top achievements
Rank 1
commented on 30 Apr 2017, 10:20 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>

Dina
Top achievements
Rank 1
commented on 30 Apr 2017, 10:43 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
        };
    }

Francisco
Top achievements
Rank 1
commented on 20 Jun 2017, 04:57 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.

 

Konstantin Dikov
Telerik team
commented on 22 Jun 2017, 12:29 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.
Francisco
Top achievements
Rank 1
commented on 22 Jun 2017, 08:20 PM

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

Have a great day.

 

Alex Hajigeorgieva
Telerik team
commented on 14 May 2020, 08:30 AM

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.
Daniel
Top achievements
Rank 3
Iron
Iron
Iron
commented on 08 Jun 2020, 11:02 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?

Alex Hajigeorgieva
Telerik team
commented on 10 Jun 2020, 09:44 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.
Daniel
Top achievements
Rank 3
Iron
Iron
Iron
commented on 10 Jun 2020, 11:11 AM

That's awesome, yes it's working now. Thank you!
Pi
Top achievements
Rank 1
commented on 10 Nov 2023, 06:54 PM

Hi Alex,

Your code worked for me.

Thankyou

Tags
Grid
Asked by
Yuhua
Top achievements
Rank 1
Answers by
Vladimir Iliev
Telerik team
Share this question
or