Tuesday, June 6, 2017

KnockoutJS - Dirty Check - Observable Pattern

KnockoutJS and Its observable feature which help us to track each field's changes and notify to user un-saved data before leaving screen.


KnockoutJS (KO) is basically a JS library that enables Declarative Bindings using an ‘Observable’ ViewModel on the html view and follow observer pattern approach, enable UI to bind and refresh itself automatically whenever the data bound is modified

KnockoutJS two way binding - Observer pattern


Here is an example of knockoutJS  - observer pattern:


HTML View notify to model JS object, if any change occurred vice versa




KnockoutJS - Dirty Check - Observable Pattern
Dirty Check Message


ViewModel Js File:

Here is a viewmodel js file, which has set of observable fields, which will be bind with view.

function ProductViewModel(model)
{
    this.Price = ko.observable(0);
    this.ID = ko.observable(model.ID);
    this.Name = ko.observable(model.Name);
    this.Email = ko.observable(model.Email);
    this.Price = ko.observable(model.Price);
    this.Product = {
        ID: this.ID(),
        Name: this.Name(),
        Email: this.Email(),
        Price: this.Price()
    };

    this.initialState = ko.toJSON(this.Product);
    this.isDirty = ko.computed(function () {
        this.Product = {
            ID: this.ID(),
            Name: this.Name(),
            Email: this.Email(),
            Price: parseFloat(this.Price())
        };

        var newvalue = ko.toJSON(this.Product);

        if (this.initialState !== newvalue) {
            return true;
        }
        else {
            return false;
        }
    });
}

ViewModel Binding with View:

Here is code, which explains how to bind the viewmodel with HTML view.

<script type="text/javascript">
    var submitted = false;
    $(document).ready(function () {
        submitted = false;
        var data = @Html.Raw(new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(Model));
        ko.applyBindings(new ProductViewModel(data));
        $("form").submit(function () {
            submitted = true;
        });

        $(window).bind('beforeunload', function () {
            var dirty = $("#IsDirty").val();
            if (dirty == "true" && submitted == false) {
                return "You haven\'t saved your changes";
            }
        });
    }
    );
</script>

HTML View:

Here is an HTML code, which defines the layout of screen and define control on page.

@using (Html.BeginForm("DirtyView", "Home", FormMethod.Post, new { ID = "form", @class = "form-horizontal" }))
{
    @Html.ValidationSummary(false, "Please resolve the following errors and click'Save Changes' again :",
    new { @class = "alert alert-danger" })
    @Html.HiddenFor(m => m.ID)

    <input type="hidden" data-bind="value : IsDirty" id="IsDirty" />
    <div class="form-group">
        @Html.LabelFor(m => m.Name, new { @class = "control-label col-sm-2" })
        <div class="cpl-sm-10">
            @Html.TextBoxFor(m => m.Name, new { data_bind = "value: Name", @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Email, new { @class = "control-label col-sm-2" })
        <div class="cpl-sm-10">
            @Html.TextBoxFor(m => m.Email, new { data_bind = "value: Email", @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Price, new { @class = "control-label col-sm-2" })
        <div class="cpl-sm-10">
            @Html.TextBoxFor(m => m.Price, new { data_bind = "value: Price", @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
       <div class="col-sm-offset-2 col-sm-10">
           <button type="submit" class="btn, btn-success">Submit</button>
       </div>
    </div>
    <p>Dirty : <strong data-bind="text: IsDirty"></strong></p>
    <div>
        <strong>OLD Product</strong>
        <span data-bind="text: initialState"></span>
    </div>
}


Thanks for Visiting!!

No comments:

SQL Server - Identify unused indexes

 In this blog, we learn about the index usage information (SYS.DM_DB_INDEX_USAGE_STATS) and analyze the index usage data (USER_SEEKS, USER_S...