Hello, Can DataTables be generated using an Endpoint URL, with pagination and search functionality handled on the client side?
Metronic v9 Tailwindcss and Laravel.
Hi
Sorry for the delay in response.
By default, providing an apiEndpoint puts the datatable into server-side processing mode, where every action (pagination, search, sort) triggers a new API call.
To get the behavior you want, we will:
- Initialize the datatable without the apiEndpoint option.
- Manually fetch the entire dataset from your URL using the fetch API.
- Inject the fetched data into the datatable's internal state.
- Tell the datatable to reload, which will now use the data you provided for all client-side operations.
This is what we can do at the moment, until the datatable support it natively.
Here is the updated JavaScript code. You can replace your existing script with this.
https://gist.github.com/faizalmy/62faa5858e9c535d9b081e858dc77208
Make sure your Laravel endpoint at {{ route("personal.getlista") }} returns a JSON array of all the records.
Thanks
Hi,
I understand, at the moment it is being handled that way, but certain functionalities are lost, such as datatable.reload(), since it does not make another call to the API. Perhaps they can include it later, thank you.
Hi, what you shared looks great for manipulating and rendering tables, but if I only fetch data from the endpoint when performing a search or advancing pagination, it makes an HTTP request to reorder and repaint the data again, which I’m trying to avoid. Ideally, I’d like to use the endpoint to fetch the data, create the <tbody> with columns, and then, when I type in the input or click the next page button, it doesn’t make an HTTP request but works locally instead.
document.addEventListener('DOMContentLoaded', function() {
const datatableElement = document.querySelector('#kt_remote_table');
const options = {
apiEndpoint: '{{ route ("personal.getlista") }}',
pageSize: 10,
pageSizes: [5, 10, 25, 50, 100],
columns: {
checkbox: {
title: '',
render: function(data, type, row) {
return '<input type="checkbox" class="kt-checkbox kt-checkbox-sm" data-kt-datatable-row-check="true" value="' + data + '" />';
},
},
id: {
title: 'ID',
data: 'id',
width: '1%',
responsivePriority: 1,
sorter: 'number',
},
nombre: {
title: 'Name',
},
email: {
title: 'Email',
},
rol: {
title: 'Rol',
},
two_factor: {
title: '2FA',
data: 'two_factor',
render: function(data, type, row) {
return data;
}
},
status: {
title: 'Status',
data: 'status',
render: function(data, type, row) {
return data;
}
},
tools: {
title: '',
width: '1%',
responsivePriority: 1,
render: function(data, type, row) {
return data;
}
}
},
};
// Inicializar el DataTable
const datatable = new KTDataTable(datatableElement, options);
});
Hi
Yes, DataTables can be generated using an endpoint URL from a server while handling pagination and search functionality entirely on the client side.
You can refer to /metronic-tailwind-html/src/app/datatables example folder.
Here is some example code.
// Assuming you have a table element in your HTML like:
// <div data-kt-datatable="true">
// <table data-kt-datatable-table="true">
// <!-- Your table headers and body -->
// </table>
// <!-- Other elements like pagination controls -->
// </div>
document.addEventListener("DOMContentLoaded", () => {
const element = document.querySelector("[data-kt-datatable="true"]"); // Target your table container
if (element) {
const datatable = new KTDataTable(element, {
apiEndpoint: "/your-laravel-endpoint-url", // Your Laravel API endpoint, e.g., "/api/data"
requestMethod: "GET", // Or "POST" if needed
requestHeaders: {
"Content-Type": "application/json", // Adjust based on your API
// Add any auth headers if required, e.g., "Authorization": "Bearer your-token"
},
pageSize: 10, // Initial page size for client-side pagination
pageSizes: [5, 10, 20, 30, 50], // Options for users to change
search: {
delay: 500, // Delay for search input
callback: (data, searchString) => { // This is already defined in your code
// Filters data locally; no changes needed
return data.filter(item =>
Object.values(item).some(value =>
String(value).toLowerCase().includes(searchString.toLowerCase())
)
);
},
},
sort: {
callback: (data, sortField, sortOrder) => {
// Sorts data locally; uses the existing sort handler
return data.sort((a, b) => {
if (a[sortField] < b[sortField]) return sortOrder === "asc" ? -1 : 1;
if (a[sortField] > b[sortField]) return sortOrder === "asc" ? 1 : -1;
return 0;
});
},
},
pagination: {
// Use the default pagination templates from your code
},
stateSave: true, // Optionally save state for persistence
});
// Now, trigger a reload to fetch data from the endpoint
datatable.reload(); // This will fetch all data via _fetchDataFromServer() and then process it client-side
// Example: Programmatically search or paginate
const searchInput = document.querySelector("input[data-kt-datatable-search]"); // Assuming you have a search input
if (searchInput) {
searchInput.addEventListener("keyup", () => {
datatable.search(searchInput.value); // Calls the search method, which uses the client-side callback
});
}
// Example: Navigate to a specific page
// datatable.goPage(2); // Go to page 2, which slices the data array locally
}
});