JSFiddle - React, Tailwind, and code Playground
by jearles
HTML
<script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.2.2/js/bootstrap.min.js"></script>
<script src="http://knockoutjs.com/downloads/knockout-2.2.0.js"></script>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/base/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/jquery-ui.min.js"></script>
<script src="http://www.eyecon.ro/bootstrap-datepicker/js/bootstrap-datepicker.js"></script>
<div class="well">
<h3>Project Name
</h3>
<input type="text" name="txtProjectName" placeholder="Project Name" data-bind='value: ProjectName, valueUpdate: "afterkeydown"' />
<div class="alert alert-error" id="alertProjectName" data-bind='visible: ProjectName.hasError, text: ProjectName.validationMessage'>
</div>
</div>
<div class="well">
<h3>Project Timeline
</h3>
<table class="table table-striped">
<thead>
<tr>
<th>Start Date</th>
<th>End date</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input data-bind="datepicker: ProjectStartDate, datepickerOptions: { startDate: new Date() }" />
</td>
<td>
<input data-bind="datepicker: ProjectEndDate, datepickerOptions: { startDate: new Date() }" />
</td>
</tr>
</tbody>
</table>
</div>
<div class="well">
<h3>Project Description
</h3>
<textarea id="ProjectDetails" data-bind='value: ProjectDescription, valueUpdate: "afterkeydown"' placeholder="Enter Project Details ..."></textarea>
<div class="alert alert-error" id="alertProjectDescription" data-bind='visible: ProjectDescription.hasError, text: ProjectDescription.validationMessage'>
</div>
</div>
<div>
...
CSS
@import url('http://twitter.github.com/bootstrap/assets/css/bootstrap.css');
@import url('http://www.eyecon.ro/bootstrap-datepicker/css/datepicker.css');
JavaScript
ko.bindingHandlers.datepicker = {
init: function (element, valueAccessor, allBindingsAccessor) {
//initialize datepicker with some optional options
var options = allBindingsAccessor().datepickerOptions || {};
$(element).datepicker(options).on("changeDate", function (ev) {
var observable = valueAccessor();
observable(ev.date);
});
},
update: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
$(element).datepicker("setValue", value);
}
};
ko.extenders.required = function (target, overrideMessage) {
//add some sub-observables to our observable
target.hasError = ko.observable();
target.validationMessage = ko.observable();
//define a function to do validation
function validate(newValue) {
target.hasError(newValue ? false : true);
target.validationMessage(newValue ? "" : overrideMessage || "This field is required");
}
//initial validation
validate(target());
//validate whenever the value changes
target.subscribe(validate);
//return the original observable
return target;
};
var ProjectViewModel = {
ProjectName: ko.observable("").extend({ required: "" }),
ProjectDescription: ko.observable("").extend({ required: "" }),
ProjectStartDate: ko.observable(new Date("09/01/2011")).extend({ required: "" }),
ProjectEndDate: ko.observable(new Date("09/01/2011")).extend({ required: "" })
};
$(document).ready(function () {
ko.applyBindings(ProjectViewModel);
});