In my Razor view I have a table with 3 non displayed properties. Id_Loaction
, Id_Level
& Id_Section
Above this table I have 3 lists of checkboxes for every location, level & section with the appropriate Ids as the value.
@foreach (var section in Model.Sections)
{
<li>
<input type="checkbox" data-bind="checked: data" value="@Html.Encode(section.Value)"/>@Html.Encode(section.Text)
</li>
}
Note: section.Value
is the ID of the element which is also used in the table rows
The table itself is fairly simple built:
@foreach (var item in Model.Offers)
{
<tr data-bind="visible: data.IsChecked == true ">
<td>
@Html.DisplayFor(modelItem => item.Description)
</td>
<td>
@Html.DisplayFor(modelItem => item.Location)
</td>
<td>
@Html.DisplayFor(modelItem => item.Section.Text)
</td>
<td>
@Html.DisplayFor(modelItem => item.Section.Value)
</td>
<td>
@Html.DisplayFor(modelItem => item.Section.IsChecked)
</td>
<td>
@Html.DisplayFor(modelItem => item.Level)
</td>
<td>
@Html.ActionLink("Details", "Details", new { id=item.ID })
</td>
</tr>
}
<script type="text/javascript">
var data = @Html.Raw(Json.Encode(Model.Sections));
function FormViewModel(data) {
this.data = ko.observableArray(data);
}
window.viewModel = new FormViewModel(data);
console.log(viewModel.data());
ko.applyBindings(viewModel);
</script>
/edit: I have updated the code to my actual mess. The Model.Sections is a ViewModel, which is identical to the ViewModel used for Model.Offers.Section. Both contain a Value, Text and IsChecked property.
How can I compare both those and display only the table rows on which the section is checked?
Please go slow on me. Kind regards
this is an attempt at using knockout with a trimmed down version of what i am assuming Serv is trying to do. This is an example of a simple filter on a list of objects and can easily be expanded to include more filters and more complex models.
Fiddle http://jsfiddle.net/zTRq2/3/
Simple Filter ViewModel:
function filterViewModel(data) {
var self = this;
self.text = ko.observable(data.text);
self.checked = ko.observable(data.checked);
}
Trimmed down Offer View Model:
function offerViewModel(offer) {
var self = this;
self.description = offer.description;
self.location = offer.location;
}
Main View Model:
function FormViewModel(data) {
var self = this;
// map data from server to locations filter
self.locations = ko.observableArray(ko.utils.arrayMap(data.locations, function (filter) {
return new filterViewModel(filter);
}));
self.offersView = ko.computed(function () {
// get list of offers that were passed in, we'll manipulate filteredOffers from now on
var filteredOffers = data.offers;
// get all selected locations view models
var selectedFilterLocations = ko.utils.arrayFilter(self.locations(), function (location) {
return location.checked();
});
// run through util function to filter only offers that match any selected location
filteredOffers = ko.utils.arrayFilter(filteredOffers, function (offer) {
var matchesLocation = false;
ko.utils.arrayForEach(selectedFilterLocations, function (location) {
if (offer.location === location.text()) matchesLocation = true;
});
return matchesLocation;
});
return filteredOffers;
});
};
HTML:
<!-- list of location checkboxes -->
<ul class="unstyled inline" data-bind="foreach: locations">
<li>
<input type="checkbox" data-bind="checked: checked" /> <span data-bind="text: text"></span>
</li>
</ul>
<!-- table which is bound to the offersView computed observable -->
<!-- offersView is recalculated everytime a selection changes from the filter list -->
<table class="table-bordered">
<tbody data-bind="foreach: offersView">
<tr>
<td data-bind="text: description"></td>
<td data-bind="text: location"></td>
</tr>
</tbody>
</table>