JSFiddle - React, Tailwind, and code Playground
HTML
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css">
<div data-bind="template: { name: 'BowItemTemplate', foreach: Bows }">
</div>
<script id="BowItemTemplate" type="text/template">
<button data-bind="add">Add</button>
<div class="clearfix" data-bind="liveEditor: Name">
<span class="view" data-bind="event: { click: Name.edit }, text: Name,"></span>
<div class="pull-right">
<ul class="list-inline text-right">
<li><label>Deleted? <input data-bind="checked: false" type="checkbox" /></label></li>
<li><i data-bind="click: Name.edit" class="icon-wrench"></i></li>
</ul>
</div>
<textarea style="width:85%" class="edit" data-bind="value: Name, enterKey: Name.stopEditing, selectAndFocus: Name.editing, event: { blur: Name.stopEditing }"></textarea>
</div>
<div style="width:100%;">
<ul class="list-unstyled list-inline">
<li><label>Bow Type</label></li>
<li data-bind="liveEditor: BowTypeID">
<span>
<span class="view" data-bind="event: { dblclick: BowTypeID.edit }, text: BowType().Description"></span>
<span class="view" data-bind="event: { dblclick: BowTypeID.edit }, text: BowTeDescription"></span>
<i data-bind="click: BowTypeID.edit" class="icon-wrench"></i>
<select style="width: 95%;" class="edit" data-bind="event: { blur: BowTypeID.stopEditing }, options: $parent.BowTypes, optionsText: 'Description', optionsValue: 'BowTypeID', value: BowTypeID, optionsCaption: 'Choose...'"></select>
</span>
</li>
<li><label>Date Created</label></li>
<li><span data-bind="text: CreatedDate"></span> <i class="icon-wrench"></i></li>
</ul>
</div>
</script>
CSS
.edit {
display: none;
}
.editing .edit {
display: block;
}
.editing .view {
display: none;
}​
JavaScript
ko.extenders.liveEditor = function (target) {
target.editing = ko.observable(false);
target.edit = function () {
if (!target.editing()) {
target.editing(true);
}
else {
target.stopEditing();
}
};
target.stopEditing = function () {
target.editing(false);
};
return target;
};
ko.bindingHandlers.liveEditor = {
init: function (element, valueAccessor) {
var observable = valueAccessor();
observable.extend({ liveEditor: this });
},
update: function (element, valueAccessor) {
var observable = valueAccessor();
ko.bindingHandlers.css.update(element, function () {
return { editing: observable.editing };
});
}
};
var MyBowsModel = function(){
var self = this;
self.BowTypes= ko.observableArray([
{
Description: ko.observable('Compound'),
BowTypeID: ko.observable('c0b0e507-70b7-43d5-8574-7d6a0103ba27'),
DefaultBow: ko.observable(false)
},
{
Description: ko.observable('Recurve'),
BowTypeID: ko.observable('5b9693dc-dccd-40bc-aea8-02b9f7e0a926'),
DefaultBow: ko.observable(true)
}
]);
console.log("bowTypes",self.BowTypes());
self.rawBow = {
BowID: '6bf1fd74-5300-49f3-92cd-9ab14188f046',
BowTypeID: '5b9693dc-dccd-40bc-aea8-02b9f7e0a926',
CreatedDate: '09/01/2019 15:00',
Name: 'My favourite Bowzzzz'
}
self.rawBows= [
{
BowID: '6bf1fd74-5300-49f3-92cd-9ab14188f046',
BowTypeID: '5b9693dc-dccd-40bc-aea8-02b9f7e0a926',
CreatedDate: '05/01/2013 15:00',
Name: 'My favourite Bow'
},{
BowID: 'XXXXXX-5300-49f3-92cd-9ab14188f046',
BowTypeID: '5b9693dc-dccd-40bc-aea8-02b9f7e0a926',
CreatedDate: '11/07/2013 15:00',
Name: 'My other Bow'
...