Reputation: 3
I am creating table with pagination and search filter. We bind table data with search filter, Is the possible to crate search filter in table with pagination. How to create pagination in table, and also perform search filter, along with sorting also.
function PlayersViewModel() {
var self = this,x, i, suits;
/* text field should be empty */
self.filterText = ko.observable(""); // Text from search field
//#region Constant Properties
self.descending = "fa fa-arrow-down";
self.ascending = "fa fa-arrow-up";
//#endregion
self.CurrentPage = ko.observable(1); // Store the current page of the user
self.DataPerPage = ko.observable(5); // To identify how many data we want to see per page
//#region Knockout Observables
// Observable array that represents each column in the table
self.columns = ko.observableArray([
{ property: "id", header: "ID", type: "number", state: ko.observable("") },
{ property: "name", header: "Name", type: "string", state: ko.observable("") },
{ property: "time", header: "Time", type: "date", state: ko.observable("") },
{ property: "dob", header: "Date of Birth", type: "date", state: ko.observable("") },
{ property: "address", header: "Address", type: "string", state: ko.observable("") },
{ property: "msg", header: "Body", type: "string", state: ko.observable("") }
]);
// Observable array that will be our data
self.players = ko.observableArray([
{ id: "01", name: "Micky", time: "2015-02-09 4:46:56.678", dob: "10/20/1974", address: "London", msg: "Received Message" },
{ id: "02", name: "Griffey", time: "2015-03-09 4:46:54.678", dob: "11/21/1969", address: "Russia", msg: "Received Message" },
{ id: "03", name: "Derek", time: "2015-01-07 4:46:55.678", dob: "6/26/1931", address: "London", msg: "Send Message" },
{ id: "04", name: "Steven", time: "2015-03-09 4:46:56.678", dob: "2/10/1963", address: "Russia", msg: "Send Message" },
{ id: "05", name: "Jafer", time: "2015-02-09 5:46:56.540", dob: "12/18/1886", address: "London", msg: "Received Message" },
{ id: "06", name: "Jenifer", time: "2015-01-14 4:52:16.379", dob: "11/29/1970", address: "China", msg: "Send Message" },
{ id: "07", name: "Jones", time: "2015-03-08 5:26:33.600", dob: "8/24/1895", address: "London", msg: "Received Message" },
{ id: "08", name: "Micky", time: "2015-02-09 4:46:56.678", dob: "10/20/1974", address: "London", msg: "Received Message" },
{ id: "09", name: "Bruce", time: "2015-03-09 4:46:54.678", dob: "11/21/1969", address: "Russia", msg: "Received Message" },
{ id: "10", name: "Peter", time: "2015-01-07 4:46:55.678", dob: "6/26/1931", address: "London", msg: "Send Message" },
{ id: "11", name: "Wayne", time: "2015-03-09 4:46:56.678", dob: "2/10/1963", address: "Russia", msg: "Send Message" },
{ id: "12", name: "Sam", time: "2015-02-09 5:46:56.540", dob: "12/18/1886", address: "London", msg: "Received Message" },
{ id: "13", name: "Jenifer", time: "2015-01-14 4:52:16.379", dob: "11/29/1970", address: "China", msg: "Send Message" },
{ id: "14", name: "Smith", time: "2015-03-08 5:26:33.600", dob: "8/24/1895", address: "London", msg: "Received Message" }
]);
//#endregion
/* script for search filter */
suits = self.players();
for ( i = 0; i < suits.length; i++) {
suits[i]["search_content"] = ">";
for ( x in suits[i] ) {
if ( !suits[i].hasOwnProperty(x) || x == "search_content" || typeof suits[i][x] !== "string") {continue;}
suits[i]["search_content"] += suits[i][x].toUpperCase();
}
}
// Collection of players after going through search filter
self.filteredTestsuites = ko.computed(function () {
var reg;
// If many white spaces in a row, replace with only one white space
fText = self.filterText().replace(/\s+/gi, '|');
fText = fText.replace(/\|\s*$/gi, '');
console.log("regex:", fText);
reg = new RegExp(fText, "gi");
// If there is anything in the search box, filter for this
// As of now this does not divide the filterText and only searches the Name field
var filteredCollection = ko.utils.arrayFilter(self.players(), function(test) {
if(fText.length)
return test.search_content.match(reg);
else
return 1;
});
return filteredCollection;
}, self);
/* script Ends with text search */
/* script for sorting */
//#region Sorting methods
self.sortClick = function (column) {
try {
// Call this method to clear the state of any columns OTHER than the target
// so we can keep track of the ascending/descending
self.clearColumnStates(column);
// Get the state of the sort type
if (column.state() === "" || column.state() === self.descending) {
column.state(self.ascending);
}
else {
column.state(self.descending);
}
console.log(column.state());
console.log(column.type);
switch (column.type) {
case "number":
self.numberSort(column);
break;
case "date":
self.dateSort(column);
break;
case "string":
default:
self.stringSort(column);
break;
}
}
catch (err) {
// Always remember to handle those errors that could occur during a user interaction
alert(err);
}
};
// Generic sort method for numbers and strings
self.stringSort = function (column) { // Pass in the column object
self.players(self.players().sort(function (a, b) {
// Set strings to lowercase to sort properly
var playerA = a[column.property].toLowerCase(), playerB = b[column.property].toLowerCase();
if (playerA < playerB) {
return (column.state() === self.ascending) ? -1 : 1;
}
else if (playerA > playerB) {
return (column.state() === self.ascending) ? 1 : -1;
}
else {
return 0
}
}));
};
self.numberSort = function (column) {
self.players(self.players().sort(function (a, b) {
var playerA = a[column.property], playerB = b[column.property];
if (column.state() === self.ascending) {
return playerA - playerB;
}
else {
return playerB - playerA;
}
}));
};
// Sort by date
self.dateSort = function (column) {
self.players(self.players().sort(function (a, b) {
if (column.state() === self.ascending) {
return new Date(a[column.property]) - new Date(b[column.property]);
}
else {
return new Date(b[column.property]) - new Date(a[column.property]);
}
}));
};
//#region Utility Methods
self.clearColumnStates = function (selectedColumn) {
var otherColumns = self.columns().filter(function (col) {
return col != selectedColumn;
});
for (var i = 0; i < otherColumns.length; i++) {
otherColumns[i].state("");
}
};
/* script Ends for sorting */
};
ko.applyBindings(new PlayersViewModel());
They should perform search filter and sorting in the table correctly, how to create pagination for the sample, they do not affect the search filter and sorting in the table.
Upvotes: 0
Views: 477
Reputation: 23397
The basics of pagination using a ko.pureComputed
:
const paginatedData = ko.pureComputed(
() => dataSource().slice(
currentPage() * pageSize(),
currentPage() * pageSize() + pageSize()
)
);
In your specific case, dataSource
is filteredTestsuites
, currentPage
is CurrentPage
and pageSize
is DataPerPage
.
Things to keep in mind:
- Fix the lower limit of currentPage
to 0
- Fix the upper limit of currentPage
to Math.floor(dataSource().length)
- Make sure that when the dataSource
changes in length (i.e. when filtering), the currentPage
is updated to match the new restrictions
- Make sure that when pageSize
is made larger, the currentPage
is updated to match the new restrictions.
const currentPage = ko.observable(0);
const pageSize = ko.observable(5);
const dataSource = ko.observableArray(
Array.from({ length: 100 }, (_, i) => i)
);
const paginatedData = ko.pureComputed(
() => dataSource().slice(
currentPage() * pageSize(),
currentPage() * pageSize() + pageSize()
)
);
ko.applyBindings({
next: () => currentPage(currentPage() + 1),
prev: () => currentPage(currentPage() - 1),
currentPage,
paginatedData
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<ul data-bind="foreach: paginatedData">
<li data-bind="text: $data"></li>
</ul>
<button data-bind="click: prev"><</button>
<span data-bind="text: currentPage"></span>
<button data-bind="click: next">></button>
Upvotes: 0