Mapping plugin test for complex view model
by bombo
HTML
<script src="http://rniemeyer.github.com/KnockMeOut/Scripts/jquery.tmpl.js"></script>
<script src="http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-1.2.1.debug.js"></script>
<script src="https://github.com/SteveSanderson/knockout.mapping/raw/master/build/output/knockout.mapping-latest.debug.js"></script>
<div class="container">
<div data-bind="safeTemplate: { name: 'AddressEntry', data: Addresses()[0] }"></div>
<div data-bind="safeTemplate: { name: 'AddressEntry', data: Addresses()[2] }"></div>
</div>
<div class="container">
<div data-bind="safeTemplate: { name: 'AddressEntry', data: Addresses()[1] }"></div>
<div data-bind="safeTemplate: { name: 'AddressEntry', data: Addresses()[3] }"></div>
</div>
<div id="debug">
<h2>Debug: </h2>
<div id="output" data-bind="html: formatJson(ko.toJSON(AddressModel))"></div>
</div>
<!-- Templates -->
<script id="AddressEntry" type="text/html">
<div class="entry">
{{if $item.check }}
<div class="field">
<label for="firstname">First name: </label>
<input type="text" id="firstname" data-bind="value: Firstname" />
</div>
<div class="field">
<label for="lastname">Last name: </label>
<input type="text" id="lastname" data-bind="value: Lastname" />
</div>
<div class="field">
<label for="street">City: </label>
<input type="text" id="street" data-bind="value: City" />
</div>
<div class="field">
<label for="addressType">Type: </label>
<select id="addressType"
data-bind="
options: AddressTypes,
value: AddressType,
optionsValue: 'Element',
optionsText: 'Value'
"
></select>
</div>
<div...
CSS
.container {
border: 1px solid #aaa;
z-index: 10;
-moz-box-shadow: 2px 2px 5px #888888; /* Firefox 3.6 and earlier */
-webkit-box-shadow: 2px 2px 5px #888888; /* Safari and Chrome */
box-shadow: 2px 2px 5px #888888;
width: 45%;
border-radius: 10px;
-moz-border-radius: 10px; /* Firefox 3.6 and earlier */
padding: 10px;
float: left;
margin-right: 10px;
}
.entry {
margin-top: 15px;
}
.field {
margin: 5px;
}
.field label {
display: inline-block;
width: 120px;
text-align: right;
}
.toolbox {
text-align: right;
}
button {
background: #ccc;
border: 1px solid #999;
cursor: pointer;
padding: 4px 8px;
border-radius: 4px;
-moz-border-radius: 4px; /* Firefox 3.6 and earlier */
-moz-box-shadow: 1px 1px 5px #888888; /* Firefox 3.6 and earlier */
-webkit-box-shadow: 1px 1px 5px #888888; /* Safari and Chrome */
box-shadow: 1px 1px 5px #888888;
}
button:hover {
background: #ccc;
border: none;
padding: 5px 9px;
-moz-box-shadow: none; /* Firefox 3.6 and earlier */
-webkit-box-shadow: none; /* Safari and Chrome */
box-shadow: none;
}
button:active {
background: #ccc;
border: none;
padding: 5px 9px;
-moz-box-shadow: 1px 1px 5px #888888 inset; /* Firefox 3.6 and earlier */
-webkit-box-shadow: 1px 1px 5px #888888 inset; /* Safari and Chrome */
box-shadow: 1px 1px 5px #888888 inset;
}
.container > .toolbox {
border-top: 1px dotted #999;
margin-top: 10px;
padding-top: 10px;
}
#debug {
clear: both;
padding-top: 20px;
}
#debug h2 {
border-top: 1px dotted #999;
padding-top: 10px;
font-family: sans-serif;
}
#output {
border: 1px solid black;
margin: 2px;
padding: 5px;
background: #ccc;
font-family: monospace;
}
JavaScript
function VM_AddressesHeader (ModelID, Action) {
this.ModelID = ModelID;
this.Action = Action;
}
function VM_AddressType(data) {
this.Element = data.Element;
this.Value = data.Value;
}
function VM_AddressesStructure (data) {
this.Header = AddressModel.Header;
this.GUID = '';
this.AddressType = '';
this.Lastname = '';
this.Firstname = '';
this.City = '';
ko.mapping.fromJS(data, {}, this);
// ValueHelps References
this.AddressTypes = AddressModel.AddressTypes;
// Actions
this.Update = function () {
ExecuteCmd('Update', this, AddressesCallback);
};
this.Delete = function () {
ExecuteCmd('Delete', this, AddressesCallback);
};
// SearchHelps
this.GetCities = function () { ExecuteCmd('GetCities', this, AddressesCallback); };
}
VM_AddressesStructure.prototype.toJSON = function() {
var copy = ko.toJS(this);
delete copy.AddressTypes;
delete copy.__ko_mapping__;
return copy;
};
var AddressModel = {
// VM_AddressesHeader
Header: new VM_AddressesHeader("b5f70c49-4fe2-4b29-86a4-2f97fc303ad0", "GetDetails"),
// VM_AdressesStructure
Addresses: ko.observableArray(),
// ValuesHelps
AddressTypes: ko.observableArray(),
// Global Actions
GetDetails: function () {
ExecuteCmd('GetDetails', AddressModel, AddressesCallback);
},
};
AddressModel.Add = function () {
this.Addresses.push(new VM_AddressesStructure ());
}.bind(AddressModel);
AddressModel.toJSON = function () {
var copy = ko.toJS(this);
delete copy.AddressTypes;
delete copy.__ko_mapping__;
return copy;
};
var first = true;
function AddressesCallback(viewModel, data) {
if (first) {
var mapping = {
'Addresses' : {
create: function (options) {
return new VM_AddressesStructure (options.data);
},
key: function (data) {
...