Binding DateTime to knockout view model with default JavaScriptSerializer
Asked Answered
H

2

12

I've just started using knockout and I'm running into trouble with DateTime Serialization and Deserialization using the JavaScriptSerializer.

I've updated the gifts model in Steves koListEditor example from his blog to include a Modified DateTime field:

public class GiftModel
{
    public string Title { get; set; }
    public double Price { get; set; }
    public DateTime Modified { get; set; }
}

Then I updated the Index.aspx to include the new field:

<asp:Content ContentPlaceHolderID="MainContent" runat="server">
    <h1>Gift list editor</h1>

    <p>You have asked for <span data-bind="text: gifts().length">&nbsp;</span> gift(s)</p>

    <form class="giftListEditor">
        <table> 
            <tbody data-bind="template: { name: 'giftRowTemplate', foreach: gifts }"></tbody> 
        </table>

        <button data-bind="click: addGift">Add Gift</button>
        <button data-bind="enable: gifts().length > 0" type="submit">Submit</button>
    </form>

    <script type="text/html" id="giftRowTemplate"> 
        <tr> 
            <td>Gift name: <input class="required" data-bind="value: Title, uniqueName: true"/></td> 
            <td>Price: \$ <input class="required number" data-bind="value: Price, uniqueName: true"/></td> 
            <td>Modified:  <input class="required date" data-bind="value: Modified, uniqueName: true"/></td> 
            <td><a href="#" data-bind="click: function() { viewModel.removeGift($data) }">Delete</a></td> 
        </tr>
    </script>

    <script type="text/javascript">
        var initialData = <%= new JavaScriptSerializer().Serialize(Model) %>;
        var viewModel = { 
            gifts : ko.observableArray(initialData), 

            addGift: function () { 
                this.gifts.push({ Title: "", Price: "", Modified:"" }); 
            },

            removeGift: function (gift) { 
                this.gifts.remove(gift); 
            },

            save: function() { 
                ko.utils.postJson(location.href, { gifts: this.gifts }); 
            } 
        }; 

        ko.applyBindings(document.body, viewModel);
        $("form").validate({ submitHandler: function() { viewModel.save() } });
    </script> </asp:Content>

However when the JavaScriptSerializer serializes the Model

var initialData = <%= new JavaScriptSerializer().Serialize(Model) %>;

the Modified Date is coming out like this:

DateTime problem

Also when using UK Dates I.e. 25/01/2011 the JavaScriptSerializer.Deserialize throws the following exception:

25/01/2011 is not a valid value for DateTime.

Although i'm having 2 problems here the main question is has anyone successfully used knockout from MVC 2 and got the JavaScriptSerializer working with DateTimes? I realise I could write my own JavaScriptSerializer but I was hoping there was a ready made solution out there :)

Here's the code for the updated version of Steve Sanderson's koListEditor:

Code on my skydrive

Thanks

Dave

However answered 25/1, 2011 at 20:32 Comment(1)
Anyone looking at the above.. you can use JSON.net to send dates to the client in what ever format you want.. see james.newtonking.com/archive/2009/02/20/…However
C
18

Well there are two options. You could do the simple fix by having a designated view model object which stores the preformated date time values as a string. This is generally what i do. I can then tryparse for the date value for validation.

The other option would be to implement a custom data binding. You can look at doing that here. This would be the more elegant approach. The nice thing about this apporach, you can then create you UI generation code on binding allowing you to add date picker to the ui in the process.

Chromoprotein answered 23/2, 2011 at 3:53 Comment(3)
Nice dude.. like the custom binding approach... Like i said to the other dude.. in the end I found JSON.net was the easiest fix.. as it allowed us to sent the dates down to the client in what ever format we wanted..However
Yeah, a big fan of the custom bindings approach. Hopefully i am not overdoing it in my project, but it makes the HTML so clean.Chromoprotein
An example of a custom binding handler for datesSalmonoid
C
1

Not an elegant solution, but it works:

data-bind="value: eval('new ' + Modified.slice(1,-1)), uniqueName: true"

Eval might be a security issue here depending on the context.

Cavanaugh answered 10/2, 2011 at 2:21 Comment(1)
I found a solution in the end.. I used JSON.net which allows you to specify your own Date Format. james.newtonking.com/archive/2009/02/20/… works a treat..However

© 2022 - 2024 — McMap. All rights reserved.