Inline edit grid with dropdown lists

3 Answers 2523 Views
Grid
Matias
Top achievements
Rank 1
Matias asked on 26 Oct 2016, 03:00 PM

I've been trying to accomplish this following several forum threads and this guide: http://docs.telerik.com/kendo-ui/aspnet-mvc/helpers/grid/templating/editor-templates but so far I can't make it work. I don't know what I'm doing wrong, since if I use my dropdown list outside the grid it works normally. I can't seem to understand how to bind the dropdown list to a grid column.

This is my grid:
@model IEnumerable<RECON.DAL.Models.Traducciones>
@(Html.Kendo().Grid(Model)
        .Name("Traducciones")
        .Columns(columns =>
        {
            columns.Bound(foo => foo.OrigenId).Title(Global.Origen).EditorTemplateName("_FiltrosTraducciones");
            columns.Bound(foo => foo.Campo).Title(Global.Campo);
            columns.Bound(foo => foo.ValorOrigen).Title(Global.ValorOrigen);
            columns.Bound(foo => foo.ValorDestino).Title(Global.ValorDestino);
            columns.Command(commands =>
            {
                commands.Edit().Text(" ").UpdateText(" ").CancelText(" ");
                commands.Destroy().Text(" ");
            }).Title("Acciones").Width(200);
        })
        .ToolBar(toolbar => toolbar.Create().Text("Nuevo"))
        .Editable(editable => editable.Mode(GridEditMode.InLine))
        .DataSource(dataSource =>
            dataSource.Ajax()
            .Model(model =>
            {
                model.Id(m => m.Id);
            })
            .Create(create => create.Action("Create", "Traduccion"))
            .Read(read => read.Action("Read", "Traduccion"))
            .Update(update => update.Action("Edit", "Traduccion"))
            .Destroy(destroy => destroy.Action("Delete", "Traduccion"))
        ))

 

This is my partial view with the dropdown list:
@model IEnumerable<RECON.DAL.ViewModels.TraduccionesOrigenes>

@(Html.Kendo().DropDownList()
        //.Name("origenes")
        .HtmlAttributes(new { style = "width: 250px" })
        .DataTextField("Descripcion")
        .DataValueField("Id")
        .DataSource(source => source.Read(read => read.Action("GetTraduccionesOrigenes", "Traduccion")))
)

I fill the dropdown list with a stored procedure and outside the grid it works fine.

Now, I don't know if I have to use the EditorTemplateName in the column I want the dropdown list or not, I'd just would like a step by step how to do it so that I can achieve what I want.

Thanks in advance.

3 Answers, 1 is accepted

Sort by
0
Viktor Tachev
Telerik team
answered on 28 Oct 2016, 12:10 PM
Hello Matias,

Please ensure that the custom editor template is placed in the ~/Views/Shared/EditorTemplates folder. Also, add the UIHint attribute to the corresponding field in the model. The string passed as argument to UIHint should match exactly the name of the editor template cshtml file.

With that said, try to populate the data for the DropDownList in the Controller and bind it via the BindTo() method as in the article.

Give the modifications a try and let me know how they work for you.

Regards,
Viktor Tachev
Telerik by Progress
Check out the new UI for ASP.NET Core, the most complete UI suite for ASP.NET Core development on the market, with 60+ tried-and-tested widgets, based on Kendo UI.
Alfredo
Top achievements
Rank 1
commented on 11 Jun 2020, 03:01 PM

I am trying to do something similar in  a project I have. I am new using Telerik Controls. But I want to populate a drop down list when I am editing (inline) a row in a Grid. I am looking for samples on how to do it. I am using DataSource with Ajax in my grid. My project is an ASP.NET MVC project with Razor Pages. You mention an Article before, where is that at?
Viktor Tachev
Telerik team
commented on 15 Jun 2020, 01:48 PM

Hi Alfredo,

 

Below you will find a link to the article describing how a custom editor can be used in the Grid component:

https://docs.telerik.com/aspnet-mvc/html-helpers/data-management/grid/templates/editor-templates#creating-custom-editors-for-bound-properties

The approach is also illustrated in the following demo. The Category field is using a custom editor.

https://demos.telerik.com/aspnet-mvc/grid/editing-custom

 

Give the approach a try and let me know how it works for you.

 

Regards,
Viktor Tachev
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.
Alfredo
Top achievements
Rank 1
commented on 15 Jun 2020, 08:19 PM

