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...