todd.pund todd.pund - 1 year ago 120
jQuery Question

Knockout.js - text input on each row of foreach table, should only edit field on that row

I have created a fiddle of the following code here.

I have created a table using a knockout foreach. Each row can be removed by an inline button on that row. Rows can be dynamically added, and a label can be edited in real time by selecting the row then using the textbox.

What I am wanting to do is move that one textbox into multiple textboxes, one on each row that edits that row alone. Help is appreciated.


function Model() {
var self = this;
this.tasks = ko.observableArray();
this.container = ko.observableArray();
this.tid = ko.observable(0);
this.addTask = function(id, content, content2) {
var obj = {
id: ko.observable(id),
content: ko.observable(content),
content2: ko.observable(content2),
selected: ko.observable(false)
this.addNewTask = function() {
var obj = {
id: self.tid() + 1,
content: "New Task",
content2: "New Service",
selected: ko.observable(false)
self.tid(self.tid() + 1);

this.selectedIndex = ko.observable(0);
this.selectTask = function(task) {
self.removeTask = function(task) {

var myModel = new Model();
myModel.addTask(1, "Task 1", "Service 1");
myModel.addTask(2, "Task 2", "Service 2");
myModel.addTask(3, "Task 3", "Service 3");



<div data-bind="foreach: tasks">
<table cellpadding="0" cellspacing="0">
<label class="wrapper" data-bind="text: content, click: $root.selectTask, css: {'selected': $root.selectedIndex() === $index()}" />
<span class="wrapper" data-bind="text: content2, click: $root.selectTask, css: {'selected': $root.selectedIndex() === $index()}"></span>
<td> <input type="button" value="remove" data-bind="click: $parent.removeTask"></td>

<br />
Add New Task: &nbsp;<input type="button" value="add" data-bind="click: addNewTask"><br /><br />
<label>Edit Task:</label> <input type="text" data-bind="value: tasks()[selectedIndex()].content2, valueUpdate: 'afterkeydown'">

Answer Source

You can move the <input> to its own <td> in the row.

You're currently binding the input to the selected item; on its new location, you can just bind it to the bindingContext:

  <label>Edit Task:</label> <input type="text" data-bind="value: content2, valueUpdate: 'afterkeydown'">

For it to work on new items, you'll have to make sure those get observable properties as well. (I've also changed this in the updated fiddle)

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download