Thank you. I got it working mixing a ForeignKey with the EditorTemplateName. 
Iman
Top achievements
Rank 1
commented on 15 Jul 2020, 09:27 AM

Hi . I Have a problem with Kendo Grid Edit Inline 

this is my code 

1.// columns.Bound(p => p.WhenDrug).ClientTemplate("#= WhenDrug.DrugName#").Width(180);
2.columns.Bound(p => p.WhenDrug).ClientTemplate("\\#= WhenDrug.DrugName\\#").Width(180);

when i use first line i receive and error that the Whendrug field not defiled and when i use second line everything work fine but  in grid i see field name instance field value 

 

this is my grid : 

01.@(Html.Kendo().Grid<WebApplication2.Models.PrescriptionViewModel>()
02.        .Name("grid")
03.        .Columns(columns =>
04.        {
05.            columns.Bound(p => p.DrugName);
06.           // columns.Bound(p => p.WhenDrug).ClientTemplate("#= WhenDrug.DrugName#").Width(180);
07.            columns.Bound(p => p.WhenDrug).ClientTemplate("\\#= WhenDrug.DrugName\\#").Width(180);
08.            columns.Command(command => { command.Edit(); command.Destroy(); }).Width(250);
09.        })
10.        .ToolBar(toolbar => toolbar.Create())
11.        .Editable(editable => editable.Mode(GridEditMode.InLine).ConfirmDelete("test").DisplayDeleteConfirmation("Test"))
12.        .Pageable()
13.        .Sortable()
14.        .Scrollable()
15.        .HtmlAttributes(new { style = "height:550px;" })
16.        .DataSource(dataSource => dataSource
17.            .Ajax()
18.            .Batch(true)
19.            .PageSize(20)
20.            .ServerOperation(false)
21.            .Events(events => events.Error("errorHandler"))
22.            .Model(model =>
23.            {
24.                model.Id(p => p.Id);
25.                
26.                model.Field(p => p.WhenDrug).DefaultValue(
27.                    ViewData["defaultDrugWhen"] as WebApplication2.Models.PrescriptionViewModel);
28.            })
29.            .Read(read => read.Action("EditingCustom_Read", "Grid"))
30.            .Update(update => update.Action("EditingCustom_Update", "Grid"))
31.            .Create(create => create.Action("EditingCustom_Create", "Grid"))
32.            .Destroy(destroy => destroy.Action("EditingCustom_Destroy", "Grid"))
33.        )
34.)
35. 
36.<script type="text/javascript">
37.    function errorHandler(e) {
38.        if (e.errors) {
39.            var message = "Errors:\n";
40.            $.each(e.errors, function (key, value) {
41.                if ('errors' in value) {
42.                    $.each(value.errors, function () {
43.                        message += this + "\n";
44.                    });
45.                }
46.            });
47.            alert(message);
48.        }
49.    }
50.</script>

this is my editor file 

1.@model WebApplication2.Models.WhenViewModel
2.@(Html.Kendo().DropDownListFor(m => m)
3.            .DataValueField("DrugId")
4.            .DataTextField("DrugName")
5.            .BindTo((System.Collections.IEnumerable)ViewData["DrugCategory"])
6.)

this is my model 

01.public class PrescriptionViewModel
02.    {
03.        public string Id { get; set; }
04.        public string DrugName { get; set; }
05. 
06.        [UIHint("WhenCategory")]
07.        public WhenViewModel WhenDrug { get; set; }
08. 
09.    }
10.    public class WhenViewModel
11.    {
12.        public string DrugId { get; set; }
13.        public string DrugName { get; set; }
14. 
15.    }
Francis
Top achievements
Rank 1
Veteran
commented on 16 Jul 2020, 03:38 PM

Hi Viktor,

I have implemented the grid adding the dropdown into a partial view and adding the ui hint to match. The dropdown shows when i enter the inline edit mode with the values populated however my problem is that I need the dropdown to default to the value that was originally there before the edit but instead it just displays the empty selection first. 

Tsvetomir
Telerik team
commented on 17 Jul 2020, 08:07 AM

Hi Francis,

Escaping the template symbols - "#" literals is needed only when the grid is nested within another widget, or if a hierarchy is built. In the current case, the escaping might only prevent the evaluation of the template and incorrect value is returned. 

If the server returns values that have null values, then you should add a check in the client template to handle them accordingly:

