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());