Generic Knockout View Model, Core, Validation Helper, & Dataservice
Generic Knockout View Model, Core, Validation Helper to add Custom errors to jQuery Validation, & Dataservice.
by cjgaudin
HTML
<script src="https://raw.github.com/SteveSanderson/knockout/master/build/output/knockout-latest.debug.js"></script>
<script src="https://raw.github.com/SteveSanderson/knockout.mapping/master/build/output/knockout.mapping-latest.debug.js"></script>
<script type="text/javascript">
(function ($, undefined) {
$(document).ready(function () {
var serverModel = @Html.Interpret(Model);
var viewModel = codeFuzion.genericViewModel;
viewModel.initialize(serverModel);
viewModel.setOptions({
baseLookupUrl: '@Url.Action("Base", "Lookup", new { area = "" })'
});
viewModel.bind();
$('#workItemTabs').tabs();
});
})(jQuery);
</script>
<div id="messageLog">
</div>
@using (Html.BeginForm("Edit", "Work", FormMethod.Post, new { @id = "workForm" })) {
<div id="workItemTabs" style="min-height: 500px;">
<ul>
<li><a href="#generalTab">General</a></li>
<li><a href="#locationTab">Location</a></li>
<li><a href="#commentsTab">Journal</a></li>
</ul>
<div id="generalTab">
@Html.Partial("_EditGeneral", Model)
</div>
<div id="locationTab">
@Html.Partial("_EditLocation", Model)
</div>
<div id="commentsTab">
@Html.Partial("_EditComments", Model)
</div>
</div>
<p id="saveButtonContent">
<a id="saveWorkButton" class="metro-button" data-bind="click: save">Save Work</a>
</p>
@Html.ValidationSummary(false)
}
<div id="dialogComment" data-bind="with: selectedComment">
<div data-bind="ifnot: $parent.editCommentMode">
@Html.Action("Add", "Comment")
</div>
<div data-bind="if: $parent.editCommentMode">
@Html.Action("Edit", "Comment")
</div>
</div>
CSS
/* Styles for Notifications */
.notification {
-webkit-background-size: 40px 40px;
-moz-background-size: 40px 40px;
background-size: 40px 40px;
background-image: -webkit-gradient(linear, left top, right bottom, color-stop(.25, rgba(255, 255, 255, .05)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, rgba(255, 255, 255, .05)), color-stop(.75, rgba(255, 255, 255, .05)), color-stop(.75, transparent), to(transparent));
background-image: -webkit-linear-gradient(135deg, rgba(255, 255, 255, .05) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .05) 50%, rgba(255, 255, 255, .05) 75%, transparent 75%, transparent);
background-image: -moz-linear-gradient(135deg, rgba(255, 255, 255, .05) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .05) 50%, rgba(255, 255, 255, .05) 75%, transparent 75%, transparent);
background-image: -ms-linear-gradient(135deg, rgba(255, 255, 255, .05) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .05) 50%, rgba(255, 255, 255, .05) 75%, transparent 75%, transparent);
background-image: -o-linear-gradient(135deg, rgba(255, 255, 255, .05) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .05) 50%, rgba(255, 255, 255, .05) 75%, transparent 75%, transparent);
background-image: linear-gradient(135deg,...
JavaScript
//-----------------------------------------------------------------------------------
//----------------------------Application View Model -------------------------------
//-----------------------------------------------------------------------------------
// verify the namespace exists
var codeFuzion = codeFuzion || {};
codeFuzion.genericViewModel = (function ($, ko, undefined) {
var viewModel = codeFuzion.genericViewModel = codeFuzion.genericViewModel || {};
//Default options for this view model
var options = {
formSelector: '#myForm',
messageSelector: '#messageLog',
tabSelector: '#myItemTabs',
baseLookupUrl: null
};
//---------------PUBLIC FUNCTIONS--------------------
viewModel.initialize = function (serverModel) {
//pull the model to bind to
viewModel.model = ko.mapping.fromJS(serverModel.Model);
//Need to include the Protected Observable Library
viewModel.model.Comments = ko.observableArray(ko.toProtectedObservableItemArray(viewModel.model.Comments));
//Selected Items
viewModel.selectedComment = ko.observable(null);
viewModel.editCommentMode = ko.observable(false);
//pull the lookup items, etc., or handling something like dates in the model since you cant bind date to an input
viewModel.stateLookup = serverModel.States;
viewModel.parishLookup = ko.observableArray(serverModel.Parishes);
// viewModel.DueDateFormatted = ko.computed({
// read: function () {
// return convertDateString(viewModel.model.DueDate());
// },
// write: function (value) {
// if (value)
// viewModel.model.DueDate(new Date(value));
// },
// owner: viewModel
// });
//Tracker
//viewModel.tracker = new...