columns.Bound(p => p.WhenDrug).ClientTemplate("#= data.WhenDrug?data.WhenDrug.DrugName: ' '#").Width(180);

Could you confirm that the issue is related to the client template and the editing of the grid is working correctly?

 

Kind regards,
Tsvetomir
Progress Telerik

Francis
Top achievements
Rank 1
Veteran
commented on 17 Jul 2020, 08:31 AM

Hi Tsvetomir 

No the issue I'm having is that I have added a kendo dropdown as the editor control on a column in a grid and when i enter edit mode the dropdown does not default to the current value for that column in the data item 

This is my grid

@(
        Html.Kendo().Grid<BookingHub.Areas.Admin.ViewModels.DriverTestTypeViewModel>
    ()
    .Name("DrivingTestTypesGrid")
    .Columns(columns => {
            columns.Bound(t => t.Name).Title("Category Name");
            columns.Bound(t => t.Description).Title("Description");
            columns.Bound(t => t.Duration).Title("Duration");
            columns.Bound(t => t.StandardFee)
                .ClientTemplate("")
                .Title("Standard Fee");
            columns.Bound(t => t.PremiumFee).Title("Premium Fee");
            columns.Bound(t => t.TheoryTestCode).Title("Theory Test Required")
            .ClientTemplate("#= TheoryTestCode == null? '' : TheoryTestCode.Description  #");
            columns.Bound(t => t.FullTestTypeRequired).Title("Full Test Required");
            columns.Command(command => {
            command.Edit().Template("<a title='Click to edit' class='k-button k-button-icontext btn btn-sm k-secondary k-grid-edit'><i class='fa fa-pencil-alt text-primary'></i></a>");
            });
    })
    .Editable(editable => editable.Mode(GridEditMode.InLine))
    .Pageable()
    .Sortable()
    .DataSource(dataSource => dataSource
            .Ajax()
            .PageSize(15)
            .AutoSync(false)
            .ServerOperation(false) //paging, sorting and grouping performed in the client
            .Events(events => events.Error("GenericErrorHandler.handleCoreErrors('#DrivingTestTypesGrid')"))
            .Model(model =>
            {
                    model.Id(p => p.Id);
                    model.Field(p => p.Name);
                    model.Field(t => t.Description);
                    model.Field(t => t.Duration);
                    model.Field(t => t.StandardFee);
                    model.Field(t => t.PremiumFee);
                    model.Field(t => t.TheoryTestCode);
                    model.Field(t => t.FullTestTypeRequired);
            }
 
            )
            //.Create("CreateCustomerAccount", "View", new { Area = "Admin" })
            .Read("GetDriverTestTypes", "DriverTestTypes", new { Area = "Admin" })//.Type(HttpVerbs.Post))
            //.Update("UpdateCustomerAccount", "View", new { Area = "Admin" })
            //.Destroy("DeactivateCustomerAccount", "View", new { Area = "Admin" })
 
    )
    )

 

This is the dropdown

@(Html.Kendo().DropDownList()
    .Name("TheoryTestCode") // The name of the widget has to be the same as the name of the property.
    .DataValueField("Id") // The value of the drop-down is taken from the TheoryTestCode Id property.
    .DataTextField("Description") // The text of the items is taken from the TheoryTestCodes Description property.
    .BindTo((System.Collections.IEnumerable)ViewData["TheoryTestCodes"]) // A list of all TheoryTestCodes which is populated in the controller.
)

 

an in the view model that I have

[UIHint("TheoryTestCodeEditor")]
public TheoryTestCodeDTO? TheoryTestCode { get; set; }

 

The Dropdown appears with all of the correct values but the selection just does not default to the current value in the field. 

Tsvetomir
Telerik team
commented on 21 Jul 2020, 07:28 AM

Hi Francis,

Indeed, when the value does not default to the one on the view, it is an indication that the binding of the widget is not correct. This usually happens when the .Name option of the DropDownList is used for binding.

Could you try alternating the editor as follows:

@(Html.Kendo().DropDownListFor(m=>m)
   // .Name("TheoryTestCode") // The name of the widget has to be the same as the name of the property.
    .DataValueField("Id") // The value of the drop-down is taken from the TheoryTestCode Id property.
    .DataTextField("Description") // The text of the items is taken from the TheoryTestCodes Description property.
    .BindTo((System.Collections.IEnumerable)ViewData["TheoryTestCodes"]) // A list of all TheoryTestCodes which is populated in the controller.
)

