How to add sortable columns and pagination to Bootstrap tables in 2025
How to Add Sortable Columns and Pagination to Bootstrap Tables in 2025
Building data tables that users can actually interact with—sorting columns, filtering rows, paginating through hundreds of records—is a common requirement in web applications. While Bootstrap provides excellent CSS styling for tables, the markup alone doesn't give you these interactive features. That's where bootstrap-table comes in: a lightweight jQuery plugin that extends standard Bootstrap tables with sorting, pagination, checkboxes, and AJAX data loading.
In this guide, you'll learn how to set up bootstrap-table, configure sortable columns, enable pagination, and handle row selection with checkboxes.
Why Use bootstrap-table?
You could build table interactivity from scratch, but bootstrap-table saves significant development time by providing:
- Instant sorting with click-to-sort column headers
- Built-in pagination with customizable page sizes
- Row selection via checkboxes or radio buttons
- AJAX data loading for server-side pagination
- Responsive design that adapts to mobile screens
- Multiple CSS framework support (Bootstrap, Semantic UI, Bulma, Material Design)
- Card view and detail views for better mobile UX
- Column visibility toggling without reloading data
Unlike heavyweight data grid libraries, bootstrap-table is lightweight (~50KB) and integrates seamlessly with existing Bootstrap projects.
Step 1: Install bootstrap-table
You have three installation options:
Via npm (Recommended)
npm install bootstrap-table
Via Yarn
yarn add bootstrap-table
Via CDN
If you prefer not to use a build tool:
<!-- Bootstrap CSS (required) -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css">
<!-- bootstrap-table CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.22.1/bootstrap-table.min.css">
<!-- jQuery (required) -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<!-- Bootstrap JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/js/bootstrap.bundle.min.js"></script>
<!-- bootstrap-table JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.22.1/bootstrap-table.min.js"></script>
Step 2: Create a Basic Table with Sorting
Here's a minimal HTML table that bootstrap-table will enhance:
<table id="table"
class="table table-striped"
data-toggle="table"
data-sortable="true"
data-sort-name="name"
data-sort-order="asc">
<thead>
<tr>
<th data-field="id" data-sortable="true">ID</th>
<th data-field="name" data-sortable="true">Name</th>
<th data-field="email" data-sortable="true">Email</th>
<th data-field="status">Status</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>John Doe</td>
<td>john@example.com</td>
<td>Active</td>
</tr>
<tr>
<td>2</td>
<td>Jane Smith</td>
<td>jane@example.com</td>
<td>Active</td>
</tr>
<tr>
<td>3</td>
<td>Bob Johnson</td>
<td>bob@example.com</td>
<td>Inactive</td>
</tr>
</tbody>
</table>
<script>
$('#table').bootstrapTable()
</script>
Key attributes:
data-toggle="table"— Tells bootstrap-table to initialize this elementdata-sortable="true"— Enables column sortingdata-field— Maps column to data propertydata-sort-nameanddata-sort-order— Set default sort column and direction
Step 3: Add Pagination
To enable pagination, add these attributes to the <table> element:
<table id="table"
class="table table-striped"
data-toggle="table"
data-sortable="true"
data-pagination="true"
data-page-size="10"
data-page-list="[5, 10, 25, 50]">
<!-- thead and tbody remain the same -->
</table>
Pagination attributes:
data-pagination="true"— Enables pagination controlsdata-page-size="10"— Sets initial rows per pagedata-page-list="[5, 10, 25, 50]"— Options for rows-per-page dropdown
Step 4: Enable Row Selection with Checkboxes
Add a checkbox column to allow users to select multiple rows:
<table id="table"
class="table table-striped"
data-toggle="table"
data-sortable="true"
data-pagination="true"
data-page-size="10"
data-show-select="true">
<thead>
<tr>
<th data-field="state" data-checkbox="true"></th>
<th data-field="id" data-sortable="true">ID</th>
<th data-field="name" data-sortable="true">Name</th>
<th data-field="email" data-sortable="true">Email</th>
</tr>
</thead>
<tbody>
<!-- rows -->
</tbody>
</table>
<script>
var $table = $('#table');
$table.bootstrapTable();
// Get selected rows
document.getElementById('getSelected').addEventListener('click', function() {
var rows = $table.bootstrapTable('getSelections');
console.log('Selected rows:', rows);
});
</script>
Selection attributes:
data-show-select="true"— Displays select-all header checkboxdata-field="state" data-checkbox="true"— Creates checkbox column
Step 5: Load Data via AJAX
For larger datasets, fetch data from a server endpoint:
<table id="table"
class="table table-striped"
data-toggle="table"
data-url="/api/users"
data-pagination="true"
data-page-size="10"
data-side-pagination="server"
data-show-select="true">
<thead>
<tr>
<th data-field="state" data-checkbox="true"></th>
<th data-field="id" data-sortable="true">ID</th>
<th data-field="name" data-sortable="true">Name</th>
<th data-field="email" data-sortable="true">Email</th>
</tr>
</thead>
</table>
<script>
$('#table').bootstrapTable({
url: '/api/users',
method: 'GET',
sidePagination: 'server',
queryParams: function (params) {
return {
limit: params.limit,
offset: params.offset,
sort: params.sort,
order: params.order
};
}
});
</script>
Your API endpoint should return JSON with this structure:
{
"total": 100,
"totalNotFiltered": 100,
"rows": [
{"id": 1, "name": "John Doe", "email": "john@example.com"},
{"id": 2, "name": "Jane Smith", "email": "jane@example.com"}
]
}
Configuration Comparison: Data Attributes vs JavaScript
| Feature | Data Attribute | JavaScript Option | Best For |
|---------|----------------|--------------------|----------|
| Sorting | data-sortable="true" | sortable: true | Simple tables |
| Pagination | data-pagination="true" | pagination: true | Pre-rendered data |
| Server-side pagination | data-side-pagination="server" | sidePagination: 'server' | Large datasets |
| Row selection | data-show-select="true" | showSelect: true | Admin dashboards |
| Custom formatting | — | formatter function | Conditionally styled cells |
Common Use Cases
Format Cell Values
Display custom content (badges, buttons, formatted dates) in cells:
$('#table').bootstrapTable({
columns: [{
field: 'status',
formatter: function(value) {
var badgeClass = value === 'Active' ? 'success' : 'danger';
return '<span class="badge bg-' + badgeClass + '">' + value + '</span>';
}
}]
});
Handle Row Click Events
Execute actions when users click a row:
$('#table').on('click-row.bs.table', function(e, row) {
console.log('Clicked row:', row);
// Navigate to detail page, open modal, etc.
});
Programmatically Add/Remove Rows
var $table = $('#table');
// Add new row
$table.bootstrapTable('insertRow', {
index: 0,
row: {id: 999, name: 'New User', email: 'new@example.com'}
});
// Remove row by ID
$table.bootstrapTable('remove', {field: 'id', values: [999]});
Troubleshooting
Sorting not working: Ensure data-sortable="true" is on both the table AND the <th> elements.
Checkboxes missing: Verify you have a <th> with data-field="state" data-checkbox="true" and data-show-select="true" on the table.
AJAX data not loading: Check browser console for network errors. Verify your endpoint returns the correct JSON structure with total and rows properties.
Next Steps
Once you've mastered basic sorting and pagination, explore:
- Column filtering (
data-filter-control="true") - Export to Excel/CSV (via extensions)
- Keyboard navigation (accessibility)
- Custom toolbar buttons for bulk actions
- Mobile card view (
data-card-view="true")
bootstrap-table handles the tedious DOM manipulation so you can focus on business logic. For production dashboards with hundreds of rows, server-side pagination keeps load times minimal while maintaining a responsive UX.
Recommended Tools
- GitHubWhere the world builds software
- DigitalOceanCloud hosting built for developers — $200 free credit for new users