Reputation: 1003
I am trying to put together a single page application that allows faceted searching and paging at the same time. I am fairly new to Knockout and I am struggling getting the two concepts linked together.
The development site can be seen here http://especial2.egcommerce.com/search
function ProductDimensionsViewModel () {
var self = this;
self.dimensions = ko.observableArray();
//self.dimensions(data);
var baseUri = 'api/product_dimensions.php';
$.getJSON(baseUri, self.dimensions);
//self.dimensions.subscribe(function(updated) {
// alert(updated);
// });
self.filterByBrand = ko.computed(function() {
return ko.utils.arrayFilter(self.dimensions(), function(dimension) { return dimension.type == "BRAND"; })
});
self.filterByArea = ko.computed(function() {
return ko.utils.arrayFilter(self.dimensions(), function(dimension) { return dimension.type == "AREA"; })
});
self.filterByType = ko.computed(function() {
return ko.utils.arrayFilter(self.dimensions(), function(dimension) { return dimension.type == "TYPE"; })
})
self.filterByBrandMenu = ko.computed(function() {
return ko.utils.arrayFilter(self.dimensions(), function(dimension) { return dimension.type == "BRAND" && dimension.menuItem == "YES"})
});
self.filterByAreaMenu = ko.computed(function() {
return ko.utils.arrayFilter(self.dimensions(), function(dimension) { return dimension.type == "AREA" && dimension.menuItem == "YES"})
});
self.filterByTypeMenu = ko.computed(function() {
return ko.utils.arrayFilter(self.dimensions(), function(dimension) { return dimension.type == "TYPE" && dimension.menuItem =="YES" })
});
self.products = ko.observableArray();
$.getJSON("api/products", self.products);
//self.products(product)
//console.log(self.products(data.count));
/*
* Paging functionality
*/
// only for example, used to demonstrate setting the total item count from a service call.
self.SetTotalResults = ko.observable(100);
// holds the total item count
self.TotalResults = ko.observable();
// actual pager, used to bind to the pager's template
// first parameter must be an observable or function which returns the current 'total item count'.
// it is wrapped in a ko.computed inside the pager.
self.Pager = ko.pager(self.TotalResults);
// Subscribe to current page changes.
self.Pager().CurrentPage.subscribe(function () {
self.search();
});
self.search = function () {
// simulate a search
// ie.:
/*
var maximumRows = self.Pager().PageSize(),
searchText = self.SearchText(),
startIndex = (self.Pager().CurrentPage() - 1) * maximumRows;
myService.search(searchText, startIndex, maximumRows)
.done(function(result) {
// set your own results etc...
self.TotalResults(result.totalItemCount);
}
*/
// setting 'total results'. This should be in your result callback
// in this example we grab it from the form.
var totalItemCount = self.SetTotalResults();
self.TotalResults(totalItemCount);
}
ko.applyBindings(new ProductDimensionsViewModel())
As you can see I have managed to populate the filters and pull in the products from a ajax call.
I now need some guidance with the following.
Any help would be appreciated, the site is only ever likely to have 1500 products so i think the solution I am trying to put in place will make the navigating the products quite slick.
Thanks for any help Rob
Upvotes: 0
Views: 1248
Reputation: 10145
This is a little challenging to explain without writing all the code, but hopefully these additions makes sense:
self.page = ko.observable(0)
self.pageSize = ko.observable(20)
self.filters = [
{ id: 'dining', label: 'Fine Dining', active: ko.observable(false) },
{ id: 'events', label: 'Hospitality and Events', active: ko.observable(false) },
{ id: 'restaurants', label: 'Restaurant', active: ko.observable(false) }
// etc...
]
self.activeFilters = ko.computed(function() {
return self.filters.filter(function(filter) {
return filter.active();
})
})
self.activeFilters.subscribe(function() {
// Make ajax call based on activeFilters, and start and pageSize as params
})
<ul data-bind="foreach: filters">
<li>
<input type="checkbox" data-bind="checked: active">
<label data-bind="text: label"></label>
</li>
</ul>
The paging markup is not shown here, but would be bound to the self.page and self.pageSize observables depending on how you want to control it.
Hope this helps.
Upvotes: 1