JSFiddle - React, Tailwind, and code Playground

by Sergio Sánchez

HTML

<script src="https://raw.github.com/furf/jquery-ui-touch-punch/master/jquery.ui.touch-punch.min.js"></script>
<script src="http://knockoutjs.com/downloads/knockout-3.0.0.debug.js"></script>
<div id="exercise" data-bind="foreach: elements">
    <!-- ko if: isReadable == true --> 
    <div class="clickzones" data-bind="attr: {id:'zone'+ID}, style:{top: top+'px', left: left+'px'}">
        <div class="images" data-bind="text: name, attr: {id:'dragzone_'+ID}, click: $parent.clickedElement "></div>
    </div>
     <!-- /ko -->
</div>
<div id="Toolbar" data-bind="foreach: elements" >
    <!-- ko if: isReadable == false --> 
    <div class="clickzones" data-bind="attr: {id:'zone'+ID}, style:{top: top+'px', left: left+'px'}">
        <div class="images" data-bind="text: name, attr: {id:'dragzone_'+ID}, click: $parent.clickedToolBarElement "></div>
    </div>
     <!-- /ko -->
</div>
<button onclick="SeeHistory();">See History</button>

CSS

#exercise {
    background-image:url('http://content.screencast.com/users/sanchitos/folders/Jing/media/34aec669-0969-4113-9d63-06965b3cd39f/2013-11-15_1719.png');
    width: 876px;
    height: 506px;
    float: left;
}
#Toolbar {   
    width: 100px;
    height: 74px;
    float: left;
}
#drop {
    float:right;
    background-color:#FFFFFF;
    width:70px;
    border:2px solid black;
}
.images {
    position: relative;
    width:60px;
    height:18px;
    padding:0;
    margin:0;
    z-index:2;
    cursor:move;
    background-color:#FFFFFF;
    text-align:center;
    line-height: 18px;
    border:2px solid black;
    margin-left: -2px;
    margin-top: -2px;
}
.clickzones {
    background-color:#FFFFFF;
    width:60px;
    height:18px;
    padding:0;
    margin:0;
    border:2px solid black;
    position: relative;
}

JavaScript

var Element = function (id, name, top, left, value, isReadable, isFixable, isTester, isReplacer) {
    this.ID = id;
    this.top = top;
    this.left = left;
    this.value = value;
    this.name = name;
    this.isReadable = isReadable;
    this.isFixable = isFixable;
    this.isTester = isTester;
    this.isReplacer = isReplacer;
}

var HistoryElement = function (id, action)
{
    this.id = id;
    this.action = action;
}
var ViewModel = function () {
    
    var self = this; // self is being used to maintain a reference to the original this even as the context is changing.
    self.TesterOn = false;
    self.ReplacerOn = false;
    self.elements = ko.observableArray([]);
    self.history = new Array();
    self.addElement = function (id, name, top, left, value, isReadable, isFixable, isTester, isReplacer ) {
        var element = new Element(id, name, top, left, value, isReadable, isFixable, isTester, isReplacer);
        self.elements.push(element);
    };
    //In case we want to change image from toolbar
    self.TesterEvent = function (on_off)
    {
      if (on_off == true)
      {
          alert ("ON tester");
      }
      else
      {
          alert ("OFF tester");
      }
        self.TesterOn = on_off;
    };
    //In case we want to change image from toolbar
    self.ReplacerEvent = function (on_off)
    {
      if (on_off == true)
      {
          alert ("ON replacer");
      }
      else
      {
          alert ("OFF replacer");
      }
        self.ReplacerOn = on_off;
    };
    self.clickedElement = function (element)
    {
        if (self.TesterOn)
        {
            if (element.isReadable)
            {
                alert(element.value);
                //element.diagnosed = true;
                var trackElement = new HistoryElement(element.ID, "Tested");
                self.history.push(trackElement);
            }
        }
        if (self.ReplacerOn)
        {
           if (element.isFixable)
            {
               ...