JSFiddle - React, Tailwind, and code Playground
HTML
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/3.1.0/knockout-min.js"></script>
<script type="text/html" id="bill-description-template">
<select data-bind = 'options:availableDescriptions, optionsText:"ItemName", optionsCaption: "Select Bill Description",optionsValue:"ItemName",value: selection' > </select>
</script>
<fieldset id='case1'>
<legend>Causes Error</legend>Clicking the button more than once will cause an error due to duplicate binding application.
<br/>
<button data-bind='click:addBillItem'>Add</button>
<div id='dropdown'></div>
</fieldset>
<fieldset id='case2'>
<legend>Dynamic</legend>Like the previous case, direct jQuery DOM manipulation achieves a "dynamic" UI, but still not in a "Knockout" way.
<br/>
<button data-bind='click:addBillItemDynamic'>Add</button>
<div>Debug: <span data-bind='text: debug'></span>
</div>
<div id='dropdownDynamic'></div>
</fieldset>
<fieldset id='case3'>
<legend>Using Templates</legend>
<br/>
<button data-bind='click:addBillingTemplate'>Add</button>
<div>Debug: <span data-bind='text: debug'></span>
</div>
<span data-bind='text: "Size " + billingDescriptions().length'></span>
<div data-bind="template: {name: 'bill-description-template', foreach: billingDescriptions}"></div>
</fieldset>
JavaScript
function Item() {
return {
ItemName: 'Name'
}
}
function AssignmentViewModel() {
self.billDescriptions = ko.observableArray();
self.billingDynamic = {};
self.debug = ko.observable()
self.addBillItem = function () {
$("#dropdown").append("<select id='ddlBillItemDescription' data-bind='options: billDescriptions'></select>");
self.billDescriptions(["one", "two", "three"]);
ko.applyBindings(self.billDescriptions(), $("#ddlBillItemDescription")[0])
};
self.addBillTemplate = function () {
$("#dropdownTemplateContainer").append("");
}
self.addBillItemDynamic = function () {
var billItems = $('.billItem').length
self.billingDynamic[billItems] = {
billDescriptions: ko.observableArray([new Item(), new Item(), new Item()]),
BillItemDescription: ko.observable()
}
var html = '<select id="ddlBillItemDescription' + billItems + '" class="billItem" data-bind=\'';
html += 'options:billDescriptions,';
html += 'optionsText:"ItemName",';
html += 'optionsCaption: "Select Bill Description",';
html += 'optionsValue:"ItemName",';
html += 'value: BillItemDescription\'>';
html += '</select>';
$("#dropdownDynamic").append(html);
console.log(html)
self.debug(ko.toJSON(self.billingDynamic))
ko.applyBindings(self.billingDynamic[billItems], $("#ddlBillItemDescription" + billItems)[0])
};
}
function BillingDescription() {
return {
availableDescriptions: ko.observableArray([new Item(), new Item(), new Item()]),
selection: ko.observable()
}
}
function KnockoutModel() {
var self = this;
self.debug = ko.observable()
self.billingDescriptions = ko.observableArray([]);
self.addBillingTemplate = function () {
var bd = new BillingDescription();
self.billingDescriptions.push(bd);
...