<Cthuvien:ma ktra> / <Cthuvien:DR_lke> - <BSSLke>
Mô tả
BSSLke là component React tra cứu dạng ComboBox/AutoComplete, thay thế cho:
- Chức năng
ktra(tra cứu gợi ý khi gõ) của control cũ<Cthuvien:ma>. - Control
<Cthuvien:DR_lke>(ComboBox tra cứu động từ CSDL quaham_list, hỗ trợ popup form tham khảof_tkhao). - Chức năng tra cứu của
<Cthuvien:nhom>.
Đây là component phức tạp nhất trong bộ BSS Controls. Điểm nổi bật:
- Tra cứu API tự động (AutoComplete): Khi người dùng gõ ký tự vào ô, component tự động gọi API (thông qua
ktrahoặclke) để lấy danh sách gợi ý từ cơ sở dữ liệu, hiển thị kết quả trong popup bảng dữ liệu. - Danh sách tĩnh (Local Options): Hỗ trợ truyền mảng
optionscố định thay vì gọi API, phù hợp cho các danh sách ngắn không cần tra cứu DB. - Phân trang trong Popup: Khi có nhiều kết quả, popup tự chia trang (số dòng mỗi trang lấy từ
suggestionLimittronguseAppStore). Hỗ trợ thanh kéo slider kéo trang bằng chuột hoặc phím tắt←→. - Hiển thị Mã hoặc Tên: Thuộc tính
hienMaTenquyết định ô input sẽ hiển thị mã hay tên của bản ghi đã chọn. Dù hiển thị cách nào, giá trị gửi raonChangeluôn là mã. - Chống giật Grid (Local State): Giá trị gõ vào chỉ cập nhật giao diện nội bộ. Khi
onBlur,Tab, hoặcEnter, component mới commit giá trị ra ngoài. - Auto-resolve tên: Khi nhận
valuelà mã từ props (VD:"NV001"), component tự động gọi API để tra ngược lấy tên tương ứng hiển thị trên ô (VD: "Nguyễn Văn A").
Thuộc tính
So sánh thuộc tính cũ và mới
Bảng dưới đây tổng hợp các thuộc tính từ cả <Cthuvien:ma> (phần ktra) và <Cthuvien:DR_lke>:
| Control Cũ | <BSSLke> | Kiểu | Mô tả / Chú ý khi chuyển đổi |
|---|---|---|---|
ten | label | string | Nhãn hiển thị (tự động dịch đa ngôn ngữ). |
ktra / ham_list | ktra | string / function | Cũ: Chuỗi ktra="bảng,mã,tên". Mới: Giữ nguyên chuỗi hoặc truyền hàm SuggestFetcher tùy chỉnh. |
tc | tc | string | Tính chất tra cứu ('A' = Tất cả, mặc định). |
nhap | readOnly | bool | Cũ: nhap="K". Mới: readOnly={true}. |
f_tkhao | (Không còn) | Cũ: Mở form popup riêng bằng F1. Mới: Popup suggest tích hợp sẵn trong component, không cần mở form khác. | |
traKieu | hienMaTen | bool | Cũ (DR_lke): traKieu="T" trả mã|tên. Mới: hienMaTen={true} hiển thị mã, false hiển thị tên. Giá trị gửi ra onChange luôn là mã. |
traAn | (Tự động) | Cũ: Giá trị ẩn lưu mã. Mới: Component tự quản lý mã nội bộ (selectedSuggestMa), không cần khai báo. | |
gtriDau | value (khởi tạo) | any | Cũ (DR_lke): gtriDau="P01{Phòng Kỹ thuật". Mới: Truyền value="P01|Phòng Kỹ thuật" (pipe phân cách), component tự tách và hiển thị. |
xep | (Không còn) | Việc sắp xếp kết quả giờ được xử lý bởi API server hoặc trong hàm SuggestFetcher tùy chỉnh. | |
luu | (Không còn) | Lưu vết truy vấn bàn phím không áp dụng trong kiến trúc React mới. | |
rong / rongB | (Tự động) | Popup tự động tính toán chiều rộng dựa trên vị trí ô input và viewport. | |
kt_xoa | (Không còn) | Logic xóa quản lý ở lớp dữ liệu store/form. |
Các thuộc tính của <BSSLke>
| Tên | Kiểu | Mặc định | Có thể có | Mục đích |
|---|---|---|---|---|
id | string | useId() | Định danh của control. Render ra HTML với prefix BSS_. | |
name | string | sinh tự động | Tên trường dữ liệu dùng làm key trong form và validation. | |
label | string | Nhãn hiển thị bên trái ô nhập (tự động dịch đa ngôn ngữ). | ||
labelWidth | number / string | var(--bss-label-width) | 100, '120px' | Độ rộng của nhãn label. |
ktra | string / function | 'bảng,mã,tên' | Cấu hình tra cứu. Chuỗi: tên bảng, trường mã, trường tên (phẩy phân cách). Function: hàm SuggestFetcher tùy chỉnh gọi API riêng. | |
lke | string / function | Tương tự ktra, dùng khi muốn đặt tên khác. ktra ưu tiên nếu cả hai cùng truyền. | ||
options | Array | [] | [{ value, label }] | Danh sách tĩnh (local) thay vì gọi API. Hỗ trợ key: value/ma/MA và label/ten/TEN. |
tc | string | 'A' | 'C', 'T', 'A' | Tính chất danh sách tra cứu truyền vào API. |
value | any | string, 'mã|tên' | Giá trị binding. Nếu truyền dạng 'mã|tên' (pipe phân cách), component tự tách hiển thị và commit chỉ phần mã. | |
hienMaTen | bool | false | true / false | true: Ô input hiển thị mã. false (mặc định): Ô input hiển thị tên/label, tooltip hiện mã khi hover. |
required | bool | false | true / false | Đánh dấu bắt buộc nhập (hiện sao đỏ). |
maxLength | number | Giới hạn ký tự nhập. Hiển thị bộ đếm lùi ở góc khi hover. | ||
error | string | Nội dung lỗi (hoặc tự lấy từ context useValidation). | ||
className | string | '' | Class CSS bổ sung cho wrapper. | |
onChange | function | (e) => void | Sự kiện chính. Trả ra { target: { name, value } } — value luôn là mã (không phải tên). | |
onSuggestSelect | function | ({ name, value, row }) => void | Sự kiện khi chọn dòng từ popup. Trả về toàn bộ dòng dữ liệu (row) để xử lý thêm (VD: fill tên vào ô khác). |
Hoạt động phía Client
Luồng tra cứu
- Người dùng gõ ký tự vào ô → Component cập nhật
displayValue(local state) và gọi API/filter danh sách tĩnh. - Popup hiện ra hiển thị bảng dữ liệu. Nếu kết quả chỉ có đúng 1 dòng khớp hoàn toàn với từ khóa (so sánh mã hoặc tên, case-insensitive), component tự động chọn dòng đó mà không cần người dùng click.
- Người dùng click vào dòng hoặc dùng phím
↓/↑rồi bấmEnter→ Component commit mã của dòng đó quaonChangevà gọionSuggestSelecttrả về toàn bộ row data.
Auto-resolve tên
Khi value thay đổi từ bên ngoài (VD: load dữ liệu từ DB), nếu hienMaTen=false, component cần hiển thị tên thay vì mã. Nó sẽ tự gọi API tra cứu ngược (resolveRemoteDisplayText) để tìm dòng tương ứng và gán tên vào ô hiển thị.
Phím tắt
| Phím | Chức năng |
|---|---|
↓ | Mở popup (nếu chưa mở) / Di chuyển xuống dòng dưới |
↑ | Di chuyển lên dòng trên |
← | Chuyển về trang trước (khi popup đang mở) |
→ | Chuyển sang trang sau (khi popup đang mở) |
Enter | Chọn dòng đang active / Commit giá trị và nhảy ô |
Space | Mở popup và tìm kiếm với giá trị hiện tại |
Esc | Đóng popup |
Tab | Commit giá trị và nhảy ô (mặc định browser) |
Thanh kéo trang (Slider)
Khi có nhiều trang, popup hiện thanh slider ở footer. Người dùng có thể:
- Click vào vị trí trên track → Nhảy đến trang tương ứng.
- Kéo (drag) thumb → Preview số trang (tooltip hiện số) và nhả chuột sẽ load trang đó.
- Hover lên track → Hiện tooltip page number.
Ví dụ
1. Tra cứu nhân viên (gọi API, hiển thị tên):
<BSSLke
label="Nhân viên"
name="ma_nv"
labelWidth={120}
required={true}
ktra="ns_nhanvien,ma,ten" // Bảng ns_nhanvien, cột mã, cột tên
value={data.ma_nv} // Lưu mã "NV001", hiển thị "Nguyễn Văn A"
onChange={handleChange}
onSuggestSelect={({ row }) => {
// row chứa toàn bộ dòng data từ API
setValue(prev => ({ ...prev, ten_nv: row.ten }));
}}
/>
2. Tra cứu hiển thị mã (thay vì tên):
<BSSLke
label="Tài khoản"
name="ma_tk"
ktra="kt_taikhoan,ma,ten"
hienMaTen={true} // Ô input hiện mã "1111", tooltip hiện "Tiền mặt"
value={data.ma_tk}
onChange={handleChange}
/>
3. Danh sách tĩnh (không gọi API):
<BSSLke
label="Loại hợp đồng"
name="loai_hd"
options={[
{ value: 'LD', label: 'Lao động' },
{ value: 'TV', label: 'Tư vấn' },
{ value: 'TT', label: 'Thời vụ' }
]}
value={data.loai_hd}
onChange={handleChange}
/>
4. Sử dụng trong lưới GridX (Không có label):
<BSSLke
ktra="dm_donvi,ma,ten"
value={row.ma_dv}
onChange={(e) => updateRowField(row.id, 'ma_dv', e.target.value)}
onSuggestSelect={({ row: r }) => updateRowField(row.id, 'ten_dv', r.ten)}
className="w-full"
/>