JSFiddle - React, Tailwind, and code Playground

by RedGoblin17

HTML

<script src="//code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<link rel="stylesheet" href="//stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
<script src="//stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<!-- 
  Bootstrap docs: https://getbootstrap.com/docs
-->
<!-- <div class="freeze-left">
  <label for="fn">First Name</label> <br>
  <label for="ln">Last Name</label> <br>
  <label for="nn">Number</label> <br>
  <label for="fullN">Full Name:</label> <br>
</div>
<div class="scrolling-wrapper" data-bind="foreach: forms">
  <div class="card" >
    <form class="form-group">
     <input id="fn" type="text" data-bind="textInput: firstName"/><br>
     
     <input id="ln" type="text" data-bind="textInput: lastName"/><br>
     <input id="nn" type="number" min="1" data-bind="value: number"/>
    </form>
    
    <p>
       <strong id="fullN" data-bind="text: data"></strong>
    </p>
  </div>
</div> -->

<div class="scrolling-table">
<div class="card">
    <form class="form-group">
    <table class="request-table">
      <tr>
        <th class="headcol">Name Builder</th>
      </tr>
      <tr>
        <th class="headcol">Full Name</th>
        <td class="long" data-bind="foreach: forms">
          <p id="fullName" class="computedTitle" data-bind="text: data"></p>
        </td>
      </tr>
      <tr>
        <div class="sticky">
          <th class="headcol">First Name</th>
        </div>
        <td class="long" data-bind="foreach: forms">
          <input id="firstName" class="form-control" type="text" data-bind="textInput: firstName"/>
        </td>
      </tr>
      <tr>
        <th class="headcol">Last Name</th>
        <td class="long" data-bind="foreach: forms">
          <input id="lastName" class="form-control"...

CSS

/* .scrolling-wrapper {
  overflow-x: scroll;
  overflow-y: hidden;
  white-space: nowrap;
  height: auto;
  width: auto;
}

.card {
  border: 5px solid white;
  width: auto;
  height: auto;
  background: #F8F8FF;
}

.scrolling-wrapper .card {
  display: inline-block;
}

.scrolling-wrapper-flex {
  display: flex;
  flex-wrap: nowrap;
  overflow-x: auto;
}

.scrolling-wrapper-flex .card {
  flex: 0 0 atuo;
  margin-right: 3px;
}

input {
  float: right;
}

.freeze-left {
  float: left;
  margin-right: 3px;
} */

/* .request-table {
  border-collapse: separate;
  border-spacing: 0;
  border-top: 1px solid grey;
}

td, th {
  margin: 0;
  border: 1px solid grey;
  white-space: nowrap;
  border-top-width: 0px;
}
 */
.scrolling-table {
  width: auto;
  overflow-x: scroll;
  overflow-y: hidden;
  padding: 0;
  white-space: nowrap;
  height: auto;
}

.card {
  border: 5px solid white;
  width: auto;
  height: auto;
  background: #F8F8FF;
}

.scrolling-table .card {
  display: inline-block;
}

.long .form-control , .long .btn{
  display: inline-block;
  width: 200px;
}

.computedTitle {
  width: 200px;
  text-align: center;
  display: inline-block;
}

.sticky {
  position: fixed;
  left: 0;
}

JavaScript

function FormViewModel(){
	var self = this;
  
  self.firstName = ko.observable("");
  self.lastName = ko.observable("");
  self.number = ko.observable();
  self.data = ko.computed(
  	function(){
  		return self.firstName() + " " + self.lastName() + " " + (typeof self.number() == "undefined" ? "" : 	self.number());
      }, this
    );
 	self.saySaved = function() {alert("Saved! " + self.data());}; 
}

function AppViewModel(){
	var self = this;
  
  self.forms = new ko.observableArray([new FormViewModel()]);
  
  self.addForm = function(){
  	self.forms.splice(0,0, new FormViewModel());
  }
}
 
ko.applyBindings(new AppViewModel());