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

InCell Editing not working

5 Answers 730 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Alex
Top achievements
Rank 1
Alex asked on 29 Feb 2016, 03:37 PM

Any time I try to do an update with InCell editing I get a javascript error as soon as I click out of the cell button.

 

function anonymous(d) {
return d.x.Col2 // 0x800a138f - JavaScript runtime error: Unable to get property 'Col2' of undefined or null reference
}

The d value seems to have my object (CP_FailureStrategyMatrixRow) in it just fine, i.e. it has a attribute called "Col2" that has a valid value in it. I feel everything would work just fine if it was doing "d.Col2", instead of looking in some inner value called x. But I have no idea where this "x" is coming from.

 

It never even gets to the server-side code:

I have tried it with both versions of the CRUD operations, as the examples on telerik seem to use both, but it doesn't seem to matter which update statement I use.

 

@model XDashboard.Models.GridModel
 
@using Kendo;
@using Kendo.Mvc;
@using Kendo.Mvc.UI;
 
 
@(Html.Kendo().Grid<XDashboard.Models.CP_FailureStrategyMatrixRow>()
    .Name("Grid")
    .Columns(columns =>
    {
        columns.Bound(p => p.Col1);
        columns.Bound(p => p.Col2).Width(140);
        columns.Bound(p => p.Col3).Width(140);
        //columns.Bound(p => p.ProbabilityOfFailureValue).Width(100);
        columns.Command(commands =>
        {
            commands.Destroy(); // The "destroy" command removes data items
        }).Title("Commands").Width(200);
    })
        // .Events(e => e.DataBound("OnChange")) //this will attach to the events for the grid
      .ToolBar(toolbar =>
      {
          toolbar.Create(); // The "create" command adds new data items
          toolbar.Save(); // The "save" command saves the changed data items
      })
      .Editable(editable => editable.Mode(GridEditMode.InCell)) // Use in-cell editing mode
      .DataSource(dataSource =>
          dataSource.Ajax()
            .Batch(false) // Enable batch updates
            .Events(events => events.Error("error_handler")) //this will grab the events for the datasource, notice hwo we are inside the method for datasource
            .Events(events => events.Change("OnChange"))
              //.Events(events => events.Sync("OnChange"))
            .Model(model =>
            {
                model.Id(product => product.ProbabilityOfFailureValue); // Specify the property which is the unique identifier of the model
                model.Field(product => product.ProbabilityOfFailureValue).Editable(false); // Make the ProductID property not editable
            })
                .Create(create => create.Action("Create2", "ManagementStrats")) // Action method invoked when the user saves a new data item
                .Read(read => read.Action("Read", "ManagementStrats"))  // Action method invoked when the grid needs data
                    .Update(update => update.Action("Update2", "ManagementStrats")) // Action method invoked when the user saves an updated data item
                        .Events(events => events.Error("error_handler")) 
                .Destroy(destroy => destroy.Action("Destroy2", "ManagementStrats")) // Action method invoked when the user removes a data item
      )
      .Pageable()
)
<script type="text/javascript">
    function error_handler(e) {
        if (e.errors) {
            var message = "Errors:\n";
            $.each(e.errors, function (key, value) {
                if ('errors' in value) {
                    $.each(value.errors, function () {
                        message += this + "\n";
                    });
                }
            });
            alert(message);
        }
    }
}

 

public class ManagementStratsController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
 
    public ActionResult Read([DataSourceRequest] DataSourceRequest request)
    {
        XEntities db = new XEntities();
        ManagementStratsService productService = new ManagementStratsService(db);
 
        return Json(productService.Read().ToDataSourceResult(request));
    }
 
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create([DataSourceRequest] DataSourceRequest request, [Bind(Prefix = "models")]IEnumerable<CP_FailureStrategyMatrixRow> products)
    {
        XEntities db = new XEntities();
        ManagementStratsService productService = new ManagementStratsService(db);
 
        var results = new List<CP_FailureStrategyMatrixRow>();
 
        if (products != null && ModelState.IsValid)
        {
            foreach (var product in products)
            {
                productService.Create(product);
                results.Add(product);
            }
        }
 
        return Json(results.ToDataSourceResult(request, ModelState));
    }
 
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create2([DataSourceRequest] DataSourceRequest request, CP_FailureStrategyMatrixRow product)
    {
        XEntities db = new XEntities();
        ManagementStratsService productService = new ManagementStratsService(db);
 
        var results = new List<CP_FailureStrategyMatrixRow>();
 
        if (product != null && ModelState.IsValid)
        {
 
                productService.Create(product);
                results.Add(product);
 
        }
 
        return Json(results.ToDataSourceResult(request, ModelState));
    }
 
    //[AcceptVerbs(HttpVerbs.Post)]
    //public ActionResult Update([DataSourceRequest] DataSourceRequest request, CP_FailureStrategyMatrixRow product)
    //{
    //    if (product != null && ModelState.IsValid)
    //    {
    //        XEntities db = new XEntities();
    //        ManagementStratsService productService = new ManagementStratsService(db);
    //    }
 
    //    return Json(new[] { product }.ToDataSourceResult(request, ModelState));
    //}
 
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Update([DataSourceRequest] DataSourceRequest request, [Bind(Prefix = "models")]IEnumerable<CP_FailureStrategyMatrixRow> products)
    {
        XEntities db = new XEntities();
        ManagementStratsService productService = new ManagementStratsService(db);
 
        if (products != null && ModelState.IsValid)
        {
            foreach (var product in products)
            {
                productService.Update(product);
            }
        }
 
        return Json(products.ToDataSourceResult(request, ModelState));
    }
 
 
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Update2([DataSourceRequest] DataSourceRequest request, CP_FailureStrategyMatrixRow product)
    {
        XEntities db = new XEntities();
        ManagementStratsService productService = new ManagementStratsService(db);
 
        if (product != null && ModelState.IsValid)
        {
            productService.Update(product);
        }
 
        return Json(new[] { product }.ToDataSourceResult(request, ModelState));
    }
 
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Destroy([DataSourceRequest] DataSourceRequest request, [Bind(Prefix = "models")]IEnumerable<CP_FailureStrategyMatrixRow> products)
    {
 
            XEntities db = new XEntities();
            ManagementStratsService productService = new ManagementStratsService(db);
 
          
 
 
        if (products != null && ModelState.IsValid)
        {
            foreach (var product in products)
            {
                productService.Destroy(product);
            }
        }
 
        return Json(products.ToDataSourceResult(request, ModelState));
    }
 
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Destroy2([DataSourceRequest] DataSourceRequest request, CP_FailureStrategyMatrixRow product)
    {
 
        XEntities db = new XEntities();
        ManagementStratsService productService = new ManagementStratsService(db);
         
 
        if (product != null && ModelState.IsValid)
        
                productService.Destroy(product);          
        }
 
        return Json(new[] { product }.ToDataSourceResult(request, ModelState));
    }
 
    //public ActionResult Unique(string field)
    //{  
 
    //    var result = GetCP_FailureStrategyMatrixRows().Distinct(new CP_FailureStrategyMatrixRowComparer(field));
 
    //    return Json(result, JsonRequestBehavior.AllowGet);
    //}
 
 
 
}

 

public class CP_FailureStrategyMatrixRow
{
    public int ProbabilityOfFailureValue { get; set; }
 
    public string Col1 { get; set; }
 
    public string Col2 { get; set; }
 
    public string Col3 { get; set; }
 
    public string Col4 { get; set; }
 
    public string Col5 { get; set; }
 
    public string Col6 { get; set; }
 
    public string Col7 { get; set; }
 
    public string Col8 { get; set; }
 
    public string Col9 { get; set; }
 
    public string Col10 { get; set; }
 
    internal CP_FailureStrategyMatrix_Test transform()
    {
        CP_FailureStrategyMatrix_Test row = new CP_FailureStrategyMatrix_Test();                    
 
        row.Col1 = Col1.Length == 1 ? (int?)(Char.GetNumericValue(Col1[0]) - 64) : null;
        row.Col2 = Col2.Length == 1 ? (int?)(Char.GetNumericValue(Col2[0]) - 64) : null;
        row.Col3 = Col3.Length == 1 ? (int?)(Char.GetNumericValue(Col3[0]) - 64) : null;
        row.Col4 = Col4.Length == 1 ? (int?)(Char.GetNumericValue(Col4[0]) - 64) : null;
        row.Col5 = Col5.Length == 1 ? (int?)(Char.GetNumericValue(Col5[0]) - 64) : null;
        row.Col6 = Col6.Length == 1 ? (int?)(Char.GetNumericValue(Col6[0]) - 64) : null;
        row.Col7 = Col7.Length == 1 ? (int?)(Char.GetNumericValue(Col7[0]) - 64) : null;
        row.Col8 = Col8.Length == 1 ? (int?)(Char.GetNumericValue(Col8[0]) - 64) : null;
        row.Col9 = Col9.Length == 1 ? (int?)(Char.GetNumericValue(Col9[0]) - 64) : null;
        row.Col10 = Col10.Length == 1 ? (int?)(Char.GetNumericValue(Col10[0]) - 64) : null;
        row.ProbabilityOfFailureValue = ProbabilityOfFailureValue;
 
        return row;
    }
 
 
 
 
 
    //public partial class CP_FailureStrategyMatrix_Test
    //{
    //    public int ProbabilityOfFailureValue { get; set; }
    //    public Nullable<int> Col1 { get; set; }
    //    public Nullable<int> Col2 { get; set; }
    //    public Nullable<int> Col3 { get; set; }
    //    public Nullable<int> Col4 { get; set; }
    //    public Nullable<int> Col5 { get; set; }
    //    public Nullable<int> Col6 { get; set; }
    //    public Nullable<int> Col7 { get; set; }
    //    public Nullable<int> Col8 { get; set; }
    //    public Nullable<int> Col9 { get; set; }
    //    public Nullable<int> Col10 { get; set; }
    //}
}

