Ok, so this is not a first, but I'm having a hard time getting a date. ;-)
I'm using Breeze, Knockout. Have a form where I wish to show short date.
<input name="start" data-bind="value: start" class="date required" required="required" placeholder="mm/dd/yyyy" style=" width:142px">
yields a long dateTime: Wed Aug 31 2011 20:00:00 GMT-0400 (Eastern Daylight Time).
Creating a method to format the desired short date accomplishes the goal of creating a short date, but my modelContext is unaware of any change notifications. So my object won't notify the screen of changes. I can possibly kludge this by trying to notify the dataContext on click, etc, but I'm hoping to not have that lost during the conversion.
function positionInitializer(posit) {
var shortDate = function (date) {
return date && moment.utc(date).isValid() ? moment.utc(date).format('L') : "";
};
posit.start = ko.observable(shortDate(posit.start()));
}
Are there any decent examples on how to do this?
I don't think I can convert when I make my call for the query b/c I am expanding the number of tables in my call & you can't do both.
var query = EntityQuery.from('Positions')
.where('id', '==', id)
.expand('Company, Projects')
.orderBy(orderBy.positions);
Thought I'd see what the hive-mind thinks...
There are a couple good options for handling date formatting using Knockout.
You could create a writable computed for your date value and do all your formatting and parsing there. For example:
var myViewModel = function(){
var self=this;
self.trueDate = ko.observable(new Date());
self.formattedDate = ko.computed({
read: function(){
return moment(self.trueDate()).format('L');
},
write: function(value){
self.trueDate(moment(value).toDate());
}
});
}
<input type="text" data-bind="value: formattedDate" />
Any time the backing observable "trueDate" is updated its observers will be alerted.
Another approach would be to build a custom data binding to format your data during binding and leave your view model simple.
var myViewModel = function(){
var self=this;
self.trueDate = ko.observable(new Date());
}
ko.bindingHandlers.dateString = {
init : function(element, valueAccessor) {
//attach an event handler to our dom element to handle user input
element.onchange = function(){
var value = valueAccessor();//get our observable
//set our observable to the parsed date from the input
value(moment(element.value).toDate());
};
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var value = valueAccessor();
var valueUnwrapped = ko.utils.unwrapObservable(value);
if (valueUnwrapped) {
element.value = moment(valueUnwrapped).format('L');
}
}
};
(Please keep in mind that the binding code above is untested, and doesn't check for invalid input, etc.)
And then your binding would be
<input type="text" data-bind="dateString : trueDate" />
I prefer the custom binding approach, since it can be easily reused for other dates and view models. A custom binding can also read other bindings on that element, so you could make the date format string configurable as a binding rather than hard-coding it to "L".
I hope this helps!