mcpField
F
fineui-grid

fineui-grid

github.com/sanshi開発545 回インストール3 日前に更新
リポジトリ

fineui-grid について

fineui-grid は、FineUI の表形式データを表示、選択、編集、処理するための開発スキルです。F.js、Pro、Core の各モードと Java を扱い、スタックごとの設定やデータ処理の違いを説明します。

主な機能

  1. 01列とカスタムレンダリングの設定
  2. 02ローカルまたはサーバーデータの読み込み
  3. 03行選択と選択データの取得
  4. 04ページング、ソート、フィルタリング
  5. 05セル編集とデータのグループ化

活用シーン

  1. 01書式付き列で業務データを表示
  2. 02サーバー側ページングとソートの実装
  3. 03行選択、フィルタリング、編集操作の追加

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/sanshi/fineui-skills --skill fineui-grid

インストール後、Claude Code で/fineui-gridを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
advanced.md
columns.md
data-loading.md
editing.md
filter.md
header.md
paging-toolbar.md
row-features.md
row-group.md
selection.md
sorting.md
summary.md
tree-grid.md

詳細

FineUI Grid(表格)技能

术语:4 部署栈(Core 含 3 种开发模式)

同一个 Grid,不同部署栈/模式写法不同。先确定目标,再动手,不要混用。

部署栈开发模式前台 UI 写法后台/数据模型
F.js—(纯 JavaScript)JS 配置对象 F.create({...})纯前端
ProWebFormsASPX 服务器控件 <f:Grid runat="server">Page_Load/IsPostBack + designer
CoreMVC(经典 MVC)Fluent API Html.F().Grid()...Controller + ViewBag
CoreRazorForms(Core 推荐)TagHelper <f:Grid>(PascalCase)三件套 + Page_Load/IsPostBack
CoreRazorPagesTagHelper <f:Grid>(PascalCase)两件套(无 designer)+ OnGet/OnPost
JavaSpring BootThymeleaf 方言 <f:grid>(kebab-case)两件套(.html + 页面类 .java,无 designer)+ Page_Load/isPostBack()

RazorForms 与 RazorPages 共用 TagHelper 标签语法(<f:Grid>/<f:RenderField> 等标签名、列属性相同),但不是完全相同——数据初始化与事件挂接的推荐写法不同:

  • RazorForms:数据在后台 Page_Load 里 Grid1.DataSource=...; Grid1.DataBind();(<f:Grid> 标签上不写 DataSource);按钮 OnClick="方法名"。
  • RazorPages:数据在标签上内联 DataSource="@Model.GetXxx()";按钮 OnClick="@Url.Handler(\"方法名\")"。

FineUI.Java 是 Core-RazorForms 的「孪生栈」:同样「标签式有状态服务端组件 + Page_Load/isPostBack() + 控件字段 + xxx_Click/事件处理器」,差异只在后台栈——标签/属性全 kebab-case(<f:grid>/<f:render-field data-field=…>),页面类用 Java Bean setter/getter(Grid1.setDataSource(...); Grid1.dataBind();),处理器返回 void(纯 JSON 增量回发,无需 UIHelper.Result())。客户端 F.js 运行时四栈完全相同——F.ui.Grid1.xxx()、渲染函数、notifySelectedRows('Grid1')、监听器 JS 一字不改。详见 fineui-foundation。

何时使用(When to Use)

  • 展示表格数据,配置列(文本/数字/日期/格式化/自定义渲染)
  • 行选择:复选框多选、单选、读取选中行
  • 数据加载:本地内联数据 / 服务端数据 / 服务端分页
  • 单元格编辑、排序、筛选、分组、合计行、工具栏

开始前(Before You Start)—— 先判定"哪个模式"

