JSFiddle - React, Tailwind, and code Playground

by tlarson

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/2.2.1/knockout-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.3.5/knockout.mapping.js"></script>
<script src="https://raw.github.com/timrwood/moment/2.0.0/min/moment.min.js"></script>
<div id="paging1">
    <ul class="list paging-items">
        <li><!-- item -->
            <h4>Due in <span data-bind="text: daysUntilFirstDate" class="days-due"></span> days</h4>
            
            <h4><span data-bind="textualDate: firstDate" class="due-date"></span></h4>
        </li><!-- #item -->
        <li><!-- item -->
            <h4>Due in <span data-bind="text: daysUntilSecondDate" class="days-due"></span> days</h4>
            
            <h4><span data-bind="textualDate: secondDate" class="due-date"></span></h4>
        </li><!-- #item -->
    </ul>
</sdiv

JavaScript

// Count days due
function daysUntil(year, month, day) {
  var now = new Date(),
      dateEnd = new Date(year, month - 1, day), // months are zero-based
      days = (dateEnd - now) / 1000/60/60/24;   // convert milliseconds to days

  return Math.round(days);
}

function daysUntilDate(d) {
    return daysUntil(d.substr(0,4),d.substr(4,2),d.substr(6,2));
}

ko.bindingHandlers.textualDate = {
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var valueUnwrapped = ko.utils.unwrapObservable(valueAccessor());
        var textContent = moment(valueUnwrapped, "YYYYMMDD").format("MM/DD/YYYY");
        ko.bindingHandlers.text.update(element, function () { return textContent; });
    }
};

var viewModel = function(){
    var self = this;
    self.firstDate = ko.observable("20130701");
    self.daysUntilFirstDate = ko.computed(function() {
        return daysUntilDate(self.firstDate());
    });
    self.secondDate = ko.observable("20130901");
    self.daysUntilSecondDate = ko.computed(function() {
        return daysUntilDate(self.secondDate());
    });
};
ko.applyBindings(new viewModel());