JSFiddle - React, Tailwind, and code Playground

by magikMaker

HTML

<script src="http://adam.labs.gype.nl/MRMStudio/src/js/vendor/jquery.tmpl.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.1.0.js"></script>
<div data-bind="template: {
  name: 'list-template',
  data: list
}">
</div>
<script type="text/html" id="list-item-template">
<ul>

</ul>
</script>
<hr />

<ul data-bind="template: { 
    name: 'list-item-template', 
    foreach: people,
    as: 'person'
  }">
</ul>

<script type="text/html" id="list-item-template">
<li data-bind="addClass: getCssClass()">
    {{if true === status}}
    <span data-bind="text: getName"></span>
    {{else}}
    NOT OK
    {{/if}}
</li>
</script>

<hr />
    
<ul data-bind="foreach: people">
  <!-- ko if: true === status -->
  <li data-bind="{
    text: getName,
    css: getCssClass        
  }"></li>
  <!-- /ko -->

    <!-- ko if: false === status -->
    <li>NOT OK</li>
    <!-- /ko -->
    
</ul>
    
<button data-bind="click: addAge">addAge()</button>

CSS

li {
  background-color: #888;
  border: 1px solid #cecece;
  color: #cecece;
  padding: 4px;
  margin: 4px
}

.status-green {
  background-color: green;
}

.status-red {
  background-color: red;
}

JavaScript

var setUpAddClassBinding = function(){
    ko.bindingHandlers.addClass = {
        /**
         * This will be called once when the binding is first applied to an element,
         * and again whenever the associated observable changes value. 
         * So it updates the css className with the current value
         * 
         * @param {Object} element
         * @param {Object} valueAccessor
         * @param {Object} allBindingsAccessor
         * @param {Object} viewModel the viewModel
         */
        update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
            var value = valueAccessor() || '';
            var $element = jQuery(element);
            $element
              .removeClass($element.data('lastCssClass') || '')
              .data('lastCssClass', value)
              .addClass(value);
        }
    };
};

var vm = function(){
    var Person = function(name, age){
        this.name = ko.observable(name);
        this.age = ko.observable(age);
        this.status = Math.random() > 0.5 ? true : false;
        
        this.getCssClass = ko.computed(function(){
            return this.age() > 50 ? 'status-green' : 'status-red';
        }, this);
        
        this.getName = ko.computed(function(){
            return this.name() +' ('+ this.age()+')';
        }, this);            
        
    };

    this.people= [
        new Person('paul', 22),            
        new Person('Yolanda', 33),
        new Person('Jirka', 16),
        new Person('Marketa', 21)
    ]; 

    this.addAge = function(){
        var age = 3;
        for(var i = 0, l = this.people.length;i<l;++i){
            this.people[i].age(this.people[i].age() + age);
        }
    };
    
    this.list = {
        people: this.people
    };
};

var viewmodel = new vm()
setUpAddClassBinding();
ko.applyBindings(viewmodel);