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>
<table>
  <thead>
    <!-- NEW: use ko foreach with 'as' to have an alias for accessing $data. -->
    <tr data-bind="foreach: { data: columns, as: 'column'}">
      <th> <span data-bind="text: column.Caption"></span>
      </th>
    </tr>
  </thead>
  <tbody data-bind="foreach: { data: valuesData, as: 'rowData'}">
    <tr data-bind="foreach: { data: $parent.columns, as: 'column' }">
      <!-- NEW: bind to the corresponding property/observable in ValuesData -->
      <td><input type="text" class="form-control textbox" data-bind="textInput: rowData[column.Property]" /> </td>
    </tr>
    <tr>
      <td>
        <input type="button" value="Remove Row" data-bind="click: $parent.removeRow" class="btn btn-danger" />
      </td>
    </tr>
  </tbody>
</table>

<br><br>
<div class="col-xs-12 col-sm-6">
  <input type="button" value="Add Row" class="btn btn-primary" data-bind="click: addRow" />
  <input type="button" value="Save" class="btn btn-primary" data-bind="click: Save" />
</div>
<pre data-bind="text: ko.toJSON(valuesData, null, 2)"></pre>

JavaScript

(function() {
  var ViewModel = function() {
    var self = this;
    self.valuesData = ko.observableArray();
    self.column = ko.observableArray();
    self.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 }));
    self.data1 (result);

    self.columns = ko.computed(function() {    
        
      if (self.valuesData().length === 0)
        return [];
        
       // debugger;
       // alert(ValuesData.columns.Caption);
      // var columns = {name:"Tahir Akhtar", occupation: "Software Development" };
   //alert('in');
    ValuesData.columns = self.data1();
      return ValuesData.columns;
    });

    self.addRow = function() {
      self.valuesData.push(new ValuesData());
    };

    self.Save = function() {
      alert('Data:')
    };

    self.removeRow = function(data) {
      self.valuesData.remove(data);
    };
  }

  // Dynamic values.
  var ValuesData = function(a,b,c) {
    var self = this;

    // Add observables dynamically for all relevant columns.
    for (var i = 0; i < ValuesData.columns.length; i++) {
      var column = ValuesData.columns[i];
      self[column.Property] = ko.observable(column.InitialValue)
    }
  };
  ValuesData.columns = [
    ];

  vm = new ViewModel()
  ko.applyBindings(vm);

  // add initial row.
  vm.addRow();


})();