<Cthuvien:GridX> - <BSSGrid>
Mô tả
BSSGrid là component UI dạng bảng (Data Grid) của hệ thống, thay thế toàn diện cho <Cthuvien:GridX> cũ (vốn kế thừa từ GridView của ASP.NET).
Trong hệ thống cũ, GridX sử dụng một file JavaScript đồ sộ để can thiệp trực tiếp vào DOM (ẩn/hiện hàng, bắt sự kiện phím, tô màu trạng thái GridX_doiMauH, xử lý trượt trang GridX_nhay). Trong kiến trúc React mới, BSSGrid xử lý tất cả thông qua Local State (useGridLogic) và tuân thủ mô hình Data-Driven, mang lại hiệu năng mượt mà hơn và code dễ bảo trì hơn.
Điểm nổi bật:
- Khai báo Declarative: Hỗ trợ truyền mảng cấu hình
columnshoặc khai báo trực tiếp qua thẻ con<BSSGrid.Column>. - Phân trang đa dạng: Hỗ trợ phân trang ảo (Virtual Slider), Pager truyền thống, Infinite Scroll, hoặc không phân trang (None).
- Nhập liệu & Validation: Tích hợp chặt chẽ với các control BSS khác (
BSSInput,BSSLke,BSSCalendar) trực tiếp bên trong từng ô dữ liệu. - Tự động tính tổng: Tự động tính tổng footer cho các cột số/tiền (
hienTong,totalAmount). - Footer linh hoạt: Hỗ trợ bật/tắt các nút Thêm, Xóa, Chèn, Lọc dễ dàng thông qua props.
Thuộc tính
So sánh cơ chế cũ và mới
| <Cthuvien:GridX> Cũ | <BSSGrid> Mới | Mô tả / Chú ý khi chuyển đổi |
|---|---|---|
loai ("X", "N", "C") | kieu ('V', 'E') | Cũ: Chỉ xem (X), Nhập liệu (N). Mới: 'V' (View - chỉ xem), 'E' (Edit - mặc định, cho phép nhập liệu). |
cot="ma,ten,sl" | <BSSGrid.Column field="..."> | Cũ: Truyền mảng chuỗi tên cột ở thuộc tính cha. Mới: Khai báo qua component con BSSGrid.Column hoặc mảng JSON columns. |
cotRong="ma:80,ten:200" | width={80} (trên Column) | Cũ: Khai báo chuỗi gom chung. Mới: Khai báo width (số px hoặc 'auto') trực tiếp trên cấu hình từng cột. |
cotS, cotN, cotNH | type="number", type="date" | Cũ: Quy định kiểu dữ liệu qua thuộc tính gom chung. Mới: Chỉ định type trên từng cột. BSSGrid tự dùng đúng control (VD: BSSCalendar cho date). |
truot | phanTrang | Cũ: "K" có trượt, "D" tắt trượt. Mới: 'virtual' (trượt ảo, mặc định), 'pager', 'infinite', 'none'. |
hangKt | pageSize | Cũ: Kích thước trang hiển thị. Mới: Số dòng trên 1 trang (mặc định cấu hình lấy từ store). |
hamRow | onRowClick | Sự kiện khi click/chuyển dòng active. |
hamUp | onChangeData | Cũ: Gọi khi ô bị sửa đổi. Mới: Grid trả về toàn bộ mảng dữ liệu mới (newData) mỗi khi có ô thay đổi. |
GridX_datBang(...) | data={...} | Cũ: Gọi hàm JS đẩy data vào DOM. Mới: Đưa mảng state dữ liệu vào prop data. |
| Các hàm thao tác (Thêm, Xóa) | Footer Tích hợp sẵn | BSSGrid tích hợp sẵn các nút và logic cơ bản ở Footer (hienThem, hienXoa, hienChon). Có thể override qua onAddRow, onCut. |
Các thuộc tính chung (Container)
| Tên | Kiểu | Mặc định | Có thể có | Mục đích |
|---|---|---|---|---|
data | Array | [] | Dữ liệu đầu vào (mảng các Object). | |
columns | Array | Mảng cấu hình cột. (Thường dùng cách khai báo thẻ <BSSGrid.Column> tiện hơn). | ||
kieu | string | 'E' | 'E', 'V' | 'E' (Edit): cho phép sửa trên ô (dựa theo cấu hình cột). 'V' (View): chế độ chỉ đọc toàn lưới. |
phanTrang | string | 'virtual' | 'virtual', 'pager', 'infinite', 'none' | Kiểu phân trang. virtual: thanh kéo ảo. |
width | number / string | Chiều rộng tổng của lưới (Ví dụ: 800, '100%'). | ||
pageSize | number | Số dòng hiển thị trên một trang. | ||
loading | bool | false | true/false | Hiển thị Skeleton loading khi đang fetch dữ liệu. |
currency | string | 'VND' | 'VND', 'USD' | Ký hiệu tiền tệ hiển thị cho các cột kiểu tiền. |
Cấu hình Footer / Hành động
| Tên | Kiểu | Mặc định | Mục đích |
|---|---|---|---|
hienChon | bool | true | Hiển thị cột checkbox "Chọn" ở đầu lưới. |
hienThem | bool | true | Bật/tắt nút "Thêm" (+). |
hienXoa | bool | true | Bật/tắt nút "Xóa" (-). |
hienChen | bool | false | Bật/tắt nút "Chèn" (Insert). |
hienTong | bool | false | Bật/tắt nút hiển thị Tổng (Sigma) và tự động tính tổng tiền. |
hienLoc | bool | true | Bật/tắt hàng Filter/Tìm kiếm trên Header. |
footer | ReactNode | Component/Nội dung tùy chỉnh bổ sung dưới cùng lưới (dưới cả phân trang). | |
gridActions | ReactNode | Nút bấm/Component custom nhúng vào vùng actions của thanh Footer. |
Các sự kiện (Events)
| Tên | Trả về | Mục đích |
|---|---|---|
onChangeData | (newData: T[]) | Callback kích hoạt mỗi khi dữ liệu trong lưới thay đổi (nhập liệu, thêm/xóa dòng). Nhận mảng dữ liệu mới. |
onRowClick | (row: T) | Callback khi click chuột trái vào dòng. |
onRowDoubleClick | (row: T) | Callback khi double click chuột trái vào dòng. |
onSelectionChange | (ids: string[]) | Trả về mảng ID (định dạng idx_{index}) của các dòng đang được check. |
onPageChange | (page, tu, den) | Callback khi chuyển trang. Cần thiết khi kết hợp tải dữ liệu từ API. |
onAddRow | () => void | Override hành vi Thêm dòng mặc định. |
onCut | (ids: string[]) | Override hành vi Xóa dòng mặc định. Nhận danh sách các index đang chọn. |
Thành phần Cột <BSSGrid.Column>
BSSGrid cho phép khai báo cột trực quan dưới dạng component con.
| Tên | Kiểu | Bắt buộc | Mặc định | Mục đích |
|---|---|---|---|---|
field | string | Có | Tên field dữ liệu map với Object. Dùng làm id nội bộ. | |
header | string | Có | Tiêu đề hiển thị của cột (Sẽ tự động dịch đa ngôn ngữ). | |
type | string | 'text' | text, number, currency, date, list, lke, checkbox, toggle. Grid sẽ tự động nhúng control BSS tương ứng. | |
width | number/string | 150 | Độ rộng cột. | |
editable | bool | true | Xác định cột này có cho phép sửa hay không (chỉ có tác dụng khi lưới là kieu="E"). | |
align | string | Canh lề chữ: 'left', 'center', 'right'. (Mặc định number/currency sẽ canh phải). | ||
sortable | bool | false | Bật tính năng click vào tiêu đề để sort nội bộ. | |
options | Array | (Dành cho type list / toggle / checkbox) Danh sách tùy chọn [{value, label}]. | ||
ktra | string/func | (Dành cho type lke) Cấu hình tra cứu bảng,mã,tên hoặc hàm fetcher, giống control BSSLke. | ||
onSuggestSelect | function | Callback trả về chi tiết dòng tra cứu khi chọn xong (cho lke). |
Hoạt động phía Client
- Grid Thông minh: Nếu bạn đặt
kieu="V", lưới tự động đặt cờeditable: falsecho toàn bộ các cột, ép lưới về dạng chỉ xem. - Chỉnh sửa Ô (Local State): Khi bạn sửa dữ liệu trên một ô (ví dụ: nhập
BSSInput), thay vì lưới bị giật/lag để render toàn bộ lại, Grid sử dụng kiến trúc local state. Nó tạo một row clone tạm thời, chỉ khi sự kiện blur/enter xảy ra, giá trị mới được commit lên mảng dữ liệu chính, kích hoạtonChangeData. - Thêm/Xóa Hàng (Internal): Nếu không truyền override
onAddRowhayonCut, Grid cung cấp các hàmhandleInternalAdd/handleInternalCutmặc định. Hàm Thêm sẽ tạo ra Object rỗng chứa đúng cấu trúc key của cột. Hàm Xóa sẽ yêu cầu check box chọn hàng rồi xóa.
Ví dụ
1. Lưới chỉ Xem (View mode), có Custom Render:
<BSSGrid
data={dataList}
kieu="V"
phanTrang="pager"
pageSize={15}
hienChon={false}
hienThem={false}
hienXoa={false}
onRowClick={(row) => console.log('Click dòng:', row)}
>
<BSSGrid.Column field="ma_nv" header="Mã NV" width={100} />
<BSSGrid.Column field="ten" header="Họ và tên" width={200} />
<BSSGrid.Column field="ngay_sinh" header="Ngày sinh" type="date" width={120} align="center" />
<BSSGrid.Column field="gioi_tinh" header="Giới tính" type="list" width={100}
options={[{value: 'M', label: 'Nam'}, {value: 'F', label: 'Nữ'}]} />
{/* Custom render trực tiếp nội dung HTML */}
<BSSGrid.Column field="status" header="Trạng thái" width={120} align="center"
render={(val) => (
<span className={val === 'A' ? 'text-green-600' : 'text-red-600'}>
{val === 'A' ? 'Đang làm' : 'Đã nghỉ'}
</span>
)}
/>
</BSSGrid>
2. Lưới Nhập Liệu Nghiệp Vụ (Edit mode):
const handleChangeData = (newData) => {
setFormData(prev => ({ ...prev, chiTiet: newData }));
};
<BSSGrid
data={formData.chiTiet}
kieu="E"
hienTong={true} // Bật tính tổng cho các cột tiền
onChangeData={handleChangeData}
>
{/* Cột mã phụ cấp tra cứu từ danh mục */}
<BSSGrid.Column field="ma_pc" header="Mã Phụ cấp" type="lke" width={120}
ktra="dm_phucap,ma,ten"
onSuggestSelect={({ row, rowIndex }) => {
// Khi chọn mã, tự điền tên vào cột ten_pc trên cùng dòng
const newData = [...formData.chiTiet];
newData[rowIndex].ten_pc = row.ten;
handleChangeData(newData);
}}
/>
<BSSGrid.Column field="ten_pc" header="Tên Phụ cấp" width={250} editable={false} />
<BSSGrid.Column field="so_luong" header="Số lượng" type="number" width={100} />
<BSSGrid.Column field="tien" header="Số tiền" type="currency" width={150} />
<BSSGrid.Column field="ghi_chu" header="Ghi chú" type="text" width={300} />
</BSSGrid>