How to bind asp.net mvc grid data inside object model without posting to server

1 Answer 3300 Views
Grid
Sree
Top achievements
Rank 1
Sree asked on 14 Mar 2016, 09:36 AM
I am new to mvc, new telerik. I have page with several sections: section A to G, and a button to register.
Section A contains an Asp.Net MVC Grid.
I would like to save this data to db only after filling all the sections. However I should be able to save the section A data in grid to the associated viewmodel each time a row is added, updated, deleted. I have tried below code as per samples provided on the telerik website, but I am unsuccessful. Please could you help me on how will be be able to achieve this?

My object model for the page looks like below:

namespace SampleProject.Models
{
public class Base {
public Guid Id {get; set;}
public string Name{get; set;}
}
public class Person : Base {
public string TelephoneNumber {get; set;}
public string FaxNumber {get; set;}
public string EmailAddress {get; set;}
}
public class Order {
public Order()
{
Persons = new List<Person> ();
}
public List<Person> Persons {get; set;}
}

}

namespace SampleProject.ViewModels
{
public class RegisterViewModel
{
public RegisterViewModel()
{
Order = new Order();
}
    Order Order {get; set;}
}
}

VIEw:
@model SampleProject.ViewModels.RegisterViewModel
 @(Html.Kendo().Grid<SampleProject.Models.Person>()
                                    .Name("PersonGrid")
                                    .Columns(columns =>
                                    {
                                        columns.Bound(c => c.Name);
                                        columns.Bound(c => c.TelephoneNumber).Title("Telephone Number");
                                        columns.Bound(c => c.FaxNumber).Title("Fax Number");
                                        columns.Bound(c => c.EmailAddress).Title("Email Address");
                                        columns.Command(command =>
                                        {
                                            command.Edit();
                                            command.Destroy();
                                        }).Title("Actions").Width(250);
                                    })
                                    .ToolBar(toolbar => toolbar.Create())
                                    .Editable(editable => editable.Mode(GridEditMode.InLine))
                                    .HtmlAttributes(new { style = "height: 150px;" })
                                    .Scrollable()
                                    .Sortable()
                                    .DataSource(dataSource => dataSource
                                                .Ajax()
                                                .Model(model => model.Id(c => c.Id))
                                                .Create(create => create.Action("CreatePerson", "Register"))
                                                .Update(update => update.Action("UpdatePerson", "Register"))
                                                .Destroy(delete => delete.Action("DeletePerson", "Register"))
                                                .Read(read => read.Action("ReadPersons", "Register"))
                                                )
                                )

Controller:
public class RegisterController
{
private RegisterViewModel registerViewModel;
public ActionResult RegisterNewOrder()
        {           
            return View(registerViewModel);
        }

public ActionResult ReadPersons([DataSourceRequest] DataSourceRequest request)
        {
            return Json(registerViewModel.Order.Persons.ToDataSourceResult(request),
                        JsonRequestBehavior.AllowGet);
        }

[AcceptVerbs(HttpVerbs.Post)]
        public ActionResult CreatePerson([DataSourceRequest] DataSourceRequest request, Person person)
        {
            if (person != null)
            {
                person.Id = Guid.NewGuid();
                if (ModelState.IsValid)
                {
                    var xPerson = new Person
                    {
                        Id = person.Id,
                        Name = person.Name,
                        TelephoneNumber = person.TelephoneNumber,
                        EmailAddress = person.EmailAddress,
                        FaxNumber = person.FaxNumber
                    };
                    registerViewModel?.Order?.Persons.Add(xPerson);
person.Id = xPerson.Id;
                }
            }
            return Json(new[] { person }.ToDataSourceResult(request, ModelState));
        }

[AcceptVerbs(HttpVerbs.Post)]
        public ActionResult UpdatePerson([DataSourceRequest] DataSourceRequest request, Person person)
        {
            if (ModelState.IsValid)
            {
                var xPerson = registerViewModel.Order.Persons
                                       .FirstOrDefault(x => x.Id == person.Id);
                //TODO: Need to find out exact
                if (xPerson  != null)
                {
                    xPerson .Name = person.Name;
                    xPerson .TelephoneNumber = person.TelephoneNumber;
                    xPerson .FaxNumber = person.FaxNumber;
                    xPerson .EmailAddress = person.EmailAddress;
                }
            }
            return Json(new[] { person }.ToDataSourceResult(request, ModelState));
        }
[AcceptVerbs(HttpVerbs.Post)]
        public ActionResult DeletePerson([DataSourceRequest] DataSourceRequest request, Person person)
        {
            if (person != null && ModelState.IsValid)
            {
                registerViewModel?.Order?.Persons.Remove(person);
            }
            return Json(new[] { person }.ToDataSourceResult(request, ModelState));
        }
}