And via the model on the page, you should accept an object of type "TheoryTestCodeDTO".

Let me know if the issue persists.

 

Kind regards,
Tsvetomir
Progress Telerik

Francis
Top achievements
Rank 1
Veteran
commented on 21 Jul 2020, 02:53 PM

Hi Tsvetomir,

When i comment out that line as above the grid fails to load and does not give any error messages.

If it helps I had posted another question but it contains the spec for each of the various parts of the grid for reference which can be seen here which might help you see something that I might have missed. 

Tsvetomir
Telerik team
commented on 23 Jul 2020, 11:01 AM

Hi Francis,

I have taken a look at the snippets from the referenced thread, however, I did not notice anything that might be causing the issue. 

Is it possible for you to share a sample project in which the defect could be observed? It would be very and I would have the chance to debug it locally.

Thank you for your cooperation.

 

Kind regards,
Tsvetomir
Progress Telerik

Shawn
Top achievements
Rank 2
commented on 18 Nov 2020, 05:26 PM

Did you guys ever resolve this?  I have an MVC Grid view with inline editing and a column bound (with UIHint) to an Editor Template that uses a Dropdownlist.  When I click the edit button, the dropdownlist is not bound to the current value of the row being edited.

 

Tsvetomir
Telerik team
commented on 19 Nov 2020, 02:23 PM

Hi Shawn,

The fact that the values of the model are not directly bound to the DropDownList indicates that there is something that breaks the binding. The most common reason is setting the Name property of the widget and using it as an editor. This leads to having a bind-value set to "FieldName.FieldName" which is incorrect. 

Is it possible for you to share the respective code snippets for the editor along with the grid's declaration so that I can investigate them?

 

Kind regards,
Tsvetomir
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Shawn
Top achievements
Rank 2
commented on 19 Nov 2020, 03:19 PM

Sure.  Here's the grid definition (the culprit column is .TranType)

@(Html.Kendo().Grid<DebtCloud.Data.Domain.TrustAccountTransaction>()
                    .Name("TrustAccountTransactionGrid")
                    .AutoBind(false)
                    .ToolBar(tb =>
                    {
                        tb.Excel();
                    })
                    .Excel(x => x.AllPages(true))
                    .Editable(ed => ed.Mode(GridEditMode.InLine))
                    .DataSource(ds => ds
                        .Ajax()
                        .PageSize(currentUser.GridPageSize)
                        .Model(m =>
                        {
                            m.Id(f => f.Id);
                            m.Field(c => c.Id).Editable(false);
                            m.Field(c => c.TranDate).Editable(false);
                            m.Field(c => c.TranType).Editable(true);
                            m.Field(c => c.TranRef).Editable(true);
                            m.Field(c => c.TranAmount).Editable(false);
                            m.Field(c => c.AllocationNotes).Editable(false);
                            m.Field(c => c.CapturedBy).Editable(false);
                            m.Field(c => c.CapturedOn).Editable(false);
                        })
                        .Read(rd => rd.Action("ReadBankStatement", "TrustAccountTransaction").Data("ReportParameters"))
                        .Update(ud => ud.Action("UpdateTransaction", "TrustAccountTransaction"))
                        .Destroy(ud => ud.Action("DeleteTransaction", "TrustAccountTransaction"))
                        .Events(ev => ev.Error("gridError"))
                    )
                    .Columns(cols =>
                    {
                        cols.Bound(c => c.Id).Hidden();
                        cols.Bound(c => c.TranDate).Format("{0:d}");
                        cols.Bound(c => c.TranType);
                        cols.Bound(c => c.TranRef).Title("Reference");
                        cols.Bound(c => c.TranAmount).Format("{0:n}").HtmlAttributes(new { @class = "ra" });
                        if (User.HasPermission(PermissionEnum.Banking_Unallocated_Withdrawals))
                            cols.Bound(c => c.AllocationNotes).ClientTemplate("#=AllocationNotes # #if(TranType == 'Withdrawal' && AllocationNotes){# <a href='\\#' onclick='unallocateWithdrawal(#=Id#,\"#=TranRef#\")' class='btn btn-warning'>Unallocate</a> #}#");
                        else
                            cols.Bound(c => c.AllocationNotes);
                        cols.Bound(c => c.CapturedBy).Hidden(true);
                        cols.Bound(c => c.CapturedOn).Hidden(true);
                        if (User.HasPermission(PermissionEnum.Banking_Capture_Bank_Statement))
                        {
                            cols.Command(c => c.Edit());
                            cols.Command(c => c.Destroy());
                        }
                    })
                    .ClientDetailTemplateId("StatementDetailTemplate")
                    .Pageable(pg => pg.Refresh(true))
                    .Filterable(f=> f.Mode((GridFilterMode)Enum.Parse(typeof(GridFilterMode), currentUser.GridFilterMode)))
                    .Resizable(r=> r.Columns(true))
                    .ColumnMenu(r=> r.Columns(true))
                    .Sortable(s=> s.SortMode(GridSortMode.MultipleColumn))
                    .ColumnMenu(cfg => cfg.Columns(true))
)