判定线索:.aspx → Pro(WebForms);Controllers/ + Views/*/Index.cshtml 且用 Html.F()(Fluent API)→ Core-MVC;Pages/*.cshtml 用 <f:Grid> 标签 → Core-RazorForms(有 .designer.cs)或 Core-RazorPages(无 .designer.cs);纯前端 .html → F.js;.html 里 <html xmlns:f="http://fineui.com/java"> + <f:grid> 小写标签、pom.xml/mvnw、页面类 .java 带 @FineUIPage(...) + extends FineUIPageBase → Java(Spring Boot)。

再确认:数据从哪来?(本地内联 / 服务端)要不要编辑?要不要选择?

各写法速览(同一个基础表格)

// ① 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();
)

<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(); }
}

<f:Grid ID="Grid1" IsFluid="true" ShowBorder="true" ShowHeader="true" Title="表格"
        DataIDField="Id" DataTextField="Name" DataSource="@Model.GetDataTable()">
    <Columns>
        <%-- 列标签与④完全一致 --%>
    </Columns>
</f:Grid>

<!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)

表格是最复杂组件,按功能分类拆成 13 个参考文件。按需求只读相关的那几篇,不必全读。

基础(数据 / 列 / 分页 / 选择 / 编辑)

文件何时读
references/columns.md列定义、列类型、格式化(日期/数字)、自定义渲染、固定列
references/data-loading.md内存分页 / 数据库分页、翻页事件回发、RecordCount
references/editing.md单元格编辑、列编辑器、读取编辑数据(各栈 API 差异)
references/selection.md行选择:复选框多选/单选、默认选中、读取与设置选中行
references/paging-toolbar.md分页工具栏、页大小选择器、窄屏简洁分页、全局配置

数据处理(排序 / 合计 / 过滤 / 分组 / 树)

文件何时读
references/sorting.md客户端/服务端排序、多列排序、按别的字段排、自定义排序函数
references/summary.md合计行:客户端/服务端、当前页/全部、浮动、多行
references/filter.md表头过滤:文本/数字/日期/下拉/复选、多条件、行内过滤、服务端过滤处理
references/row-group.md行分组:分组头渲染、展开折叠、组内小计
references/tree-grid.md树表格:父子层级行、复选框级联、图标、分页

布局与交互(表头 / 行功能 / 高级)

文件何时读
references/header.md表头选项(隐藏/菜单/提示/列自定义属性)、多表头、动态创建列
references/row-features.md行扩展列、弹窗列、行命令按钮、行单击/双击/选中事件、行/单元格样式、行高行密度
references/advanced.md列锁定、列/行拖拽排序、单元格合并、大数据表格

概念 → 各記法の属性名対照(主要なオプション一覧)

Core-RazorForms と Core-RazorPages では、同じ TagHelper 属性(下表の「Core-TagHelper」列)を使用します。データの初期化とイベントが異なります(制約 5、6 と selection.md を参照)。Java 列は独立しており、属性名は Core-TagHelper 名を kebab-case に変換したものです(Int/Date などの属性「値」は PascalCase のままです)。

概念F.jsPro (WebForms)Core-MVC (Fluent API)Core-TagHelperJava (Thymeleaf 方言)
コンポーネントtype: 'Grid'<f:Grid runat="server">F.Grid()<f:Grid><f:grid>
幅の自動調整isFluid: trueIsFluid="true".IsFluid(true)IsFluid="true"is-fluid="true"
行 ID フィールドidFieldDataIDField.DataIDField()DataIDFielddata-id-field
列コレクションcolumns: [ ]<Columns>.Columns( )<Columns><f:columns>
行番号列columnType:'rownumberfield'<f:RowNumberField>F.RowNumberField()<f:RowNumberField><f:row-number-field>
データフィールドfieldDataField.DataField()DataFielddata-field
列タイトルtextHeaderText.HeaderText()HeaderTextheader-text
フィールド型fieldTypeFieldType.FieldType(FieldType.X)FieldTypefield-type="Int"
組み込みレンダラー(fieldType+fieldFormat)Renderer+RendererArgument.Renderer(Renderer.X).RendererArgument()Renderer+RendererArgumentrenderer="Date"+renderer-argument
カスタム JS レンダリングrenderer: fnRendererFunction="fn".RendererFunction("fn")RendererFunction="fn"renderer-function="fn"
チェックボックスによる複数選択checkboxSelect: trueEnableCheckBoxSelect="true".EnableCheckBoxSelect(true)EnableCheckBoxSelect="true"enable-check-box-select="true"

関連スキル(関連スキル)

  • fineui-foundation:F.create / PageManager / デプロイスタックとパターンの概要 / RawHtml のセキュリティモデル / 命名規則
  • fineui-form:Grid のセルエディターやフィルターフィールドで使用するフォームフィールド(TextBox / NumberBox / DropDownList など)
  • fineui-window:Grid のポップアップ列で使用する Window コンポーネント
  • fineui-tree:独立した Tree コントロール(Grid の「ツリーテーブル」とは異なります。tree-grid.md を参照)

制約とルール(制約とルール)

  1. 绝不编造 API:不确定的属性去查官网 API(见下方 Official Resources)或 F/doc/ 的 JSDoc,别猜。不同模式属性名不同,尤其别把某模式的名字用到另一模式。
  2. 先定模式、不混用:一个页面只用一种模式的写法。判定见「开始前」。F.js 用 text/field,C# 三模式用 HeaderText/DataField,Java 用 header-text/data-field(全 kebab-case)——不要串;Fluent API(MVC)与 TagHelper(RazorForms/RazorPages)不要混写。
  3. 文本默认 HTML 编码(RawHtml 安全模型):Grid 单元格/列头文本默认转义。要输出可信 HTML:
    • F.js:列 renderer 返回的字符串会作为 HTML 插入(渲染函数内自行保证可信);普通文本属性用 F.rawHtml(...)。
    • C#:给控件文本赋 HTML 用 xxx.TextRawHtml = new RawHtml("...");消息用 ShowNotify(new RawHtml("..."))。绝不手写 Text + TextRaw 两个属性。
    • Java:标签使用 xxx-raw-html(如 header-text-raw-html / text-raw-html),服务端使用 new RawHtml(...) 与对应 setter;消息实例用 notify.setMessageRawHtml(new RawHtml(...)) 后调用 notify.show()。不要以 encode-text="false" 作为新代码的通用逃生口。渲染函数返回值与 F.js 一致(客户端插入)。
  4. Pro 数据绑定固定套路:!IsPostBack 内 Grid1.DataSource = table; Grid1.DataBind();。忘了 !IsPostBack 会在每次回发重复绑定、丢失状态。
  5. Core 三种模式的数据初始化各不相同:
    • MVC(Fluent API):Controller 设 ViewBag.Grid1DataSource,View 里 .DataSource(ViewBag.Grid1DataSource)。
    • RazorForms:后台 Page_Load(!IsPostBack)里 Grid1.DataSource=...; Grid1.DataBind();,<f:Grid> 标签不写 DataSource。
    • RazorPages:标签上内联 DataSource="@Model.GetXxx()"。
    • Java(同 RazorForms 范式):页面类 Page_Load(!isPostBack())里 Grid1.setDataSource(list); Grid1.dataBind();,<f:grid> 标签不写 data-source;控件字段手动在类里声明(com.fineui.java.core.controls.Grid Grid1;,字段名 = 标签 id);事件/命令处理器返回 void(如 public void Grid1_PageIndexChanged(Object sender, GridPageEventArgs e))。
  6. RazorForms vs RazorPages(同为 TagHelper,但后台模型不同):RazorForms 三件套(.cshtml + .cshtml.cs partial + .designer.cs),后台继承项目现有的 RazorForms 页面基类(官方示例为 BaseModel,它本身可继承 PageModel),使用 Page_Load/IsPostBack、OnClick="方法名";同步控件事件返回 void,按钮点击示例为 protected void 方法名(object sender, EventArgs e),分页、排序、行命令等则使用各自的专用 EventArgs,不写 OnPost、不返回 IActionResult、不调用 UIHelper.Result()。RazorPages 两件套(非 partial、无 designer)、OnGet/OnPostXxx、OnClick="@Url.Handler(\"方法名\")",OnPostXxx 返回 IActionResult 和 UIHelper.Result();Java 两件套(.html + .java,无 designer)、Page_Load/isPostBack()、on-click="方法名"、@FineUIPage("area/page") 定路由。
  7. 新代码只使用三栈共有列:普通列用 RenderField,布尔展示列用 RenderCheckField,另有 RowNumberField、GroupField 及 RenderField.Commands。不要根据 FineUI.Pro 的历史示例生成仅 Pro 存在的服务端渲染列。
  8. 行选择统一使用稳定行 ID:初始化、读取与服务端主动选中都先设置 DataIDField / data-id-field,再使用 SelectedRowID / SelectedRowIDArray / getSelectedRowIdArray()。Pro/Core 的 SelectedRowIndex / SelectedRowIndexArray 已废弃,只用于识别和迁移旧代码;Java 已直接删除同名 getter/setter 与模板属性。读取选中行数据时,Pro / Core-RazorForms 调 Grid1.GetSelectedDataKeys(),Java 调 Grid1.getSelectedDataKeys();必须让 DataKeyNames / _DataKeyNames / data-key-names 包含行 ID 字段。数据库分页跨页选择或敏感业务只取稳定行 ID,再查询数据库。详见 references/selection.md。
  9. 三个"分组/层级"概念别混:多表头(列的分组,GroupField,header.md)≠ 行分组(数据行按字段分组,EnableRowGroup,row-group.md)≠ 树表格(行父子层级,EnableTree,tree-grid.md)。用户说"分组"时先确认是哪一种。
  10. F.js 嵌套配置 vs .NET 拍平属性:多个高级功能 F.js 把选项收进一个对象(tree:{...}/rowGroup:{...}/rowExpander:{...}/filter:{...}),而 Pro/Core 拍平成一堆独立属性(EnableTree/TreeColumn/...)。转写时注意这种结构差异。
  11. 行事件 EventArgs 类名按栈不同:同一行事件,Pro 与 RazorForms 的参数类名不一样(如行命令 Pro GridCommandEventArgs / RazorForms GridRowCommandEventArgs)。Java 的类名与 Core 又不完全一致:行命令用 GridCommandEventArgs(同 Pro),行单击/双击用 GridRowEventArgs,行数据绑定用 GridRowDataBoundEventArgs,翻页 GridPageEventArgs、排序 GridSortEventArgs(getter 取值,如 e.getRowIndex()/e.getCommandName())。详见 row-features.md,别照抄错。
  12. 合并/拖拽无服务端属性:单元格合并(mergeCells/mergeColumns)、行拖拽(moveRowUp 等)都是客户端方法;列/行顺序持久化使用 F.customEvent + Page_CustomEvent,结构化参数传 JSON 对象/数组。详见 advanced.md。
  13. 行命令统一用 RenderField.Commands:Pro、Core RazorForms 与 Java 都使用 RenderField.Commands;Command 只属于 RenderField。客户端附加逻辑监听 Grid 的 rowcommand,服务端声明 OnRowCommand。

官方资源(Official Resources)

コメント