Việc kết hợp Bootstrap-Table cùng với Bootstrap Modal là một phương án phổ biến để hiển thị dữ liệu chi tiết một cách nhanh chóng. Tuy nhiên, trong quá trình triển khai, nhà phát triển thường gặp phải lỗi hiển thị: các hàng dữ liệu bị lệch, thanh cuộn không khớp hoặc xuất hiện khoảng trắng bất thường ở phía dưới bảng.
Nguyên nhân gây ra lỗi hiển thị
Vấn đề này thường xảy ra khi bảng được khởi tạo với thuộc tính height cố định bên trong một Modal đang trong trạng thái ẩn hoặc đang thực hiện hiệu ứng chuyển cảnh (animation). Tại thời điểm đó, trình duyệt không tính toán chính xác được kích thước của các phần tử DOM, dẫn đến việc lớp .fixed-table-container bị thiếu đi thuộc tính padding-bottom cần thiết (thông thường là 37px để dành chỗ cho phần phân trang hoặc thanh trạng thái).
Biểu hiện rõ nhất là khi bạn chuyển trang hoặc thay đổi kích thước trình duyệt, bảng sẽ tự động căn chỉnh lại và hiển thị bình thường. Tuy nhiên, việc để người dùng thấy giao diện lỗi trong lần đầu mở Modal là một trải nghiệm không tốt.
Giải pháp xử lý triệt để
Để giải quyết vấn đề này, chúng ta cần can thiệp vào giai đoạn sau khi bảng đã đổ dữ liệu vào DOM. Bootstrap-Table cung cấp sự kiện onPostBody, sự kiện này được kích hoạt mỗi khi thân bảng được render xong. Việc gán lại giá trị CSS tại đây đảm bảo giao diện luôn nhất quán bất kể trạng thái của Modal.
onPostBody: function () {
// Chỉ định lại khoảng đệm phía dưới để tránh lỗi tràn dòng hoặc lệch khung
$('.fixed-table-container').css('padding-bottom', '37px');
}
Ví dụ triển khai chi tiết
Dưới đây là mã nguồn minh họa cách tích hợp giải pháp này vào cấu trúc một trang quản lý thông tin đơn giản:
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<title>Quản lý nhân viên</title>
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdn.staticfile.org/bootstrap-table/1.9.0/bootstrap-table.min.css">
</head>
<body>
<div class="container" style="margin-top: 20px;">
<button class="btn btn-primary" id="btnOpenModal">Xem danh sách nhân viên</button>
</div>
<!-- Bootstrap Modal -->
<div class="modal fade" id="dataModal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span>×</span></button>
<h4 class="modal-title">Dữ liệu hệ thống</h4>
</div>
<div class="modal-body">
<table id="employeeTable"></table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Đóng</button>
</div>
</div>
</div>
</div>
<script src="https://cdn.staticfile.org/jquery/2.1.0/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdn.staticfile.org/bootstrap-table/1.9.0/bootstrap-table.min.js"></script>
<script>
$(function() {
$('#btnOpenModal').click(function() {
$('#dataModal').modal('show');
renderEmployeeTable();
});
});
function renderEmployeeTable() {
const $table = $('#employeeTable');
// Hủy bảng cũ trước khi khởi tạo mới để tránh xung đột dữ liệu
$table.bootstrapTable('destroy');
$table.bootstrapTable({
url: '/api/get-employees', // Thay thế bằng endpoint thực tế của bạn
method: 'get',
height: 450,
pagination: true,
pageSize: 10,
sidePagination: 'server',
columns: [
{ field: 'id', title: 'ID', width: '10%' },
{ field: 'full_name', title: 'Họ và Tên', width: '40%' },
{ field: 'department', title: 'Phòng ban', width: '30%' },
{
field: 'status',
title: 'Trạng thái',
formatter: function(value) {
return value === 1 ? '<span class="label label-success">Đang làm việc</span>' : '<span class="label label-default">Nghỉ việc</span>';
}
}
],
onPostBody: function () {
// Xử lý lỗi hụt layout khi render trong modal
console.log('Fixing table layout...');
$('.fixed-table-container').css('padding-bottom', '37px');
}
});
}
</script>
</body>
</html>
Bằng cách sử dụng onPostBody, chúng ta ép trình duyệt phải áp dụng đúng thuộc tính CSS ngay sau khi cấu trúc bảng được hình thành. Điều này giúp loại bỏ hoàn toàn hiện tượng các dòng dữ liệu bị tràn ra ngoài biên của bảng hoặc phần chân trang (footer) đè lên dữ liệu khi sử dụng trong môi trường Modal linh hoạt.