And here is the model property for TranType:

[Required]
[StringLength(10)]
[UIHint("TranTypeDDL")]
public string TranType { get; set; }

And here is the Editor Template:

@model string
 
@(Html.Kendo().DropDownListFor(m => m)
      .BindTo(new List<string> { "Deposit", "DebitOrder", "BankCharge", "Withdrawal", "Interest" })
)
Tsvetomir
Telerik team
commented on 20 Nov 2020, 01:56 PM

Hi Shawn,

I have used the provided code snippets in order to replicate the issue to no avail. Attached to my response is a project that depicts a grid with a DropDownList editor. Is it possible for you to take a look and let me know the differences compared to the one on your side? 

Looking forward to your reply.

 

Kind regards,
Tsvetomir
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Simon
Top achievements
Rank 1
commented on 14 Jan 2021, 07:36 PM

The demo at https://demos.telerik.com/aspnet-mvc/grid/editing-custom is really good. I was able to use it to add a drop down listof Locations to our grid as described. The only question I would have is how to add a "Select..." option as the first item in the drop down list and then make it required on click of Update ?

I thought I could add the it to DropDownListFor  in the Locations.cshtml editor template as in:

@(Html.Kendo().DropDownListFor(m => m)
        .Placeholder("Select...")
    .DataValueField("LocationID")
    .DataTextField("LongName")
    .Events(events =>
    {
         events.Change("fees_admin.locationChange");
    })
    .BindTo((System.Collections.IEnumerable)ViewData["locations"])

)

 

But apparently DropDownListFor does not support .Placeholder - is there a way to do this?

 

Thanks.

Alex Hajigeorgieva
Telerik team
commented on 18 Jan 2021, 10:41 AM

Hi, Simon,

The UI for ASP.NET MVC DropDownList has an OptionLabel() method that can be used to add the "Select..." option.

As for the required validation, you can decorate the model with the [Reqired] attribute and add the validation to the editor:

// model class 
[Required]
public Location Location
{
     get;
      set;
}
@(Html.Kendo().DropDownListFor(m => m)
    .OptionLabel("Select...")
    .DataValueField("LocationID")
    .DataTextField("LongName")
    .Events(events =>
    {
         events.Change("fees_admin.locationChange");
    })
    .BindTo((System.Collections.IEnumerable)ViewData["locations"])
)

@Html.ValidationMessageFor(m=>m)

Let us know should you need further assistance.

Kind Regards,
Alex Hajigeorgieva
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Simon
Top achievements
Rank 1
commented on 19 Jan 2021, 02:43 PM

Perfect, thank you.

 

Simon

0
Nestor
Top achievements
Rank 2
answered on 20 Apr 2021, 01:52 PM

Hi there

Great post, I was able to implement the dropdown list in the grid, however in my case, each row has a different data set for the dropdown, it depends on the Id (In my case, item id) of the object, so, how can you bind the data source which ultimately will be different row by row

Id     

0
Tsvetomir
Telerik team
answered on 22 Apr 2021, 10:54 AM

Hi Matias,

In general, you could send an additional parameter to the endpoint that would be feeding the DropDownList editor with data. This could happen by passing a JavaScript function to the .Data() option of the Read setup for the DropDownList. 

A similar example of how additional parameters can be sent to the server-side can be found in the following forum thread:

https://www.telerik.com/forums/pass-additional-parameters-to-read-ajax-datasource-method---mvc#6-wwFQboTECQByGUQYKKhw

Let me know if additional assistance is required.

 

Kind regards,
Tsvetomir
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Tags
Grid
Asked by
Matias
Top achievements
Rank 1
Answers by
Viktor Tachev
Telerik team
Nestor
Top achievements
Rank 2
Tsvetomir
Telerik team
Share this question
or