Let’s DataTable

  • It increases page loading time which might discourage people from using your web application.
  • It might crash your web application because of having to load too much data at once.
  • Having too much information to feed the users might be a bit discouraging.
  • Adding custom filters/fields might be a bit difficult to implement.
  1. Control what you load from the server
  2. Control the data formatting
  3. Control the pagination
  4. Control the re-rendering of the table
  5. Control the filter, sorting and searching

Control what you load from the server

DataTable({
ajax: {
url: requestURL,
headers: {
'Authorization': 'Bearer ' + $('#token').val()
},
dataSrc: function (JSONResponseFromServer) {
return filterData(JSONResponseFromServer);
},
});

Control the data formatting

initComplete: function (settings, JSONResponseFromServer) {
// buildPagination(JSONResponseFromServer);
// format JSON response
}
DataTable({
columnDefs: [
target: 0 // table column index
data: null // null if you're not sure of the column name
orderable: false, // if you do not want the column to be sorted
render: function(data, type, row) {
// You can do date formatting
return moment().format("l hh:ss a z");

//Decide what data format to return for the column
const complete = row.complete;
if (true === complete) {
return "Yes";
}
return "No";
}
] })

Control the pagination

{
current_page: 1
data: [{id: 5696, user_id: 2319, name: "House Wallace LLC", address: "Necessitatibus lauda"}]
first_page_url: "http://byd.test/api/admin/users?page=1"
from: 1
last_page: 81
last_page_url: "http://byd.test/api/admin/users?page=81"
next_page_url: "http://byd.test/api/admin/users?page=2"
path: "http://byd.test/api/admin/users"
per_page: 50
prev_page_url: null
to: 50
total: 4040
}
const buildPagination = (JSONResponseFromServer) => {
const json = JSONResponseFromServer
let links = "";
const paginate = $("ul.pagination");
const nextPageURL = json.next_page_url;
const prevPageURL = json.prev_page_url;
if (null === prevPageURL) {
links += `
<li class="paginate_button previous disabled" id="nonprofits-list_previous">
<a href="#" aria-controls="nonprofits-list" data-dt-idx="0" tabindex="0">Previous</a>
</li>`;
}
if (null !== prevPageURL) {
links += `
<li class="paginate_button previous" id="list_previous">
<a href="#" data-dt-href="${json.prev_page_url}" aria-controls="list" data-dt-idx="${
json.current_page - 1
}" tabindex="0">Previous</a>
</li>`;
}
if (null !== json.last_page_url) {
links += `
<li class="paginate_button disabled pager_info">
<a href="#" aria-controls="nonprofits-list" data-dt-idx="1" tabindex="0" disabled>Page ${json.current_page} of ${json.last_page}</a>
</li>`;
}
if (null === nextPageURL) {
links += `
<li class="paginate_button next disabled" id="list_next">
<a href="#" aria-controls="list" data-dt-idx="0" tabindex="0">Next</a>
</li>`;
}
if (null !== nextPageURL) {
links += `
<li class="paginate_button next" id="list_next">
<a href="#" data-dt-href="${json.next_page_url}" aria-controls="list" data-dt-idx="${
json.current_page + 1
}" tabindex="0">Next</a>
</li>`;
}
paginate.html("").append(links);
};
initComplete: function (settings, json) {
state = {};
const immutableJson = Object.assign({}, json);
immutableJson.data = filterData(immutableJson);
state[immutableJson.first_page_url] = immutableJson;
buildPaginationLinks(immutableJson);
},
// pagination
$(document).on("click", ".next", function () {
refreshDataTable(table, $(this), state);
return false;
});
$(document).on("click", ".previous", function (e) {
refreshDataTable(table, $(this), state);
return false;
});
$(document).on("click", ".pager_info", function (e) {
return false;
});

Control the re-rendering of the table

const reDrawDataTable = (table, JSONResponse) => {
const filteredData = filterUserData(JSONResponse)
table.clear();
table.rows.add(filteredData).draw();
};
//You can also doconst table = DataTable({});
table.clear();
table.rows.add(JSONResponse).draw();

Control the filter, sorting and searching

// unbind sorting click event
$("th").unbind("click.DT");
$("th").bind("click.DT", function (e) {
e.stopPropagation();

let sort = "";
const column = e.target.cellIndex;
const sortBy = $(this).html().trim().toLocaleLowerCase();
if (!_this.hasClass("sorting_desc")) {
sort = "desc";
_this.removeClass("sorting_asc");
_this.addClass("sorting_desc");
} else {
sort = "asc";
_this.removeClass("sorting_desc");
_this.addClass("sorting_asc");
}
// Fetch and redraw the table
fetchAndReDrawTable(requestURL, table);
// tell DataTable to sort the column
table.order([[column, sort]]);
return false;
});
const getFormFilter = () => {
const form = $("form.admin-users");
const state = form.find("select#state");
const complete = form.find("select#complete");
return {
state,
complete,
};
};
$("#state").on("change", function () {
const requestURL = filterUsers();
fetchAndReDrawTable(requestURL, dataTable);
return false;
});
$("#complete").on("change", function () {
const requestURL = filterUsers();
fetchAndReDrawTable(requestURL, dataTable);

return false;
});
const filterUsers = () => {
const paginate = $("ul.pagination");
paginate.html("....");
const { state, complete } = getFormFilter(); const URL = 'any-url';
let search = $("#search");
const requestURL = encodeURI(
`${URL} q=${search.val().trim()}&state=${state.val()}&complete=${complete.val()}`
);
return requestURL;
};

Additional Tips

info: false, // Disable the table information at the bottom of the tablebDestroy: true, // Allow for creating a new instance of the datatable everytime eventhough it's been created before.bPaginate: false, // I want to control the pagination myself
pageLength: 50, //
stateSave: true // this will allow the table to remember the last pagination link you last visited until you clear your cache or build a reset button functionalitydom: '<"toolbar">frtip', // Add a contain/div where you can attach your custom control to the table header such as filter form, download dropdown type, etc
$("div.toolbar").html(
'<div class="" style="margin-top: 20px; ">' +
'<button type="button" class="btn btn-primary" id="delete_all">Delete All</button></div>'
);

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store