Click counter

Description

This sample shows how to create a simple model and apply multiple bindings that define view appearance depending on the certain state.

The sample calculates button clicks. When button is clicked 3 times it becomes inactive, instead the other button providing the ability to reset clicks number appears. Logic of click count is hosted on the server and is set by RegisterClick and ResetClicks methods. HasClickedTooManyTimes computed property is subscribed for the the property containing the number of clicks NumberOfClicks. It manages availability of the main button and ability to reset click number.

The original example: http://knockoutjs.com/examples/clickCounter.html

Live example

You've clicked times
That's too many clicks! Please stop before you wear out your fingers.

Model

public class ClickCounterModel
{
    public int NumberOfClicks { get; set; }

    [Computed]
    [ScriptIgnore]
    [JsonIgnore]
    public bool HasClickedTooManyTimes
    {
        get { return NumberOfClicks >= 3; }
    }

    public void RegisterClick()
    {
        NumberOfClicks++;
    }

    public void ResetClicks()
    {
        NumberOfClicks = 0;
    }
}

Razor

@using PerpetuumSoft.Knockout
@model KnockoutMvcDemo.Models.ClickCounterModel
@{
  var ko = Html.CreateKnockoutContext();
}
<div>You've clicked @ko.Html.Span(m => m.NumberOfClicks) times</div>
@ko.Html.Button("Click me", "RegisterClick", "ClickCounter").Disable(m => m.HasClickedTooManyTimes)
<div @ko.Bind.Visible(m => m.HasClickedTooManyTimes)>
  That's too many clicks! Please stop before you wear out your fingers.
  @ko.Html.Button("Reset clicks", "ResetClicks", "ClickCounter")
</div>

@ko.Apply(Model)

Controller

public class ClickCounterController : BaseController
{
    public ActionResult Index()
    {
        InitializeViewBag("Click counter");
        return View(new ClickCounterModel());
    }

    public ActionResult RegisterClick(ClickCounterModel model)
    {
        model.RegisterClick();
        return Json(model);
    }

    public ActionResult ResetClicks(ClickCounterModel model)
    {
        model.ResetClicks();
        return Json(model);
    }
}

Html (autogenerated)

<div>You've clicked <span data-bind="text : NumberOfClicks"></span> times</div>
<button data-bind="click : function() {executeOnServer(viewModel, &#39;/ClickCounter/RegisterClick&#39;);},disable : HasClickedTooManyTimes">Click me</button>
<div data-bind="visible : HasClickedTooManyTimes">
  That's too many clicks! Please stop before you wear out your fingers.
  <button data-bind="click : function() {executeOnServer(viewModel, &#39;/ClickCounter/ResetClicks&#39;);}">Reset clicks</button>
</div>

<script type="text/javascript"> 
var viewModelJs = {"NumberOfClicks":0};
var viewModel = ko.mapping.fromJS(viewModelJs); 
viewModel.HasClickedTooManyTimes = ko.computed(function() { try { return ((this.NumberOfClicks() < 3) == false)} catch(e) { return null; }  ;}, viewModel);
ko.applyBindings(viewModel);
</script>