SuperAPI AI Directory

fineui-grid

Frontend & websites

View repository

Updated 10-16 06:52

About this skill

FineUI Grid skill

Terminology: 4 deployment stacks (Core includes 3 development modes)

The same Grid is written differently across deployment stacks/modes.Determine the target first, then start; do not mix them.

Deployment stack Development mode Front-end UI syntax Backend/data model
F.js — (pure JavaScript) JS configuration object F.create({...}) Pure front-end
Pro WebForms ASPX server control <f:Grid runat="server"> Page_Load/IsPostBack + designer
Core MVC(classic MVC) Fluent API Html.F().Grid()... Controller + ViewBag
Core RazorForms(Core recommended) TagHelper <f:Grid>(PascalCase) Three-piece set + Page_Load/IsPostBack
Core RazorPages TagHelper <f:Grid>(PascalCase) Two-piece set (no designer) + OnGet/OnPost
Java Spring Boot Thymeleaf dialect <f:grid>(kebab-case) Two-piece set (.html + page class .java, no designer) + Page_Load/isPostBack()

RazorForms and RazorPages share TagHelper tag syntax(<f:Grid>/<f:RenderField> and other tag names and column attributes are the same), butthey are not exactly the same——the recommended ways to initialize data and attach events differ:

  • RazorForms: data is in the backend Page_Load in Grid1.DataSource=...; Grid1.DataBind();(<f:Grid> on the tagdo not write DataSource); button OnClick="方法名"。
  • RazorPages: data is on the taginline DataSource="@Model.GetXxx()"; button OnClick="@Url.Handler(\"方法名\")"。

FineUI.Java is the "twin stack" of Core-RazorForms: likewise "tag-based stateful server-side components + Page_Load/isPostBack() + control fields + xxx_Click/event handlers", the differenceis only in the backend stack—tags/attributes are all kebab-case(<f:grid>/<f:render-field data-field=…>), the page class uses Java Bean setters/getters (Grid1.setDataSource(...); Grid1.dataBind();), the handlerreturns void(pure JSON incremental postback, no need for UIHelper.Result())。the client-side F.js runtime is exactly the same across all four stacks——F.ui.Grid1.xxx(), render functions,notifySelectedRows('Grid1'), and listener JS remain unchanged. See fineui-foundation。

When to Use

  • Display tabular data, configure columns (text/number/date/formatting/custom rendering)
  • Row selection: checkbox multi-select, single select, read selected rows
  • Data loading: local inline data / server-side data / server-side paging
  • Cell editing, sorting, filtering, grouping, summary rows, toolbar

Before You Start — first determine "which mode"

