JSFiddle - React, Tailwind, and code Playground

by ksingh24

HTML

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.16/css/dataTables.bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.16/js/jquery.dataTables.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.16/js/dataTables.bootstrap.min.js"></script>
<br>
<div class="col-md-14" style="margin-top:20px">
  <!--<span data-bind="text: ko.toJSON($data)"></span>-->
  <input type="button" value="Add New Tab" class="btn btn-info" data-bind="click: AddTab" />
</div>
<br>

<div id="tabs" data-bind="foreach: tabs">
  <div class="tab" data-bind="css: {selected: $parent.selectedTab() == id()}, text: name, click: $parent.selectedTab.bind($parent, id())"></div>
</div>

<br><br>

<div id="tabContent" data-bind="foreach: tabs">
  <div data-bind="if: $parent.selectedTab() == id()">

    Item Table

    <div style="width:70%">
      <table class="table table-bordered">
        <thead class="mbhead">
          <tr class="mbrow">
            <th>Input</th>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Separator</th>
            <th>Address</th>
          </tr>
        </thead>
        <tbody data-bind="foreach: items">
          <tr data-bind="css: { invalidRow: isInvalid }">
            <td id="tdName"><select class="form-control textbox-wide" data-bind="options: $parent.ddl, optionsText: 'firstName', value: selectedValue, optionsCaption: '--Select--'"> </select></td>
            <td data-bind="with: selectedValue">
              <span data-bind="text:...

CSS

body {
  padding: 10px;
}

#tabs {
  padding: 3px 3px 1px 3px;
}

.tab {
  cursor: default;
  border: 1px solid grey;
  border-bottom: none;
  border-radius: 4px 4px 0 0;
  padding: 1px 10px 0 10px;
  background: linear-gradient(silver 30%, grey 100%);
  color: white;
  transition: all .25s ease;
  display: inline-block;
  margin-top: 4px;
}

.tab.selected {
  font-weight: bold;
  padding-top: 3px;
  margin-top: 2px;
  background: linear-gradient(white 30%, silver 70%, grey 100%);
  color: black;
}

.tab:hover {
  background: linear-gradient(white 30%, silver 70%, grey 100%);
  color: black;
}

@keyframes bgColor {
  from {
    background: hsl(0, 100%, 99%);
  }
  12% {
    background: hsl(45, 100%, 99%);
  }
  25% {
    background: hsl(90, 100%, 99%);
  }
  37% {
    background: hsl(135, 100%, 99%);
  }
  50% {
    background: hsl(180, 100%, 99%);
  }
  62% {
    background: hsl(225, 100%, 99%);
  }
  75% {
    background: hsl(270, 100%, 99%);
  }
  88% {
    background: hsl(315, 100%, 99%);
  }
  to {
    background: hsl(360, 100%, 99%);
  }
}

.table {
    display: block;
    overflow-x: auto;
    white-space: nowrap;
    width:1000px;
}
.table td,th {
    display:inline-block;
    width: 180px !important;
}

JavaScript

(function() {
  var ViewModel = function() {
    var self = this;
     self.selectedTab = ko.observable(1);
    self.tabs = ko.observableArray([]);
    self.Tab = function(id, name, text, selected) {
      var tab = this;
      tab.id = ko.observable(id);
      tab.name = ko.observable(name);
      tab.text = ko.observable(text);
      tab.items = ko.observableArray([]); //create a copy of the template array
      tab.valuesData = ko.observableArray([]);
      tab.ddl = ko.observableArray();
      
    tab.GetData = function() {
      var c = '[{"FirstName":"Alex","LastName":"Sanders","Address":123},{"FirstName":"Sam","LastName":"Billings","Address":"Mahony Street"}]';
      var jsonResult = JSON.parse(c);
      for (key in jsonResult) {
        var item = {
          firstName: jsonResult[key].FirstName,
          lastName: jsonResult[key].LastName,
          address: jsonResult[key].Address
        };
        tab.ddl.push(item);
      }
    }

    //Item Table
    tab.addRow = function() {
      self.items.push(new Item());
    };
    tab.removeRow = function(data) {
      self.items.remove(data);
    };
    
    //Values Table
    tab.addValueRow = function() {
      tab.valuesData.push(new ValuesData());
    };

    tab.removeValueRow = function(data) {
      tab.valuesData.remove(data);
    };   
  

    tab.valuesData = ko.observableArray();
    tab.column = ko.observableArray();
    tab.data1 = ko.observable();
    var col = "ID, Co1, Col2, Col3, Col4, Col5, Comment";
    var result = col.split(",").map(s => ({
      Caption: s.trim(),
      Property: s.trim(),
      InitialValue: undefined
    }));
    tab.data1(result);
    tab.columns = ko.computed(function() {

      if (tab.valuesData().length === 0)
        return [];

      ValuesData.columns = tab.data1();
      return ValuesData.columns;
    });      
      
      
      tab.addRow = function() {
        tab.items.push(new Item());
      };

      tab.removeRow = function(data) {
       ...