JSFiddle - React, Tailwind, and code Playground
by blineberry
HTML
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<ul class="list" data-bind="foreach: recipeParts">
<li class="list-item" data-bind="css: { 'is-editable': isEditable() }">
<div class="text">
<span data-bind="text: qty"></span>
<span data-bind="text: unit"></span>
<span data-bind="text: ingredientName"></span>
<span data-bind="text: modifier"></span>
<span data-bind="text: isOptional() ? '(optional)' : ''"></span>
<span data-bind="text: isGarnish() ? '(garnish)' : ''"></span>
</div>
<div class="form">
<label data-bind="attr{ for: 'data[\'RecipePart\'][' + $index() + '][\'qty\']' }">Quantity</label>
<input data-bind="value: qty, attr{ name: 'data[\'RecipePart\'][' + $index() + '][\'qty\']' }, hasfocus: isEditable()" />
<label data-bind="attr{ for: 'data[\'RecipePart\'][' + $index() + '][\'unit\']' }">Unit</label>
<input data-bind="value: unit, attr{ name: 'data[\'RecipePart\'][' + $index() + '][\'unit\']' }" />
<label data-bind="attr{ for: 'data[\'RecipePart\'][' + $index() + '][\'recipe_part_id\']' }">Ingredient</label>
<select data-bind="value: ingredientId, options: $root.ingredients, optionsText: 'name', optionsValue: 'id'"></select>
<label data-bind="attr{ for: 'data[\'RecipePart\'][' + $index() + '][\'modifier\']' }">Modifier</label>
<input data-bind="value: modifier, attr{ name: 'data[\'RecipePart\'][' + $index() + '][\'modifier\']' }" />
<label data-bind="attr{ for: 'data[\'RecipePart\'][' + $index() + '][\'optional\']' }"><input type="checkbox" data-bind="attr{ name: 'data[\'RecipePart\'][' + $index() + '][\'optional\']' }" value="1" /> Optional?</label>
<label data-bind="attr{ for: 'data[\'RecipePart\'][' + $index() +...
CSS
body {
font-size: 16px;
line-height: 1.5;
padding: 1em;
}
.list {
margin: 0;
padding: 0;
list-style: none;
}
.list-item .form {
display: none;
}
.list-item.is-editable .form {
display: block;
}
.list-item.is-editable .text {
display: none;
}
JavaScript
function viewModel() {
var vm = this;
vm.ingredients = [
{
id: 0,
name: 'Absinthe'
},
{
id: 1,
name: 'Bourbon'
},
{
id: 2,
name: 'Gin'
},
{
id: 3,
name: 'Tequila'
},
{
id: 4,
name: 'Vodka'
}
];
vm.recipePart = function (data) {
var rp = this;
var defaults = data || {};
rp.qty = ko.observable(defaults.qty);
rp.unit = ko.observable(defaults.unit);
rp.ingredientId = ko.observable(defaults.ingredientId);
rp.ingredientName = ko.computed(function() {
var item = $.grep(vm.ingredients, function(e){
console.log(e.id);
console.log(rp.ingredientId());
return e.id == rp.ingredientId();
})[0];
if (typeof item !== 'undefined') {
return item.name;
}
else {
return null;
}
});
rp.modifier = ko.observable(defaults.modifier);
rp.isOptional = ko.observable(defaults.isOptional || 0);
rp.isGarnish = ko.observable(defaults.isGarnish || 0);
rp.isEditable = ko.observable(defaults.isEditable || true);
rp.toggleEdit = function () {
if (rp.isEditable()) {
rp.isEditable(false);
} else {
rp.isEditable(true);
}
}
//self.save = function (recipePart) {
// recipePart.isEditable(false);
//};
};
vm.recipeParts = ko.observableArray([]);
vm.addRecipePart = function (recipePart) {
vm.recipeParts.push(new vm.recipePart());
}
vm.removeRecipePart = function (recipePart) {
vm.recipeParts.remove(recipePart)
};
}
ko.applyBindings(new viewModel());