JSFiddle - React, Tailwind, and code Playground
by nyothecat
HTML
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="container traffic-controller">
<div class="product-selection row box">
<div class="col-med-12">
<h2>Create New Product Definition</h2>
<div class="col-md-6 form-group">
<label class="control-label">Product Name</label>
<select class="form-control" data-bind="options: mmProductList, value: selectedProduct"></select>
</div>
<div class="col-md-6 form-group">
<button type="button" class="btn btn-primary new-product" data-bind="click: addProduct">Create</button>
</div>
</div>
</div>
<h2>Products</h2>
<div id='productsList' data-bind="foreach: products">
<div>Product Allocation: <span data-bind="text: $root.prodAllocation"></span></div>
<div class="product clearfix box" data-bind="attr: { 'id': prodName }">
<h2 data-bind="text: prodName">Product Name</h2>
<form role="form">
<div><a href='#' data-bind='click: $root.removeProduct'>Delete</a></div>
<div data-bind="foreach: splits">
<div class="row">
<div class="col-md-4 form-group">
<label class="control-label">Page Name</label>
<select class="form-control" data-bind="options: page"></select>
</div>
<div class="col-md-1 form-group">
<label class="control-label">Allocation %</label>
<input type="text" class="form-control allocation" data-bind="value: allocation" placeholder="%">
...
CSS
label {
font-size:13px;
}
/* generic box styles */
.box {
padding:10px;
margin:20px 0;
border-radius:.2em;
}
button.delete {
margin-top:20px;
color:#323232;
text-decoration:underline;
}
button.new-product {
margin-top:20px;
}
/* direct wire styles */
.direct-wire {
background: #ccebee;
}
/* default split */
.default-split {
background: #eee;
}
/* product selection */
.product-selection {
background: #5bb6bc;
color:#fff;
}
/* product box */
.product {
background: #ecf8f9;
}
/* progress bar */
.progress {
overflow: hidden;
height: 20px;
margin: 10px 0;
background-color: #f1f1f1;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
}
.progress-bar {
float: left;
width: 0%;
height: 100%;
font-size: 12px;
line-height: 20px;
color: #ffffff;
text-align: center;
background-color: #1b8e96;
-webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
-webkit-transition: width 0.6s ease;
transition: width 0.6s ease;
}
.progress-bar.warning {
background-color: #C52E12;
}
.progress-error {
color: #C52E12;
}
JavaScript
var initialData = [
/* Sample data
{ prodName: "MSVR", splits: [
{ page: "Page Name", allocation: "10%"},
{ page: "Page Name", allocation: "20%"}]
}*/
];
var ProductsModel = function(products) {
var self = this;
self.mmAllPages = ko.observableArray(['Page 1', 'Page 2', 'Page 3']);
self.mmProductList = ko.observableArray(['Product 1', 'Product 2', 'Product 3', 'Product 4']);
self.selectedProduct = ko.observable();
self.prodAllocation = ko.observable();
self.products = ko.observableArray(ko.utils.arrayMap(products, function(contact) {
return { prodName: contact.prodName, splits: ko.observableArray(contact.splits) };
}));
self.addProduct = function() {
currentProduct = self.selectedProduct();
self.products.push({
prodName: currentProduct,
splits: ko.observableArray()
});
self.mmProductList.remove(currentProduct);
};
self.removeProduct = function(contact) {
self.products.remove(contact);
self.mmProductList.push(currentProduct);
};
self.addDefinition = function(contact) {
var s = {
page: self.mmAllPages(),
allocation: ko.observable(),
};
s.allocation.subscribe(function () {
var sum = 0;
for (var i = 0; i < contact.splits().length; i++)
sum += contact.splits()[i].allocation() *1;
self.prodAllocation(sum);
});
contact.splits.push(s);
};
self.removeDefinition = function(phone) {
$.each(self.products(), function() { this.splits.remove(phone) })
};
self.save = function() {
self.lastSavedJson(JSON.stringify(ko.toJS(self.products), null, 2));
...