Reputation: 1176
I have a resusable control/custom binding & template designed to build a dynamic wizard based on a set of passed in config options and the ViewModel that is ultimately bound to the page. I've got the wizard building itself properly and displaying all of the required fields but I have been unable, so far, to get the actual input field values to display.
Any ideas?
ViewModel
var user = function () {
var self = this;
self.FirstName = ko.observable("Brent");
self.LastName = ko.observable("Pabst");
self.Email = ko.observable("[email protected]");
self.FullName = ko.computed(function () {
return self.FirstName() + " " + self.LastName();
});
};
var tenant = function () {
var self = this;
self.Name = ko.observable("Tenant Name");
self.SubDomain = ko.observable("Sub Domain");
self.User = ko.observableArray([new user]);
self.wizardModel = new merlin.wizard({
title: "Add a Tenant",
model: self,
steps: [
{ Title: "Tenant Information",
Fields: [
{ Name: "Name", Label: "Organization Name", Value: "Name" },
{ Name: "SubDomain", Label: "Login Page", Value: "SubDomain" }
]
},
{ Title: "Administrator Information",
Fields: [
{ Name: "FirstName", Label: "First Name", Value: "User.FirstName" },
{ Name: "LastName", Label: "Last Name", Value: "User.LastName" },
{ Name: "Email", Label: "E-Mail Address", Value: "User.Email" }
]
}
]
});
self.save = function () {
alert(ko.toJSON(self));
};
};
ko.applyBindings(tenant());
Wizard Model
merlin.wizard = function (config) {
var self = this;
self.steps = config.steps;
self.title = config.title;
self.model = config.model;
self.currentStep = ko.observable(0);
};
Template & Binding
var templateEngine = new ko.nativeTemplateEngine();
templateEngine.addTemplate = function (templateName, templateMarkup) {
document.write("<script type=\"text/html\" id='" + templateName + "'>" + templateMarkup + "<" + "/script>");
};
templateEngine.addTemplate("merlin_wizard", "\
<form class=\"m-ui-wizard\">\
<h1 data-bind=\"text: title\" />\
<h2 data-bind=\"text: title\" />\
<div class=\"m-ui-wizard-steps\" data-bind=\"foreach: steps\">\
<div class=\"m-ui-wizard-step\">\
<!-- ko if: $data.Fields -->\
<!-- ko foreach: Fields -->\
<label data-bind=\"text: Label, attr: { for: Name }\"></label>\
<input type=\"text\" data-bind=\"attr: { name: Name }, Value: typeof value === 'function' ? Value($root.model) : $root.model[Value]\" />\
<!-- /ko -->\
<!-- /ko -->\
</div>\
</div>\
</form>");
ko.bindingHandlers.wizard = {
init: function () {
return { controlsDescendantBindings: true };
},
update: function (element, viewModelAccessor, allBindingsAccessor) {
var viewModel = viewModelAccessor(), allBindings = allBindingsAccessor();
while (element.firstChild)
ko.removeNode(element.firstChild);
var wizTemplateName = allBindings.gridTemplate || "merlin_wizard";
var wizContainer = element.appendChild(document.createElement("DIV"));
ko.renderTemplate(wizTemplateName, viewModel, { templateEngine: templateEngine }, wizContainer, "replaceNode");
}
};
HTML Snippet
<div data-bind="wizard: wizardModel"></div>
Note: I have been unable to get this to work at all in Fiddle, not really sure why other than the fact that I may be pushing the boundaries of Fiddle with this setup.
Upvotes: 0
Views: 1199