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

Working with timespans

3 Answers 638 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Mikael
Top achievements
Rank 2
Mikael asked on 27 Feb 2013, 09:41 AM
Hello.
I need some assistance with a grid where I'm attempting to work with a timespan value.
This is my grid code right now:
<div class="twelve columns">
 @(Html.Kendo().Grid<TimelineMarker>()
  .Name("TimelineMarkers")
  .Columns(columns =>
    {
    columns.Bound(p => p.Order).Width(60);
    columns.Bound(p => p.Time).ClientTemplate("#= Time.Minutes #:#= Time.Seconds #:#= Time.Milliseconds #");
    columns.Bound(p => p.Text);
   columns.Bound(p => p.Type);
    columns.Command(command => { command.Edit(); command.Destroy(); }).Width(200);
  })
   .ToolBar(toolbar => toolbar.Create())
   .Editable(editable => editable.Mode(GridEditMode.InLine))
   .Pageable()
   .Sortable()
   .Scrollable()
   .DataSource(dataSource => dataSource
   .Ajax()
   .Events(events => events.Error("error_handler"))
  .Model(model =>
   {
    model.Id(p => p.TimelineMarkerId);
    model.Field(x => x.Media.Name).Editable(false);
    model.Field(x => x.MediaId).DefaultValue(Model.Media.MediaId);
 
   })
   .Create(update => update.Action("TimelineMarker_Create", "MediaAdminService"))
   .Read(read => read.Action("TimelineMarker_Read/"+Model.Media.MediaId, "MediaAdminService"))
   .Update(update => update.Action("TimelineMarker_Update", "MediaAdminService"))
   .Destroy(update => update.Action("TimelineMarker_Destroy", "MediaAdminService"))
   )
  )
</div>
I made a custom editor helper for editing the timespan in the way i'd like to, and it looks like this:
@model TimeSpan
@using Kendo.Mvc.UI
<div id="timespanEditor">
    <div class="three columns">
        @(Html.Kendo().IntegerTextBoxFor(m => m.Minutes)
          .Name("timespanpickerMinute")
          .Min(new TimeSpan(0, 0, 0).Seconds)
          )
    </div>
    <div class="three columns">
        @(Html.Kendo().IntegerTextBoxFor(m => m.Seconds)
      .Name("timespanpickerSecond")
      .Min(new TimeSpan(0, 0, 0).Seconds)
      )
    </div>
    <div class="three columns">
        @(Html.Kendo().IntegerTextBoxFor(m => m.Milliseconds)
          .Name("timespanpickerMillisecond")
          .Min(new TimeSpan(0, 0, 0).Seconds)
              )
    </div>
</div>
First problem, I need to be able to bind the Timespan Helper to the actual TimeSpan values.  I understand that Javascript doesn't support TimeSpan, and converts it to something like this:
,"Time":{"Hours":0,"Minutes":15,"Seconds":14,"Milliseconds":230,"Ticks":9142300000,"Days":0,"TotalDays":0.01058136574074074,"TotalHours":0.25395277777777775,"TotalMilliseconds":914230,"TotalMinutes":15.237166666666667,"TotalSeconds":914.2299999999999}
How can I modify my helper to manipulate this Json object instead and get it to update the values in the objects that I'm sending back to the database.

Second problem is, when I attempt to create a new object inline, I get a Javascript error telling me that Time is not defined.
If I remove the ClientTemplate from the Time column in the grid code I don't get that error. The ClientTemplate code is something I found on these forums, but in that example they only used Minutes, Seconds like this:
ClientTemplate("#= Minutes #:#= Seconds #:#= Milliseconds #");
But when I tried that I got a "Minutes is not defined" error.
Any advice on how to work around this would be cool.

I've considered just making a TimeSpan helper class with int properties for the values I need to edit and convert it back and forth in my .net code. But it depends on how much work it will be to get what I already have working, it would be nice to be able to work with the timespan objects in the kendo grid.

3 Answers, 1 is accepted

Sort by
0
Daniel
Telerik team
answered on 01 Mar 2013, 09:36 AM
Hello Mikael,

The values are not updated because the name of the NumericTextBoxes is overridden. The name is used for the fields binding so not the correct fields will be updated this way. Removing the Name should resolve the problem:

