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

4 posts, 0 answers
  1. Shafi
    Shafi avatar
    43 posts
    Member since:
    Dec 2014

    Posted 02 Jun Link to this post

    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?

  2. Shafi
    Shafi avatar
    43 posts
    Member since:
    Dec 2014

    Posted 05 Jun Link to this post

    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.

  3. UI for ASP.NET MVC is VS 2017 Ready
  4. Daniel
    Admin
    Daniel avatar
    2117 posts

    Posted 07 Jun Link to this post

    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
  5. Shafi
    Shafi avatar
    43 posts
    Member since:
    Dec 2014

    Posted 08 Jun Link to this post

    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.

Back to Top
UI for ASP.NET MVC is VS 2017 Ready