KO Component Widget with template
Inserts a template component that contains a child component
by Doug Hill
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-debug.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>
<table>
<tbody data-bind="foreach:filters">
<tr>
<th data-bind="text:name"></th>
<td data-bind="template:{name:template}"></td>
</tr>
</tbody>
</table>
<span data-bind="text:ko.mapping.toJSON(queryData)"></span>
<template id="stringfilter">
<input data-bind="value:value"/>
</template>
<template id="dropdownfilter">
<select data-bind="value:value,options:values"></select>
</template>
<template id="rangefilter">
<input data-bind="value:value1"/><input data-bind="value:value2"/>
</template>
JavaScript
var data={
filters: [
{
name: "Frequency",
type: "dropdown",
config: {
values: [
"High",
"Low"
]
},
value: "Low"
},
{
name: "ATTUID",
type: "string",
config: null,
value: "123"
},
{
name: "Range",
type: "range",
config: null,
value: {value1:"1",value2:"2"}
}
]
};
var filterModels={
"stringfilter": {
viewModel:function (def) {
var self = this;
self.value=ko.observable(def.value);
}
},
"dropdownfilter": {
viewModel:function (def) {
var self = this;
self.value=ko.observable(def.value);
self.values=def.config.values;
}
},
"rangefilter": {
viewModel: function (def) {
var self = this;
self.value1=ko.observable(def.value.value1);
self.value2=ko.observable(def.value.value2);
self.value=ko.computed(function(){
return {
value1: self.value1(),
value2: self.value2()
};
});
}
}
}
var parentViewModel=function(){
var self=this;
self.filters=ko.observableArray();
self.loadFilters=function(filterData){
var filters=[];
ko.utils.arrayForEach(filterData.filters,function(filterDef){
var filter=new filterModels[filterDef.type+ 'filter'].viewModel(filterDef);
filter.template=filterDef.type + 'filter';
filter.name=filterDef.name;
filters.push(filter);
});
self.filters(filters);
}
self.queryData=ko.computed(function(){
return ko.utils.arrayMap(self.filters(),function(filter){
return {
name:filter.name,
...