@model TimeSpan
@using Kendo.Mvc.UI
<div id="timespanEditor">
    <div class="three columns">
        @(Html.Kendo().IntegerTextBoxFor(m => m.Minutes)         
          .Min(new TimeSpan(0, 0, 0).Seconds)
          )
    </div>
    <div class="three columns">
        @(Html.Kendo().IntegerTextBoxFor(m => m.Seconds)     
      .Min(new TimeSpan(0, 0, 0).Seconds)
      )
    </div>
    <div class="three columns">
        @(Html.Kendo().IntegerTextBoxFor(m => m.Milliseconds)         
          .Min(new TimeSpan(0, 0, 0).Seconds)
              )
    </div>
</div>
As for the the error when creating an item, the default value for the objects is null so accessing its field will cause an error. You can specify a different default value through the DataSource Model in order to avoid the error:
.Model(model =>
   {
    model.Id(p => p.TimelineMarkerId);
    model.Field(x => x.Media.Name).Editable(false);
    model.Field(x => x.MediaId).DefaultValue(Model.Media.MediaId);
    model.Field(x => x.Time).DefaultValue(new TimeSpan());
   })
Regards,
Daniel
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Mikael
Top achievements
Rank 2
answered on 04 Mar 2013, 11:18 AM
Hello.
I'v implemented both changes but I'm still getting the "Time field is required" error, when I attempt to create new ones AND when I attempt to edit an existing object. In my browser console I get this warning when I attempt to submit the changes:
EDIT: Actually this warning pops up when I attempt to edit any of the values using the helper.
JQMIGRATE: jQuery.parseJSON requires a valid JSON string jquery-migrate-1.1.1.js:40
console.trace() jquery-migrate-1.1.1.js:42
migrateWarn jquery-migrate-1.1.1.js:42
jQuery.parseJSON jquery-migrate-1.1.1.js:222
onError jquery.validate.unobtrusive.js:43
p.isFunction.f jquery.min.js:2
$.extend.showLabel jquery.validate.js:652
$.extend.defaultShowErrors jquery.validate.js:608
$.extend.showErrors jquery.validate.js:387
$.extend.element jquery.validate.js:364
$.extend.defaults.onfocusout jquery.validate.js:228
delegate jquery.validate.js:314
(anonymous function) jquery.validate.js:1181
p.event.dispatch jquery.min.js:2
g.handle.h jquery.min.js:2
p.event.trigger jquery.min.js:2
jQuery.event.trigger jquery-migrate-1.1.1.js:483
p.event.simulate jquery.min.js:2
d
The raw data beeing sendt from the browser looks like this:
HTTP/1.1 200 OK
Cache-Control: private, s-maxage=0
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/8.0
X-AspNetMvc-Version: 4.0
X-AspNet-Version: 4.0.30319
X-MiniProfiler-Ids: ["db3df6d1-0c7e-4786-83aa-97e2c98b7a8a"]
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcTWlrYWVsXERyb3Bib3hcVmlzdWFsU3R1ZGlvXEJsYWNrQmlyZFxCbGFja0JpcmRcTWVkaWFBZG1pblNlcnZpY2VcVGltZWxpbmVNYXJrZXJfVXBkYXRl?=
X-Powered-By: ASP.NET
Date: Mon, 04 Mar 2013 11:35:29 GMT
Content-Length: 354
 
{"Data":[{"TimelineMarkerId":7,"MediaId":7,"Media":null,"Order":1,"Time":{"Hours":0,"Minutes":0,"Seconds":0,"Milliseconds":0,"Ticks":0,"Days":0,"TotalDays":0,"TotalHours":0,"TotalMilliseconds":0,"TotalMinutes":0,"TotalSeconds":0},"Type":null,"Text":"Test2"}],"Total":1,"AggregateResults":null,"Errors":{"Time":{"errors":["The Time field is required."]}}}
(From fiddler) as you can see the Time values are are zero.
 
Any suggestions?
0
Daniel
Telerik team
answered on 06 Mar 2013, 11:59 AM
Hello Mikael,

The DefaultModelBinder does not support the TimeSpan type. You should implement a custom model binder for the type and register it in the Global.asax Application_Start method. Another option is to use a custom object with the needed properties as parameter. In this case however, you will also need to remove the ModelState error or disable the explicit validation for value fields.

Regards,
Daniel
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
Tags
Grid
Asked by
Mikael
Top achievements
Rank 2
Answers by
Daniel
Telerik team
Mikael
Top achievements
Rank 2
Share this question
or