KO multi date picker

by whelkaholism

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.2/moment.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
<a data-bind="click: init">INIT</a>
<hr/>
<div data-bind="multiDatePicker: Items"></div>
<hr/>
<ul data-bind="foreach: Items">
    <li data-bind="text: dt"></li>
</ul>

CSS

.ui-multi-date-picker {
	border: 1px solid #aaaaaa;
	padding: 0.1em;
	display: inline-block;
}

.ui-multi-date-picker ul {
    display: inline-block;
}

.ui-multi-date-picker li {
    display: inline-block;
    background: #dddddd;
    padding: 0.1em;
    margin-right: 0.1em;
}

.ui-multi-list-delete {
    margin-left: 0.1em;
}

.ui-multi-list-add {
    margin-left: 0.1em;
}

JavaScript

// Shortcut to moment to avoid constantly creating extra date string fields
ko.bindingHandlers.dateText = {
	update: 
		function(el, f_valueaccessor, allbindings, viewmodel, bindingcontext) 
		{
			// Get current value of supplied value
			var val = ko.unwrap(f_valueaccessor());            
      var dt = ko.unwrap(val.dt);
			var format = allbindings.get('dateTextFormat') || 'DD/MM/YYYY';
                        
			$(el).html(dt ? moment(dt).format(format) : '');
		}
};


ko.bindingHandlers.multiDatePicker = {
	init: 
		function(el, f_valueaccessor, allbindings, viewmodel, bindingcontext) 
		{
            var field = f_valueaccessor();
			var val = ko.unwrap(field);
            var options = {};
            
            if(!ko.isObservable(field))
            {                
            	options = val.options;
                
                val = val.boundField;
            }
            
            var markup =
                '<div class="ui-multi-date-picker">' +
                  '<ul data-bind="foreach: MultiDates">' +
                    '<li>' + 
                      '<span data-bind="dateText: $data"></span>' +
                      '<a data-bind="click: deleteItem.bind($data, $index())"><i class="ui-multi-list-delete fa fa-times"></i></a>' +
                    '</li>' +
                  '</ul>' +
            	  '<a class="ui-multi-list-add" data-bind="click: addItem"><i class="ui-multi-list-delete fa fa-plus"></i></a>' +
                  '<input type="text" tabindex="-1" style="position:absolute;opacity:0;width:1px"/>' +
                '</div>';             	
            
            $(markup).appendTo(el);
            
			options.dateFormat = options.dateFormat || 'dd/mm/yy';
			options.firstDay = typeof(options.firstDay) != 'undefined' ? options.firstDay : 1;
			options.changeYear =  typeof(options.changeYear) != 'undefined' ? options.firstDay : true;
			options.sortOrder =  typeof(options.keepSorted) != 'undefined' ? options.sortOrder :...