Thanks,
Sreeni

1 Answer, 1 is accepted

Sort by
0
Boyan Dimitrov
Telerik team
answered on 16 Mar 2016, 09:08 AM

Hello Sree,

 

I am afraid that I am not completely sure that I understand what you are trying to achieve. 

 

With regards to the title of the thread I believe you are trying initially to populate the Kendo UI Grid for ASP.NET MVC from the model object, but not to send a request to the read action method. This is actually possible using the following syntax: 

@model KendoUIMVC5.Models.Category
 
@(Html.Kendo().Grid(Model.Products)
              .Name("Products")
....

The @model SampleProject.ViewModels.RegisterViewModel object exists only on the server side. When the update/create/delete operation is performed on the client-side there is no @model SampleProject.ViewModels.RegisterViewModel object on the client-side. This is why Kendo UI DataSource should post to update/create/delete action methods in order to sync changes made on the client-side with the server. 

 

Regards,
Boyan Dimitrov
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
Nikki
Top achievements
Rank 1
commented on 11 Sep 2019, 05:35 PM

I have the same situation and I have searched all over but still can't get it working.

I have a ViewModel:

  public class MainModel
  {
       public DateTime Field1{ get; set; }
    public decimal Field2 { get; set; }

public IEnumerable<ChildModel> ChildModelRecords{get;set;}

}

  public class ChildModel
  {

           public int Id{ get; set; }

    [UIHint("ItemTypeEditor")]
    public int? ItemTypeId { get; set; }
    public decimal Amount{ get; set; }

}

My view has the fields from the MainModel with a submit button, then a grid (below):

@(Html.Kendo().Grid(Model.ChildModelRecords)
    .Name("Grid")
    .ToolBar(tools => tools.Create().Text("Add new item"))
    .Editable(editable => editable.Mode(GridEditMode.InCell))
    .Columns(columns =>
    {
      columns.Bound(p => p.ItemTypeId).ClientTemplate("#= ItemTypeTitle #" +
        "<input type='hidden' name='ChildModelRecords[#= index(data)#].ItemTypeId' value='#= ItemTypeId #' />"
      ).EditorTemplateName("ItemTypeEditor");
      columns.Bound(p => p.Amount).ClientTemplate("#= Amount #" +
        "<input type='hidden' name='ChildModelRecords[#= index(data)#].Amount' value='#= Amount #' />"
      );
      columns.Bound(p => p.Id).Hidden().ClientTemplate("#= Id #" +
        "<input type='hidden' name='ChildModelRecords[#= index(data)#].Id' value='#= Id #' />"
      );
    })
    .DataSource(dataSource => dataSource.Ajax()
      .Model(model =>
      {
        model.Id(p => p.Id);
        model.Field(p => p.ItemTypeId).Editable(true);
        model.Field(p => p.Amount).Editable(true);
      })
      .ServerOperation(false)
    )
    .Scrollable()
    .HtmlAttributes(new { style = "height:350px" })
  )

<script>

  function index(dataItem) {
    var data = $("#Grid").data("kendoGrid").dataSource.data();
    return data.indexOf(dataItem);
}

</script>

 

I have a couple of issues:

1. The dropdown in the grid is not working.  I am getting an error that the ItemTypeId is null and the value I select doesn't populate.

2. When I click the submit button, the ChildModelRecords collection in the MainModel is not populated, no matter how many times I click Add new item on the grid and populate the Amount column for the rows.

 

Any help would be greatly appreciated.  I am new to asp.net, and mvc.  I have working kendo grids using popup editors, but this one is different because the values for the MainModel and any rows created in the ChildModel all need to be maintained client side until the submit button is clicked.  Plus this is the first grid that will be editable inrow or incell.  Thanks in advance!

Boyan Dimitrov
Telerik team
commented on 13 Sep 2019, 02:54 PM

Hello,

Actually we do have an example that is pretty close to the scenario that you are trying to achieve. The model does contain a list of objects that need to be displayed in the grid and then submit with the form. 

Hope that this will be helpful to implement your scenario. 

Regards,
Boyan Dimitrov
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Tags
Grid
Asked by
Sree
Top achievements
Rank 1
Answers by
Boyan Dimitrov
Telerik team
Share this question
or