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

Map a client-end data array to the List<Model> type

3 Answers 380 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Shafi
Top achievements
Rank 1
Shafi asked on 02 Jun 2016, 08:49 PM

Hi!

After a while, I was able to have a working EditorTemplate for a List<MyObject> type. I'm calling the Template using UIHint over the collection property n the parent ViewModel. The grid on the EditorTemplate is however complete Widget-based now. It is working with the data array woth matching properties as of the actual ViewModel. How do I map the final rows of a kendo grid to the Model?

3 Answers, 1 is accepted

Sort by
0
Shafi
Top achievements
Rank 1
answered on 05 Jun 2016, 06:22 AM

Here is the grid attached. it is a part of an EditorTemplate but the grid is now 100% client-side working against a local data source like-a-so:

function createRandomData() {
      var data = [];
 
      data.push({
        ParkingServiceId: 1,
        TerminalId: 0,
        ServiceId: 54,
        ParkingCardNumber: 'CARD113',
        ParkingCardIssueDate: '01-May-16',
        ParkingCardExpiryDate: '01-May-17',
        ParkingCardGroup: 'SomeText1',
        ServiceFee: 940
      });
      data.push({
        ParkingServiceId: 2,
        TerminalId: 1,
        ServiceId: 164,
        ParkingCardNumber: 'CARD114',
        ParkingCardIssueDate: '01-May-16',
        ParkingCardExpiryDate: '01-Nov-16',
        ParkingCardGroup: 'SomeText2',
        ServiceFee: 470
      });
      data.push({
        ParkingServiceId: 3,
        TerminalId: 2,
        ServiceId: 1554,
        ParkingCardNumber: 'CARD115',
        ParkingCardIssueDate: '01-May-16',
        ParkingCardExpiryDate: '01-Aug-16',
        ParkingCardGroup: 'SomeText3',
        ServiceFee: 235
      });
 
      return data;
  }
 
var kendoDataSource = new kendo.data.DataSource({
  data: createRandomData(),
  pageSize: 5,
  schema: {
    model: {
      id: "ParkingServiceId",
      fields: {
        ParkingServiceId: { type: 'number', editable: false },
        TerminalId: { type: 'number', validation: { required: true } },
        ServiceId: { type: 'number', validation: { required: true } },
        ParkingCardNumber: { type: 'string' },
        ParkingCardIssueDate: { type: 'string', validation: { required: true } },
        ParkingCardExpiryDate: { type: 'string', validation: { required: true } },
        ParkingCardGroup: { type: 'string' },
        ServiceFee: { type: 'number', validation: { min: 0, required: true } }
      }
    }
  }
});

This anonymous array is a 100% replica of the intended ViewModel (that I wanted to bind with Helper originally but epic-failed):

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
 
namespace Custom.Services.CarPark.Presentation.Web.Models
{
    public class ParkingServiceDetailViewModel : ViewModelBase, IValidatableObject
    {
 
        [Display(Name = "Parking Service Id")]
        public int ParkingServiceId { get; set; }
 
        [UIHint("TerminalId")]
        [Display(Name = "Terminal")]
        public int TerminalId { get; set; }
 
        [UIHint("ServiceId")]
        [Display(Name = "Service")]
        public int ServiceId { get; set; }
 
        [Display(Name = "Card #")]
        [DataType(DataType.Text)]
        public string ParkingCardNumber { get; set; }
 
        [Display(Name = "Issued On")]
        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:dd-MMM-yyyy}", ApplyFormatInEditMode = true, ConvertEmptyStringToNull = true)]
        public DateTime? ParkingCardIssueDate { get; set; }
 
        [Display(Name = "Expiry")]
        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:dd-MMM-yyyy}", ApplyFormatInEditMode = true, ConvertEmptyStringToNull = true)]
        public DateTime? ParkingCardExpiryDate { get; set; }
 
        [Display(Name = "Group")]
        [DataType(DataType.Text)]
        public string ParkingCardGroup { get; set; }
 
        [Display(Name = "Fee")]
        [DataType(DataType.Currency)]
        public decimal? ServiceFee { get; set; }
 
        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            if (TerminalId < 0)
            {
                yield return new ValidationResult("Terminal Id is required.", new[] { "TerminalId" });
            }
        }
    }
}

On the main view, I have stopped the Save button from posting to controller:

function submit_OnClick(e) {
  e.preventDefault();
}

No, since the client-side grid has no knowledge of the actual MVC model, I need to JSON the grids datasource and submit it OR use Model bindings to my advantage and update the controller's API from:

[HttpPost]
public async Task<ActionResult> Save(ParkingCardRequestViewModel cardRequest)
{
    // ...
}

To:

[HttpPost]
public async Task<ActionResult> Save(ParkingCardRequestViewModel cardRequest, IEnumerable<ParkingServiceDetailViewModel> bookedServices)
{
    // ...
}

I need help regarding the way to g as the HTML generated by the Kendo Grid is not following simple object names that, as per my understanding, are required by Model Binder.

0
Daniel
Telerik team
answered on 07 Jun 2016, 05:43 AM
Hello,

Unfortunately I am not sure if I understand the setup based on the code and the description. From what I understand you have parent ViewModel that holds a list property that should be bound to the grid but I am not sure if I understand how should the data be sent to the server. Should the data be posted with a form? If yes, then please check this code-library project. If this is not the case then please provide the code that you attempted to use for the grid and clarify how should the data be submitted.

Regards,
Daniel
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
Shafi
Top achievements
Rank 1
answered on 08 Jun 2016, 05:49 AM

Here is how I resolved the issue:

function submit_OnClick(e) {
    e.preventDefault();
 
    var servicesBooked = $("#serviceDetailsGrid").data('kendoGrid').dataSource.data().toJSON();
    var stringed = JSON.stringify(servicesBooked);
 
    $('#serviceList').val(stringed);
    $('form').submit();
}

I captured the submission and converted the data from the grid to JSON. I updated a hidden filed called serviceList:

<input id="serviceList" name="serviceList" type="hidden" />

The javascript and the input is on one EditorTemplate and the Grid is a child EditorTemplate but since everything becomes one fine sandwich...

Now. on the submission, the controller is now declared as so:

public async Task<ActionResult> Save(ParkingCardRequestViewModel cardRequest, string serviceList)
        {
        }

And MVC binding takes care of the rest.

Tags
Grid
Asked by
Shafi
Top achievements
Rank 1
Answers by
Shafi
Top achievements
Rank 1
Daniel
Telerik team
Share this question
or