Reputation: 689
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.
Viewmodel:
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)
};
self.tid(id);
self.tasks.push(obj);
};
this.addNewTask = function() {
var obj = {
id: self.tid() + 1,
content: "New Task",
content2: "New Service",
selected: ko.observable(false)
}
self.tid(self.tid() + 1);
self.tasks.push(obj);
}
this.selectedIndex = ko.observable(0);
this.selectTask = function(task) {
self.selectedIndex(self.tasks.indexOf(task));
};
self.removeTask = function(task) {
self.tasks.remove(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");
ko.applyBindings(myModel);
View:
<div data-bind="foreach: tasks">
<table cellpadding="0" cellspacing="0">
<tr>
<td>
<label class="wrapper" data-bind="text: content, click: $root.selectTask, css: {'selected': $root.selectedIndex() === $index()}" />
</td>
<td>-</td>
<td>
<span class="wrapper" data-bind="text: content2, click: $root.selectTask, css: {'selected': $root.selectedIndex() === $index()}"></span>
</td>
<td> <input type="button" value="remove" data-bind="click: $parent.removeTask"></td>
</tr>
</table>
</div>
<br />
Add New Task: <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'">
Upvotes: 0
Views: 1319
Reputation: 141
First of all, if you want to edit your newly created lines, you have to make ko.observable its values :
this.addNewTask = function() {
var obj = {
id: ko.observable(self.tid() + 1),
content: ko.observable("New Task"),
content2: ko.observable("New Service"),
selected: ko.observable(false)
} ....
Then, to have a textbox on each line, replace :
<span class="wrapper" data-bind="text: content2, click: $root.selectTask, css: {'selected': $root.selectedIndex() === $index()}"></span>
with :
<input type="text" data-bind="value: content2, valueUpdate: 'afterkeydown'">
To go further move your data-bind="foreach: tasks" to the . You'll repeatlines and not tables for each task.
Upvotes: 0
Reputation: 23372
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
:
<td>
<label>Edit Task:</label> <input type="text" data-bind="value: content2, valueUpdate: 'afterkeydown'">
</td>
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)
https://jsfiddle.net/90w1pagr/
Upvotes: 1