Core Docs

SearchEntry

Picker entity với type-ahead search — dùng cho dimension table lớn (Customer, Product…). Bind foreign key (int).

Source: Core/Components/SearchEntry.cs ComponentType trong DB: Dropdown với Precision < 2 (alias chính). Cũng dùng được SearchEntry qua reflection. Đặt Precision >= 2 cùng ComponentType = Dropdown → Core pick MultipleSearchEntry thay thế.

Cấu hình

ComType:           Dropdown               # alias chính (Precision < 2 → SearchEntry)
FieldName:         CustomerId
Reference:         Customer
DataSourceFilter:  ?$filter=Active eq true     # bắt buộc đủ "?$filter="

Field DB dùng

FieldVai trò
FieldNameProperty entity bind FK (int CustomerId).
ReferenceType entity tham chiếu (vd Customer).
RefNameTên entity tham chiếu dạng string.
RefClassClass CSS của hiển thị reference.
DataSourceFilterOData filter đủ ?$filter=..., có thể có placeholder {<Field>} cho cascade.
TemplateTemplate hiển thị suggestion ("{Code} - {Name}").
FormatDataFormat trong dropdown.
FormatEntityFormat hiển thị entity đã chọn (sau khi pick).
EditableFalse → render disabled (read-only).
EventsJSON map event → method C# (Change, AfterCreated, AfterRender).
HideGridTrue → ẩn nút mở popup picker (kèm phím mũi tên phải).
LocalDataInline JSON list data → bypass API call (test / fixed list).
LocalHeaderCấu hình cột cho popup picker grid (local).
LocalRenderTrue → render custom local thay vì grid mặc định.
RowSố dòng hiển thị popup picker (chiều cao).
PrecisionSố chữ số thập phân (rare cho picker).
PlainTextTrue → render plain.
IsPivotTrue → render dạng pivot.
GroupByField group by trong popup picker.
DefaultValGiá trị mặc định khi tạo record mới.
TopEmptyTrue → thêm option “Trống” ở đầu list.
ComponentGroupReference tới ComponentGroup chứa picker.
ComponentTypeSub-type (rare).

Events kích hoạt

EventMethod signatureKhi nào
change(entity, matched, oldMatch, parent)User chọn 1 entity từ dropdown.
AfterCreated(entity)Sau khi widget mount xong.
AfterRender(entity)Sau khi render giá trị lên DOM.

matched là entity tham chiếu vừa chọn (vd 1 Customer object), oldMatch cái cũ.

public void OnCustomerChanged(object entity, object matched, object oldMatch, object parent)
{
    var invoice  = (Invoice)entity;
    var customer = matched as Customer;
    if (customer != null)
    {
        invoice.CountryId = customer.CountryId;   // auto-fill
        this.FindComponentByName<SearchEntry>("Country")?.UpdateView();
    }
}

Behavior

  • Khi user gõ → query Client.GetRawList<Customer> với filter ghép DataSourceFilter + text user nhập trên các cột tìm kiếm cấu hình metadata.
  • Lưu id (int) vào entity.<FieldName>.
  • Cache result gần đây.
  • Phím mũi tên phải mở popup picker (1 GridView của entity tham chiếu) — hữu ích khi cần filter nhiều cột.

Cấu hình cột cho popup picker (GridPolicy)

Khi user mở popup picker (phím mũi tên phải), Core render 1 GridView của entity tham chiếu (vd Customer). Cột của grid này lấy từ bảng GridPolicy theo rule:

Điều kiện row GridPolicyKhi nào áp dụng
FeatureId IS NULLDefault cho entity — áp cho mọi SearchEntry tham chiếu entity này.
ComponentId = <Id picker>Custom riêng cho row picker này — override default cho 1 picker cụ thể.

Field tham chiếu entity là EntityId (FK của bảng GridPolicy trỏ vào Entity của entity tham chiếu — vd Customer).

Workflow:

  1. Mặc định: tạo các row GridPolicy với FeatureId = NULL, ComponentId = NULL, EntityId = <Id của entity> (vd Customer). Mọi SearchEntry tham chiếu Customer đều dùng các cột này.

  2. Custom cho 1 picker cụ thể: nếu picker A cần thêm/bớt cột so với default, tạo các row GridPolicy riêng với ComponentId = <Id của row Component picker A>. Core merge 2 nguồn theo logic ưu tiên ComponentId > FeatureId IS NULL.

Ví dụ SQL:

-- Default cho Customer (mọi picker tham chiếu Customer đều thấy 3 cột này)
INSERT INTO GridPolicy (FeatureId, ComponentId, EntityId, FieldName, ShortDesc, Width, [Order]) VALUES
  (NULL, NULL, /*Customer Id*/ 12, 'Code',  N'Mã',  '120', 10),
  (NULL, NULL, 12,                'Name',  N'Tên', '240', 20),
  (NULL, NULL, 12,                'Phone', N'SĐT', '140', 30);

-- Custom thêm cột "Email" cho riêng picker A (Component Id = 999)
INSERT INTO GridPolicy (FeatureId, ComponentId, EntityId, FieldName, ShortDesc, Width, [Order]) VALUES
  (NULL, 999, 12, 'Email', 'Email', '200', 25);

⚠ Đừng set FeatureId = <Id feature đang edit> cho default GridPolicy của entity tham chiếu — đó là feature chứa picker, không phải entity tham chiếu. Quy tắc đúng: FeatureId IS NULL cho default toàn cục.

Picker cascade (filter theo entity hiện tại)

Dùng placeholder {<FieldName>} (curly braces) — runtime substitute giá trị từ entity:

DataSourceFilter: ?$filter=CustomerId eq {CustomerId}

→ Khi entity.CustomerId = 7, query thực tế ?$filter=CustomerId eq 7.

Hỗ trợ dotted path:

DataSourceFilter: ?$filter=CountryId eq {Customer.CountryId}

Tip

  • DataSourceFilter phải đủ ?$filter=.... Sai → không load.
  • Clear field: Esc + Enter hoặc code entry.Value = null.
  • Bind code string thay vì id → dùng SearchEntryString.
  • Multi-select → MultipleSearchEntry.

Core Docs · Astro · Core.API/wwwRoot/docs