Determination clues:.aspx → Pro(WebForms);Controllers/ + Views/*/Index.cshtml and use Html.F()(Fluent API)→ Core-MVC;Pages/*.cshtml use <f:Grid> tag → Core-RazorForms(has .designer.cs) or Core-RazorPages(no .designer.cs); pure front-end .html → F.js;.html in <html xmlns:f="http://fineui.com/java"> + <f:grid> lowercase tags,pom.xml/mvnw, page class .java with @FineUIPage(...) + extends FineUIPageBase → Java(Spring Boot)。

Then confirm:Where does the data come from?(local inline / server-side)Do you need editing? Do you need selection?

Quick overview of each syntax (the same basic table)

// ① F.js
F.create({
    type: 'Grid', isFluid: true, id: 'Grid1', renderTo: '#wrap', title: '表格',
    idField: 'Id', textField: 'Name',
    columns: [
        { columnType: 'rownumberfield' },
        { text: '姓名', field: 'Name' },
        { text: '入学年份', field: 'EntranceYear', fieldType: 'int' },
        { text: '所学专业', field: 'Major', flex: 1, minWidth: 150 }
    ],
    data: [{ Id: 1, Name: '张三', EntranceYear: 2020, Major: '软件工程' }]
});
<%-- ② Pro(WebForms,.aspx)--%>
<f:Grid ID="Grid1" runat="server" IsFluid="true" ShowBorder="true" ShowHeader="true" Title="表格" DataIDField="Id" DataKeyNames="Id">
    <Columns>
        <f:RowNumberField />
        <f:RenderField ColumnID="Name" DataField="Name" HeaderText="姓名" />
        <f:RenderField ColumnID="EntranceYear" DataField="EntranceYear" FieldType="Int" HeaderText="入学年份" />
        <f:RenderField ColumnID="Major" DataField="Major" ExpandUnusedSpace="true" MinWidth="150px" HeaderText="所学专业" />
    </Columns>
</f:Grid>
// ②后台 Grid.aspx.cs
protected void Page_Load(object sender, EventArgs e) {
    if (!IsPostBack) { Grid1.DataSource = GetDataTable(); Grid1.DataBind(); }
}
// ③ Core-MVC(Fluent API,Index.cshtml)
@{ var F = Html.F(); }
@(F.Grid().IsFluid(true).Title("表格").ID("Grid1").DataIDField("Id").DataTextField("Name")
    .Columns(
        F.RowNumberField(),
        F.RenderField().HeaderText("姓名").DataField("Name"),
        F.RenderField().HeaderText("入学年份").DataField("EntranceYear").FieldType(FieldType.Int),
        F.RenderField().HeaderText("所学专业").DataField("Major").ExpandUnusedSpace(true).MinWidth(150)
    )
    .DataSource(ViewBag.Grid1DataSource)   // Controller: ViewBag.Grid1DataSource = GetDataTable();
)
<!-- ④ Core-RazorForms(TagHelper):标签不写 DataSource,数据在后台 Page_Load 绑定 -->
<f:Grid ID="Grid1" IsFluid="true" ShowBorder="true" ShowHeader="true" Title="表格" DataIDField="Id" DataTextField="Name">
    <Columns>
        <f:RowNumberField />
        <f:RenderField HeaderText="姓名" DataField="Name" />
        <f:RenderField HeaderText="入学年份" DataField="EntranceYear" FieldType="Int" />
        <f:RenderField HeaderText="所学专业" DataField="Major" ExpandUnusedSpace="true" MinWidth="150" />
    </Columns>
</f:Grid>
// ④后台 Grid.cshtml.cs(partial,配 designer.cs)
protected void Page_Load(object sender, EventArgs e) {
    if (!IsPostBack) { Grid1.DataSource = GetDataTable(); Grid1.DataBind(); }
}
<!-- ⑤ Core-RazorPages(TagHelper):列同④,但数据在标签上内联绑定 -->
<f:Grid ID="Grid1" IsFluid="true" ShowBorder="true" ShowHeader="true" Title="表格"
        DataIDField="Id" DataTextField="Name" DataSource="@Model.GetDataTable()">
    <Columns>
        <%-- 列标签与④完全一致 --%>
    </Columns>
</f:Grid>
<!-- ⑥ FineUI.Java(Thymeleaf 方言):标签/属性全 kebab-case;列同④结构,数据在页面类 Page_Load 绑定 -->
<!DOCTYPE html>
<html xmlns:f="http://fineui.com/java" layout:decorate="~{shared/layout}">
<head><title>FineUI.Java · 基础表格</title></head>
<body>
  <th:block layout:fragment="body">
    <f:grid id="Grid1" is-fluid="true" show-border="true" show-header="true" title="表格" data-id-field="Id" data-text-field="Name">
      <f:columns>
        <f:row-number-field></f:row-number-field>
        <f:render-field header-text="姓名" data-field="Name"></f:render-field>
        <f:render-field header-text="入学年份" data-field="EntranceYear" field-type="Int"></f:render-field>
        <f:render-field header-text="所学专业" data-field="Major" expand-unused-space="true" min-width="150"></f:render-field>
      </f:columns>
    </f:grid>
  </th:block>
  <th:block layout:fragment="script"><script src="/res/js/grid.js"></script></th:block>
</body>
</html>
// ⑥后台 Grid.java(页面类,无 designer;字段名 = 标签 id)
@FineUIPage("grid/grid")
public class Grid extends FineUIPageBase {
    com.fineui.java.core.controls.Grid Grid1;   // 全限定名避免与本页类名 Grid 冲突;或 import 后写 Grid Grid1;
    public void Page_Load(Object sender, EventArgs e) {
        if (!isPostBack()) { Grid1.setDataSource(getDataList()); Grid1.dataBind(); }
    }
}

Documentation Reference Files

The table is the most complex component, split into 13 reference files by functional category.Read only the relevant articles as needed, no need to read everything.

Basics (data / columns / pagination / selection / editing)

File When to read
references/columns.md Column definitions, column types, formatting (date/number), custom rendering, fixed columns
references/data-loading.md In-memory pagination / database pagination, page-change event postback, RecordCount
references/editing.md Cell editing, column editors, reading edited data (API differences across stacks)
references/selection.md Row selection: checkbox multi-select/single-select, default selected, read and set selected rows
references/paging-toolbar.md Pagination toolbar, page size selector, compact pagination for narrow screens, global configuration

Data processing (sorting / totals / filtering / grouping / tree)

File When to read
references/sorting.md Client/server sorting, multi-column sorting, sorting by another field, custom sort function
references/summary.md Total row: client/server, current page/all, floating, multiple rows
references/filter.md Header filtering: text/number/date/dropdown/checkbox, multiple conditions, inline filtering, server-side filtering handling
references/row-group.md Row grouping: group header rendering, expand/collapse, subtotals within a group
references/tree-grid.md Tree grid: parent-child hierarchical rows, checkbox cascade, icons, pagination

Layout and interaction (headers / row features / advanced)

File When to read
references/header.md Header options (hide/menu/tooltip/custom column attributes),multiple headers, dynamically create columns
references/row-features.md Row expand column, modal column, row command buttons, row click/double-click/selection events, row/cell styles, row height and density
references/advanced.md Column locking, column/row drag-and-drop sorting, cell merging, large data grids

Concepts → property name cross-reference for each syntax (Key Options at a Glance)

Core-RazorForms and Core-RazorPages share the same set of TagHelper properties (the "Core-TagHelper" column in the table below); the differences are in data initialization/events (see Constraints 5, 6 and selection.md).Java columns are listed separately, property names = Core-TagHelper names converted to kebab-case(property "values" such as Int/Date still remain PascalCase).

Concept F.js Pro (WebForms) Core-MVC (Fluent API) Core-TagHelper Java (Thymeleaf dialect)
Component type: 'Grid' <f:Grid runat="server"> F.Grid() <f:Grid> <f:grid>
Adaptive width isFluid: true IsFluid="true" .IsFluid(true) IsFluid="true" is-fluid="true"
Row ID field idField DataIDField .DataIDField() DataIDField data-id-field
Column collection columns: [ ] <Columns> .Columns( ) <Columns> <f:columns>
Row number column columnType:'rownumberfield' <f:RowNumberField> F.RowNumberField() <f:RowNumberField> <f:row-number-field>
Data field field DataField .DataField() DataField data-field
Column title text HeaderText .HeaderText() HeaderText header-text
Field type fieldType FieldType .FieldType(FieldType.X) FieldType field-type="Int"
Built-in renderer (fieldType+fieldFormat) Renderer+RendererArgument .Renderer(Renderer.X).RendererArgument() Renderer+RendererArgument renderer="Date"+renderer-argument
Custom JS rendering renderer: fn RendererFunction="fn" .RendererFunction("fn") RendererFunction="fn" renderer-function="fn"
Checkbox multi-select checkboxSelect: true EnableCheckBoxSelect="true" .EnableCheckBoxSelect(true) EnableCheckBoxSelect="true" enable-check-box-select="true"

Related Skills

  • fineui-foundation:F.create / PageManager / deployment stack and mode overview / RawHtml security model / naming conventions
  • fineui-form: form fields used by Grid cell editors and filter fields (TextBox / NumberBox / DropDownList, etc.)
  • fineui-window: Window component used by Grid modal columns
  • fineui-tree: standalone Tree control (different from the Grid's "tree grid", see tree-grid.md)

Constraints & Rules

  1. Never make up APIs: for properties you are unsure about, check the official website API (see Official Resources below) or F/doc/ JSDoc, don't guess. Property names differ between modes; in particular, don't use one mode's names in another mode.
  2. Decide on a mode first, don't mix them: A single page uses only one mode's syntax. For how to decide, see "Before you start". F.js uses text/field, the three C# modes use HeaderText/DataField,Java uses header-text/data-field(all kebab-case)—don't mix them up; don't mix Fluent API (MVC) with TagHelper (RazorForms/RazorPages).
  3. Text is HTML-encoded by default (RawHtml safety model): Grid cell/column header text is escaped by default. To output trusted HTML:
    • F.js: column renderer the returned string is inserted as HTML (the render function itself must guarantee it is trusted); for plain text properties use F.rawHtml(...)。
    • C#: to assign HTML to control text use xxx.TextRawHtml = new RawHtml("..."); for messages use ShowNotify(new RawHtml("..."))。never hand-write the two Text + TextRaw properties。
    • Java: Labels use xxx-raw-html(e.g. header-text-raw-html / text-raw-html), the server side uses new RawHtml(...) and the corresponding setter; for message instances use notify.setMessageRawHtml(new RawHtml(...)) then call notify.show(). Don't use encode-text="false" as a general escape hatch for new code. Render function return values are the same as F.js (client-side insertion).
  4. Fixed Pro data binding pattern:!IsPostBack inside Grid1.DataSource = table; Grid1.DataBind();. Forgetting !IsPostBack will rebind on every postback and lose state.
  5. The three Core modes each initialize data differently:
    • MVC(Fluent API): Controller sets ViewBag.Grid1DataSource, in the View .DataSource(ViewBag.Grid1DataSource)。
    • RazorForms: backend Page_Load(!IsPostBack) inside Grid1.DataSource=...; Grid1.DataBind();,<f:Grid> tagdo not write DataSource。
    • RazorPages: inline on the tag DataSource="@Model.GetXxx()"。
    • Java (same paradigm as RazorForms): page class Page_Load(!isPostBack()) inside Grid1.setDataSource(list); Grid1.dataBind();,<f:grid> tagdo not write data-source; control fieldsdeclare manually in the class(com.fineui.java.core.controls.Grid Grid1;, field name = tag id); event/command handlersreturn void(e.g. public void Grid1_PageIndexChanged(Object sender, GridPageEventArgs e))。
  6. RazorForms vs RazorPages (both are TagHelper, but the backend models differ): RazorForms trio (.cshtml + .cshtml.cs partial + .designer.cs), the backend inherits the project's existing RazorForms page base class (the official example is BaseModel, which itself can inherit PageModel), uses Page_Load/IsPostBack、OnClick="方法名"; synchronous control events return void, a button click example is protected void 方法名(object sender, EventArgs e), while paging, sorting, row commands, etc. use their own dedicated EventArgs,do not write OnPost, do not return IActionResult, do not call UIHelper.Result(). RazorPages pair (not partial、none designer)、OnGet/OnPostXxx、OnClick="@Url.Handler(\"方法名\")",OnPostXxx returns IActionResult and UIHelper.Result();Java pair (.html + .java, no designer),Page_Load/isPostBack()、on-click="方法名"、@FineUIPage("area/page") define routes.
  7. New code uses only columns common to all three stacks: for plain columns use RenderField, for boolean display columns use RenderCheckField, plus RowNumberField、GroupField and RenderField.Commands. Do not generate server-rendered columns that exist only in Pro based on historical FineUI.Pro examples.
  8. Row selection uniformly uses a stable row ID: initialization, reading, and server-side active selection all first set DataIDField / data-id-field, then use SelectedRowID / SelectedRowIDArray / getSelectedRowIdArray(). Pro/Core's SelectedRowIndex / SelectedRowIndexArray is deprecated and is only used to identify and migrate old code; Java has directly removed the getter/setter and template property of the same name. When reading selected row data, Pro / Core-RazorForms call Grid1.GetSelectedDataKeys(), Java calls Grid1.getSelectedDataKeys(); you must make DataKeyNames / _DataKeyNames / data-key-names include the row ID field. For database pagination cross-page selection or sensitive business, only take the stable row ID, then query the database. See references/selection.md。
  9. Don't confuse the three "grouping/hierarchy" concepts:Multi-header(grouping of columns,GroupField,header.md)≠ row grouping(data rows grouped by field,EnableRowGroup,row-group.md)≠ tree table(row parent-child hierarchy,EnableTree,tree-grid.md). When the user says "grouping", first confirm which one it is.
  10. F.js nested configuration vs .NET flattened properties: several advanced features in F.js put options into one object (tree:{...}/rowGroup:{...}/rowExpander:{...}/filter:{...}), while Pro/Core flattens them into a bunch of independent properties (EnableTree/TreeColumn/...). Pay attention to this structural difference when transcribing.
  11. Row event EventArgs class names differ by stack: for the same row event, the parameter class names of Pro and RazorForms are different (e.g., row command Pro GridCommandEventArgs / RazorForms GridRowCommandEventArgs)。Java's class names are also not completely consistent with Core: row command uses GridCommandEventArgs(same as Pro), row single-click/double-click uses GridRowEventArgs, row data binding uses GridRowDataBoundEventArgs, paging GridPageEventArgs, sorting GridSortEventArgs(getter retrieves the value, e.g., e.getRowIndex()/e.getCommandName()). See row-features.md, don't copy it wrong.
  12. Merge/drag have no server-side properties: cell merging (mergeCells/mergeColumns), row dragging (moveRowUp , etc.) are all client-side methods; column/row order persistence uses F.customEvent + Page_CustomEvent, with structured parameters passed as JSON objects/arrays. See advanced.md。
  13. Row commands uniformly use RenderField.Commands: Pro, Core RazorForms, and Java all use RenderField.Commands;Command belongs only to RenderField. Client-side additional logic listens to the Grid's rowcommand, server-side declares OnRowCommand。

Official Resources