Roman Kolpak
Roman Kolpak

Reputation: 2012

How do I dynamically generate edit form for a selected item in a list using knockout.js

I'm probably being such a noobie right now, but here's the question. I have a list of users generated by knockoutjs. Here's a basic code I'm using (all the unnecessary details skipped):

function User(info) {
    this.id = info.id;
    this.firstName = ko.observable(info.firstname);
    this.lastName = ko.observable(info.surname);

    this.fullName = ko.computed(function() {
        return this.firstName() + " " + this.lastName();
    }, this);
}

function HrManagementViewModel() {
    var self = this;
    self.users = ko.observableArray([]);

    $.getJSON("/users", function (data) {
        var mappedUsers = $.map(data, function (item) { return new User(item); });
        self.users(mappedUsers);
    });
}

And HTML code looks like this:

<ul data-bind="foreach: users">
   <li data-bind="text: fullName"></li>
</ul>

What I'm trying to accomplish here is whenever list item is clicked, editing form shows up prepopulated with clicked user's information. Any tips or tricks on how to accomplish this would be super awesome of you guys. Thanks.

Upvotes: 2

Views: 1502

Answers (1)

egor-k8n
egor-k8n

Reputation: 91

ko.applyBindings() function has an optional second argument, which can be used to specify the element you want to search for data-bind attributes. So you can make something like this:

<ul data-bind="foreach: users">
    <li data-bind="text: fullName, click: $parent.showForm"></li>
</ul>
<hr/>
<form id="form">
    <p><input data-bind="value: id"></input></p>
    <p><input data-bind="value: firstName"></input></p>
    <p><input data-bind="value: lastName"></input></p>
</form>

Then, in HrManagementViewModel:

self.currentUser = ko.observable(null);

self.showForm = function(user, event) {
    // first argument here is the item, associated with the <li> element
    // second - the event object.

    var previousSelection = self.selectedUser();
    self.selectedUser(user); // Wrap your user viewModel in observable. To change
                             // the input fields bindings just update it 
                             // with a new viewModel and KO will do the rest.
    if (previousSelection == null) {
        var target = document.getElementById('form');
        ko.applyBindings(self.selectedUser, target); 
    }
}

Here, give it a try: http://jsfiddle.net/mH3fx/4/

Upvotes: 3

Related Questions