JSFiddle - React, Tailwind, and code Playground
by sykvel
HTML
Data:
<div class="inputs">
<!-- ko foreach: computedData -->
<div>
<input data-bind="value: name, hasFocus: isSelected" />
<input data-bind="value: f" />
<hr/>
</div>
<!-- /ko -->
<div>
<input class="add-field" data-bind="hasFocus: blankLineIsSelected" tabindex=0 readonly/>
</div>
</div>
Output:
<ul data-bind="foreach: computedData">
<li data-bind="text: name"></li>
</ul>
Data:
<ul data-bind="foreach: data">
<li data-bind="text: name"></li>
</ul>
CSS
.inputs {
display: flex;
flex-direction: column;
}
.add-field {
opacity: 0;
z-index: -1;
position: absolute;
}
JavaScript
function Item(id, name, isSelected = false) {
this.id = ko.observable(id);
this.name = ko.observable(name);
this.f = ko.observable('');
this.isEmpty = ko.computed(() => (!this.name() && !this.f()));
this.isSelected = ko.observable(isSelected);
}
function ItemsViewModel() {
var self = this;
self.blankLineIsSelected = ko.observable(false);
self.data = ko.observableArray([
new Item(1, "One description"),
new Item(2, "Two description"),
new Item(3, "Three description")]);
self.computedData = ko.computed(function() {
self.data(ko.utils.arrayFilter(self.data(), i => !i.isEmpty()));
if(self.blankLineIsSelected())
{
self.data().push(new Item(0, "", true));
}
return self.data();
});
}
ko.applyBindings(new ItemsViewModel());