5 Answers, 1 is accepted

Sort by
0
Alex
Top achievements
Rank 1
answered on 29 Feb 2016, 04:25 PM

Well I found out, sorta, why this is happening...

 

I have my main View "Summary.cshtml" that contains some code. Notice the "m => x". If I change it to "m => y", the javascript error references y instead of x, so this is certainly the cause of the issue.

@foreach (var x in Model.GridModels)
{
   <!-- MyDashboardMaint and MyReports are handled differently -->
    if (x.GridType == "AssetMgmtStrategy")
    {
        <div class="grid-placeholder-@x.GridType">
            <!-- See GridModel.cshtml in DisplayTemplates -->
            @Html.DisplayFor(m => x, new ViewDataDictionary(this.ViewData) { { "ShowOpen", true } })
        </div>
    }
}

 

which then calls a partial view (GridModel.cshtml)

 

@model eRPortalDashboard.Models.GridModel
@{
 
    if (Model.GridDatasource != null)
    {
 
        <div class="panel-group">
            <div class="panel panel-primary">
                <div class="panel-heading clearfix" data-toggle="collapse" data-target="@("#content-Grid" + @Model.ID)">
                    @Html.Partial("_GridTitleBar", Model)
                </div>
                @* if ShopOpen is true then we add a class 'in' that will show the collapsable panel by default *@
                <div id="@("content-Grid" + @Model.ID)" class=@("panel-collapse collapse" + (Convert.ToBoolean(ViewData["ShowOpen"]) == true ? " in" : ""))>
                    <div class="panel-body">
 
                        @if (Model.GridDatasource.GetType() == typeof(List<eRPortalDashboard.Models.CP_FailureStrategyMatrixRow>))
                        {
                            @Html.Partial("ManagementStratsGridModel")
                        }
                        
                    </div>
                </div>
            </div>
        </div>
    }
}

 

Which then finally calls my partial view that contains the Kendo grid. If I call my partial View (ManagementStratsGridModel.cshtml), directly from Summary.cshtml:

@Html.Partial("ManagementStratsGridModel", new ViewDataDictionary(this.ViewData) { { "ShowOpen", true } });

instead of 

@Html.DisplayFor(m => x, new ViewDataDictionary(this.ViewData) { { "ShowOpen", true } });

then I get no error at all. Why is this happening? Am I doing something wrong, or is this a bug with Kendo?

0
Alex
Top achievements
Rank 1
answered on 01 Mar 2016, 10:40 PM

I have attached a compilable project that replicates the issue. It is simply a telerik example that I modified. Please see Index.cshtml for turning the issue on or off.

 

Can someone from Telerik please look at this?

 

To make the file under 2MB, I deleted the contents of the following folders:

\batch-editing\lib\KENDOUIMVC\2014.3.1119.440

\batch-editing\packages

\batch-editing\KendoGridBatchEditing\bin

 

 

0
Rosen
Telerik team
answered on 02 Mar 2016, 12:28 PM

Hello Alex,

The behavior you are experiencing is due to the way ASP.NET MVC generates nested Editor templates. The framework is adding a prefix to the names of the input elements on every level of nesting. This however will prevent the Grid's edit form to correctly bind to the fields of the edited model as it will use the name of the input to automatically generate the MVVM binding. In order to address this you should remove the html prefix inside the Grid's editor template. Similar to the following:

@{ViewData.TemplateInfo.HtmlFieldPrefix = "";}
 
@(Html.Kendo().Grid<KendoGridBatchEditing.Models.ProductViewModel>()
      .Name("grid")
      /*..*/
)

Regards,
Rosen
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
0
Alex
Top achievements
Rank 1
answered on 02 Mar 2016, 01:43 PM

Will this be addressed in some way in the future? e.g. throwing some sort of error, or warning message, or some other way to determine what needs to be done to fix this issue?

Am I doing something that out of the ordinary where people almost never run into this? If so, could you point me in the direction of why what I'm doing is "wrong"?

0
Rosen
Telerik team
answered on 03 Mar 2016, 10:06 AM

Hello Alex,

This is not something which can be addressed in the Grid itself. As I have mentioned this is how the ASP.NET MVC will generate the Editor Template input names, and it is not possible to automatically account for this behavior from withing the Grid.
As the automatic binding generation expects the name of the elements and fields to match, if you need to still have the names prefixed, it will be required to use a custom editor template where manually to apply the appropriate MVVM bindings in order to bind the form to the model instance.

Regards,
Rosen
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
Alex
Top achievements
Rank 1
Answers by
Alex
Top achievements
Rank 1
Rosen
Telerik team
Share this question
or