Knockout Js vs Pims
by rpallas
HTML
<script src="http://knockoutjs.com/downloads/knockout-3.0.0.js"></script>
<script src="https://raw.github.com/Knockout-Contrib/Knockout-Validation/master/Dist/knockout.validation.min.js"></script>
<!-- ======= Knockout Templates ======= -->
<script id="branchDetails" type="text/html">
<p><a data-bind="click: toggleEditPanel" class="button edit">Edit Gp Branch</a></p>
<div class="content">
<span data-bind="text: name"></span> <br/>
<span data-bind="text: addressFirstLine"></span> <br/>
<span data-bind="text: addressCity"></span> <br/>
<span data-bind="text: postcode"></span> <br/>
</div>
</script>
<script id="branchEditDetails" type="text/html">
<p><a data-bind="click: toggleEditPanel" class="button edit">Cancel Edit</a></p>
<div class="content">
<p><label for="name">GP Branch name</label>
<input type="text" id="name" data-bind="value: name" name="name"></p>
<p><label for="addressFirstLine">First line of address</label>
<input type="text" id="addressFirstLine" data-bind="value: addressFirstLine" name="addressFirstLine"></p>
<p><label for="addressCity">Town / City</label>
<input type="text" id="addressCity" data-bind="value: addressCity" name="addressCity"></p>
<p><label for="postcode">Postcode</label>
<input type="text" id="postcode" data-bind="value: postcode" name="postcode"></p>
<button data-bind="click: saveBranch">Save GpBranch</button>
</div>
</script>
<!-- ======= [END] Knockout Templates ======= -->
<div id="container">
<h1>Knockout Js vs Pims</h1>
<h2>A simple edit module typically found in Pims</h2>
<h3>Manage GP Branches in Wonderland Gp Practice</h3>
<p><a class="button" data-bind="click: addBranch"><span>Add GP Branch</span></a></p>
<!-- ko template: {name: branchDetailsView, foreach: gpBranches} -->
<!-- /ko -->
</div>
<div id="debug" style="clear: both">
<hr />
...
CSS
body
{
background:#1a1a1a;
text-align:left;
color:#666;
width:700px;
font-size:14px;
font-family:georgia, 'time new romans', serif;
margin:0 auto;
padding:0;
}
a:focus
{
outline:none;
}
h1
{
font-size:34px;
font-family:verdana, helvetica, arial, sans-serif;
letter-spacing:-2px;
color:#9FC54E;
font-weight:700;
padding:20px 0 0;
}
h2
{
font-size:24px;
font-family:verdana, helvetica, arial, sans-serif;
color:#444;
font-weight:400;
padding:0 0 10px;
}
h3
{
font-size:14px;
font-family:verdana, helvetica, arial, sans-serif;
letter-spacing:-1px;
color:#fff;
font-weight:700;
text-transform:uppercase;
margin:0;
padding:8px 0;
}
p
{
color:#ccc;
line-height:22px;
margin:20px 0;
padding:0 0 10px;
}
#container
{
clear:both;
margin:0;
padding:0;
}
#container a.button
{
background:#9FC54E;
border:1px solid #9FC54E;
-moz-border-radius-topright:20px;
-webkit-border-top-right-radius:20px;
-moz-border-radius-bottomleft:20px;
-webkit-border-bottom-left-radius:20px;
text-decoration:none;
font-size:16px;
letter-spacing:-1px;
font-family:verdana, helvetica, arial, sans-serif;
color:#fff;
font-weight:700;
padding:20px;
}
#container a.button:hover
{
background:#a0a0a0;
border:1px solid #ccc;
-moz-border-radius-topright:20px;
-webkit-border-top-right-radius:20px;
-moz-border-radius-bottomleft:20px;
-webkit-border-bottom-left-radius:20px;
text-decoration:none;
font-size:16px;
letter-spacing:-1px;
font-family:verdana, helvetica, arial, sans-serif;
color:#fff;
font-weight:700;
padding:20px;
}
#container a.button.edit
{
float:right;
}
#container a.button.edit:hover
{
float:right;
}
.content
{
font-style:normal;
font-family:helvetica, arial, verdana, sans-serif;
color:#fff;
background:#333;
border:1px solid #444;
-moz-border-radius-topright:20px;
-webkit-border-top-right-radius:20px;
-moz-border-radius-bottomleft:20px;
...
JavaScript
var pims = pims || {};
ko.validation.rules.pattern.message = 'Invalid.';
ko.validation.configure({registerExtenders: true, messagesOnModified: true, insertMessages: true, parseInputAttributes: true, messageTemplate: null});
$(function () {
var GpBranch = function () {
this.name = ko.observable("").extend({ minLength: 2, maxLength: 15 });
this.addressFirstLine = ko.observable("").extend({
required: { message: 'Please supply the first line of your address.' }
});
this.addressCity = ko.observable("");
this.postcode = ko.observable("").extend({
required: true,
pattern: {
message: 'Please enter a valid postcode.',
//params: '^[a-zA-Z]{1,2}\d{1,2}\s?\d[a-zA-Z]{2}$'
params: '.+'
}
});
this.isInEditMode = ko.observable(false);
};
var branches = [
new GpBranch()
.name("Gp Branch One")
.addressFirstLine("Lane One")
.addressCity("One City")
.postcode("LL1 1LL"),
new GpBranch()
.name("Gp Branch Two")
.addressFirstLine("Lane Two")
.addressCity("Two City")
.postcode("TT2 2TT"),
new GpBranch()
.name("Gp Branch Three")
.addressFirstLine("Lane Three")
.addressCity("Three City")
.postcode("EE3 3EE")
];
pims.viewModel = function () {
// private fields
var self = this;
gpBranches = ko.observableArray(branches),
// private functions
addBranch = function () {
self.gpBranches.unshift(new GpBranch().isInEditMode(true));
},
saveBranch = function (gpBranch) {
if (pims.viewModel.errors().length == 0) {
$.ajax({
url: '/echo/json/',
data: JSON.stringify(gpBranch),
contentType: 'application/json',
...