Reputation: 1945
I have observable array. I want to filter observable depending upon some text. I will select option button and depending upon it i need to filter observable array and bind to table. Here is my code till now. This is my view
<table>
<tbody data-bind="foreach: dataOne">
<tr >
<td data-bind="text: id"></td><td > </td>
<td data-bind="text: display"></td><td > </td>
<td> </td>
</tr>
</tbody>
<table >
<tr>
<td><input name="optbtn" type="radio" value="All"/> All</td>
<td><input name="optbtn" type="radio" value="Selected"/> Selected</td>
</tr>
</table>
Here is my view model
var data1 = [{
name1: "one",
id: 1,
display: "<temp>Is this employee</temp> required <val>in our company</val>"
}, {
name1: "two",
id: 2,
display: "<temp>Is this bachelor</temp>required in our group"
}, {
name1: "three",
id: 3,
display: "Test"
}];
var viewModel = {
dataOne: ko.observableArray(data1),
};
$("input[name='optbtn']").change(function (e) {
debugger;
var str = "<temp>";
var stringFromArray = "";
if ($(this).val() == "All") {
alert("All");
}
else {
ko.utils.arrayFirst(self.dataOne(), function (data) {
debugger;
stringFromArray = data.display();
if (stringFromArray.indexOf(str) == 0) {
return data.display();
}
});
}
});
ko.applyBindings(viewModel);
If i select "Selected" option button then it should only return with text "<temp>
in it.
So it should return only 2 records.
How can i achieve this? When i load my page it will show all records and mark "All" button as selected. When i selected "Selected" then it must filter records.
Update
here is my Fiddle
Upvotes: 1
Views: 813
Reputation: 139788
I would suggest that you should use the checked
binding on your options instead of subscribing manually to the change event.
<input name="optbtn" type="radio" value="All"
data-bind="checked: selection" />All
<input name="optbtn" type="radio"
data-bind="checked: selection" value="Selected" />Selected
And in your view model:
var viewModel = {
dataOne: ko.observableArray(data1),
selection: ko.observable("All")
};
Now that you have the current selection on your viewmodel you can add a ko.computed
(see doc) which does the filtering (it will trigger each time your viewModel.selection
changes):
viewModel.filteredData = ko.computed(function () {
var str = "<temp>";
if (viewModel.selection() == "All") return viewModel.dataOne();
return ko.utils.arrayFilter(viewModel.dataOne(), function (data) {
stringFromArray = data.display;
if (stringFromArray.indexOf(str) == 0) {
return true;
}
});
});
And use this filteredData
in your foreach
:
<tbody data-bind="foreach: filteredData">
<tr>
...
</tr>
</tbody>
Demo JSFiddle.
Note: you need to use ko.utils.arrayFilter
if you want to filter an array based on a criteria instead of ko.utils.arrayFirst
which returns the first found item. And you need to return true/false from its second parameter function to signal whether an item should be included or not.
Upvotes: 3