Reputation: 3295
How i can change value of one column on the basis of another column value change.In the following code i want to update % column using marks columns value change.
HTML:
<table data-bind="foreach: users()">
<thead class="flip-content table-head">
<tr>
<th align="center">Name</th>
<th align="center">Marks</th>
<th align="center">% out of 100</th>
</tr>
</thead>
<tr >
<td data-bind="text: $data.name()"> </td>
<td>
<input data-bind="value: $data.marks()" />
</td>
<td data-bind='text: $data.percent()'></td>
</tr>
</table>
SCRIPT:
var UserModel = function () {
this.users = ko.observableArray([
{
id: 1,
name: ko.observable('Bob'),
marks: ko.observable(0),
percent: ko.computed(function () {
//percentage formula
}, this)
},
{
id: 2,
name: ko.observable('Jane'),
marks: ko.observable(0),
percent: ko.computed(function () {
//percentage formula
}, this)
}
]);
this.selectedUser = ko.observable(this.users()[0]);
}
var userModel = new UserModel();
ko.applyBindings(userModel);
How i can do this.
Upvotes: 1
Views: 354
Reputation: 23372
The easiest and most common solution is to use "class" instances rather than plain objects. These allow you to easily select the right marks
value because inside the constructor, this
refers to the current user.
var User = function(id, name, marks) {
this.id = id;
this.name = name;
this.marks = ko.observable(marks);
this.percent = ko.pureComputed(function() {
return this.marks() + "%";
}, this);
}
var UserModel = function () {
this.users = ko.observableArray([
new User(1, "Bob", 10),
new User(2, "Alice", 30),
]);
this.selectedUser = ko.observable(this.users()[0]);
}
var userModel = new UserModel();
ko.applyBindings(userModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<table data-bind="foreach: users()">
<thead class="flip-content table-head">
<tr>
<th align="center">Name</th>
<th align="center">Marks</th>
<th align="center">% out of 100</th>
</tr>
</thead>
<tr >
<td data-bind="text: name"> </td>
<td>
<input data-bind="value: marks" />
</td>
<td data-bind='text: percent'></td>
</tr>
</table>
If you absolutely need to use plain objects, you can define percent
's logic on your parent model and pass a reference to the current item in the view to create a computed on the fly. (I wouldn't recommend this)
var UserModel = function () {
this.users = ko.observableArray([
{
id: 1,
name: ko.observable('Bob'),
marks: ko.observable(0)
},
{
id: 2,
name: ko.observable('Jane'),
marks: ko.observable(0)
}
]);
this.selectedUser = ko.observable(this.users()[0])
};
UserModel.prototype.percentageFor = function(user) {
return user.marks() + "%";
};
var userModel = new UserModel();
ko.applyBindings(userModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<table data-bind="foreach: users()">
<thead class="flip-content table-head">
<tr>
<th align="center">Name</th>
<th align="center">Marks</th>
<th align="center">% out of 100</th>
</tr>
</thead>
<tr >
<td data-bind="text: name"> </td>
<td>
<input data-bind="value: marks" />
</td>
<td data-bind='text: $parent.percentageFor($data)'></td>
</tr>
</table>
Upvotes: 2