Reputation: 6916
I have a table of users that I need to filter by their activity based on a radio button changed.
I did it with Knockout but it doesn't work, I don't get an error, but the table comes up empty, am I do something wrong?
Without the filtering, the page works perfectly (when the foreach is on users
and not filteredUsers
)
The radio buttons:
<div class="btn">
<input id="active" checked class="filterOpt selectedRadio" name="filterOpt" type="radio" data-bind="checked: inactive, attr: { 'value': 'false' }" /> <label class="filterLbl selectedRadio" for="active">ACTIVE</label>
</div>
<div class="btn">
<input id="inActive" class="filterOpt" name="filterOpt" type="radio" data-bind="checked: inactive, attr: { 'value': 'true' }" /> <label class="filterLbl" for="inactive">INACTIVE</label>
</div>
<div class="btn">
<input id="all" class="filterOpt" name="filterOpt" type="radio" data-bind="checked: inactive, attr: { 'value': 'all' }" /> <label class="filterLbl" for="all">ALL</label>
</div>
And the KO code:
self.users= ko.observableArray([]);
self.inactive = ko.observable();
self.filteredClients = ko.observableArray([]);
self.filteredUsers= ko.computed(function () {
var val = self.inactive();
return self.users().filter(function (item) {
console.log(ko.toJSON(item));
return item.inactive === val;
});
});
Then my table:
<!--ko foreach: filteredUsers-->
<table class="table">
<tr class="header">
<td class="name n" data-bind="text: name"></td>
<td class="rep" data-bind="text: email"></td>
<td class="status" data-bind="text: inactive"></td>
</tr>
</table>
Upvotes: 1
Views: 756
Reputation: 6916
After @JoseLuis's answer, I was able to get it to work with a few minor changes, I post it in case someone in the future will run into a similar issue.
As @JoseLuis mentioned the problem was with the comparison of Boolean
and String
, in order to solve that I parsed the String
to Boolean
then I got a comparison between two booleans.
And this is the entire function:
self.filteredUsers = ko.computed(function () {
if (self.inactive() == "true" || self.inactive() == "false") {
var val = JSON.parse(self.inactive());
}
else var val = self.inactive();
return self.users().filter(function (item) {
return (item.inactive() === val) || (val === 'all');
});
});
Upvotes: 1
Reputation: 994
Your radio buttons returns the selected value as a string. If the User object has inactive
as a boolean, then the ===
always is going to return false, because you are comparing a boolean with a string.
This is a Codepen as an example. You could see than User 2
has a true as a boolean, and is not show (User 1
is show).
This is the User
object:
function User(name, inactive){
var self = this;
self.inactive = inactive;
self.name = name;
self.email = "[email protected]"
}
This is the ViewModel:
function ViewModel() {
self.users= ko.observableArray([
new User('User 1', 'true'),
new User('User 2', true),
new User('User 3', 'false'),
]);
self.inactive = ko.observable();
self.filteredClients = ko.observableArray([
]);
self.filteredUsers= ko.computed(function () {
var val = self.inactive();
return self.users().filter(function (item) {
console.log(ko.toJSON(item));
return (item.inactive === val) || (val === 'all');
});
});
}
As you can see, I create three User
:
new User('User 1', 'true'),
new User('User 2', true),
new User('User 3', 'false'),
The second has true
as boolean, the others have a string. If you change the boolean with a text, both users are shown.
Please, write you answer too.
:-)
Upvotes: 1