Bootstrap buttons for spa

Bootstrap 2.3.2 Knockout 3.0.0rc

HTML

<link rel="stylesheet" href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css">
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
<script src="http://knockoutjs.com/downloads/knockout-3.0.0rc.js"></script>
<div class="navbar navbar-inverse navbar-fixed-top">
    <div class="navbar-inner">
        <div class="container">
            <button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"> <span class="icon-bar"></span>
 <span class="icon-bar"></span>
 <span class="icon-bar"></span>

            </button> <a class="brand" href="#">Button samples</a>

            <!--/.nav-collapse -->
        </div>
    </div>
</div>

<h3>Samples</h3>

<hr/>

<h4>Vertical Group</h4>

<div class="row-fluid">
    <div data-toggle="buttons-radio" class="btn-group btn-group-vertical cvy" style="width:100px; margin:10px;">
        <button type="button" class="btn btn-primary btn-block ">Session Start</button>
        <button type="button" class="btn btn-danger btn-block active ">Stop</button>
    </div>
    <div data-toggle="buttons-radio" class="btn-group btn-group-vertical cvy" style="width:100px; margin:10px;">
        <button type="button" class="btn btn-success btn-block ">Session Start</button>
        <button type="button" class="btn btn-danger btn-block active ">Stop</button>
    </div>
</div>

<h4>Horizontal Group</h4>

<div class='row-fluid'>
    <div data-toggle="buttons-radio" class="btn-group cvy " style="width:150px; margin:10px;">
        <button type="button" class="btn btn-primary  ">Session Start</button>
        <button type="button" class="btn btn-danger  active ">Stop</button>
    </div>
    <div data-toggle="buttons-radio" class="btn-group cvy" style="width:200px; margin:10px;">
        <button type="button" class="btn btn-success  ">Session Start</button>
        <button type="button" class="btn btn-danger  active ">Stop</button>
   ...

CSS

span {
    color: #a00;
}
.cvy .btn:active, .cvy .btn.active {
    color: #ffffff;
    background-color: #757575 !important;
}
.cvy .btn.disabled, .cvy .btn[disabled] {
    background-color: #CECECE !important;
}
/* btn-danger - active color change */

/*
 .cvy .btn-danger:active, .cvy .btn-danger.active, .cvy .btn-danger.disabled, .cvy .btn-danger[disabled] {
    color: #ffffff;
    background-color: #757575 !important;
}
*/

/* btn-primary - active color change */

/*
 .cvy .btn-primary:active, .cvy .btn-primary.active, .cvy .btn-primary.disabled, .cvy .btn-primary[disabled] {
    color: #ffffff;
    background-color: #757575 !important;
}
*/

/* btn-success */

/*
 .cvy .btn-success:active, .cvy .btn-success.active, .cvy .btn-success.disabled, .cvy .btn-success[disabled] {
    color: #ffffff;
    background-color: #757575 !important;
}
*/

JavaScript

ko.bindingHandlers.radio = {
    init: function (element, valueAccessor, allBindings, data, context) {
        var observable = valueAccessor();
        if (!ko.isWriteableObservable(observable)) {
            throw "You must pass an observable or writable computed";
        }
        $(element).on('click', '.btn', function () { // use delegate click handler vs click handler for each btn
            var $btn = $(this),
                disabled = $btn.hasClass('disabled'),
                radioValue;
            if (!disabled) {
                radioValue = $btn.data("value") || $btn.attr("value") || $btn.text();
                observable(radioValue);
            }
        });
    },
    update: function (element, valueAccessor, allBindings, data, context) {
        var observable = valueAccessor(),
            options = allBindings(),
            disabled = ko.unwrap(options.disabled) || false;
        $(".btn", element).each(function () {
            var $btn = $(this),
                radioValue = $btn.data("value") || $btn.attr("value") || $btn.text();
            $btn.toggleClass("active", isTextMatch(observable, radioValue))
                .toggleClass('disabled', disabled);
        });

        function isTextMatch(a, b) {
            var src = ko.unwrap(a) || '',
                target = ko.unwrap(b) || '';
            return src.toLowerCase() === target.toLowerCase();
        }
    }
};


ViewModel = function () {
    this.paceMode = ko.observable('Instructor');
    this.correctness = ko.observable('Show');
    this.session = ko.observable('Stop');
    this.disable = ko.observable(true);
    this.allowChange = ko.observable('No');

};

ko.applyBindings(new ViewModel()); // This makes Knockout get to work