Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A KnockoutJS component to create date/time inputs that work together to update a single observable value. This value gets passed in as a parameter, `datetimeObservable`. This value is updated in realtime on every keypress.
// Usage: <datetime params="id: 'any-unique-id', datetimeObservable: observableDateTimeObjectFromParentViewModel, default: defaultDateObject, min: new Date(), max: maxDateObject"></datetime>
ko.components.register('datetime', {
viewModel: function(params) {
this.dateid = params.id + '-date';
this.timeid = params.id + '-time';
this.date = '';
this.time = '';
this.datetimeObservable = params.datetimeObservable;
this.datetimeObservable.subscribe(function(datetime) {
if (datetime === null) {
return;
}
this.date = datetime.getFullYear() + '-' + ('00' + (datetime.getMonth() + 1)).slice(-2) + '-' + ('00' + datetime.getDate()).slice(-2)
this.time = ('00' + datetime.getHours()).slice(-2) + ':' + ('00' + datetime.getMinutes()).slice(-2);
dateElm = document.getElementById(this.dateid);
timeElm = document.getElementById(this.timeid);
if (
dateElm && timeElm &&
this.date.match(/\d{4}-\d{2}-\d{2}/) && this.time.match(/\d{2}:\d{2}/)
) {
document.getElementById(this.dateid).value = this.date;
document.getElementById(this.timeid).value = this.time;
}
}.bind(this));
if (params.default) {
this.datetimeObservable(params.default);
}
['min', 'max'].forEach(function(minmax) {
if (params[minmax]) {
this[minmax] = params[minmax].getFullYear() + '-' + ('00' + (params[minmax].getMonth() + 1)).slice(-2) + '-' + ('00' + params[minmax].getDate()).slice(-2)
} else { this[minmax] = ''; }
});
this.update = function(data, event) {
dateElm = document.getElementById(this.dateid);
timeElm = document.getElementById(this.timeid);
if (
dateElm.value && timeElm.value &&
dateElm.value.match(/\d{4}-\d{2}-\d{2}/) && timeElm.value.match(/\d{2}:\d{2}/)
) {
data.datetimeObservable(new Date(dateElm.value + 'T' + timeElm.value));
} else {
data.datetimeObservable(null);
}
}.bind(this);
},
template:
'<div class="datetime-component"><div class="datetime-component-date">' +
'<input type="date" data-bind="attr: {id: dateid, min: min, max: max}, value: date, event: {change: update}">' +
'</div><div class="datetime-component-time">' +
'<input type="time" data-bind="attr: {id: timeid}, value: time, event: {change: update}">' +
'</div></div>'
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment