ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Handsontable Autocomplete Cell Type 完全指南:从三种编辑模式到 source/filter/sortByRelevance 全配置解析

2026/9/20 18:10:43 拓冰建站 浏览量
Handsontable Autocomplete Cell Type 完全指南:从三种编辑模式到 source/filter/sortByRelevance 全配置解析 前端UI组件【免费下载链接】handsontableJavaScript Data Grid / Data Table with a Spreadsheet Look Feel. Works with React, Angular, and Vue. Supported by the Handsontable team ⚡项目地址https://gitcode.com/gh_mirrors/ha/handsontable点击查看免费下载Autocomplete自动补全是 Handsontable 内置的单元格类型之一它把一个带建议列表的文本输入框嵌入单元格让用户既可以从预定义列表中挑选也可以自由键入自定义值。本文基于官方文档 autocomplete-cell-type.md 并结合仓库源码系统讲解它的三种编辑模式、source的两种数据格式、以及visibleRows、trimDropdown、filter、filteringCaseSensitive、sortByRelevance、allowHtml、allowInvalid等全部相关配置项。读完后你将能够为任意一列配置带下拉建议的输入单元格并正确处理键值对数据、异步数据源与输入校验。概述Autocomplete 单元格类型是什么Autocomplete cell type 的核心价值在于可选也可填下拉列表提供建议suggestions但用户不被建议列表束缚仍可键入列表外的自定义内容。它适用于用户应从已知值中选择但也可以自由输入的典型业务场景例如颜色、品牌、状态标签、机场名称等枚举数据的录入。从源码看该 cell type 在 autocompleteType.ts 中被注册为四个部件的组合export const AutocompleteCellType { CELL_TYPE, // autocomplete editor: AutocompleteEditor, // 编辑时的下拉输入框继承自 HandsontableEditor renderer: autocompleteRenderer, validator: autocompleteValidator, valueGetter, valueSetter, parsePastedValue: true, };也就是说一个 autocomplete 单元格由编辑器下拉 输入框、渲染器、校验器、取值/赋值器四部分协作完成这与 Dropdown cell type只允许选择、不允许自由输入和 Select cell type原生select下拉形成互补。三种编辑模式Autocomplete 单元格可以以三种方式编辑灵活模式Flexible mode默认用户可以边输入边从建议中选择也可以输入一个不在建议列表中的自定义值严格模式Strict mode单元格只接受source列表中定义的值严格模式 异步数据Strict mode with asynchronous data建议列表由source函数从远端如服务器 API异步加载。在全部三种模式下source选项都支持两种格式值数组Array of values含key和value属性的对象数组Array of objects。关于校验Validation所有三种模式下校验只在值被写入单元格时执行即用户编辑并确认后。网格加载时数据源中已存在的值不会被自动校验。如需对已有数据做检查并打上无效标记应在网格创建完成后手动调用validateCells()Core 方法。Autocomplete 灵活模式Flexible Mode灵活模式是默认行为。下面的示例配置了一个四列网格第一列Car是 autocompletestrict: false第三列Chassis color和第四列Bumper color分别演示两个关键的下拉外观选项。import Handsontable from handsontable/base; import { registerAllModules } from handsontable/registry; // 注册 Handsontable 全部模块生产环境可按需按模块引入 registerAllModules(); const colors [ yellow, red, orange and another color, green, blue, gray, black, white, purple, lime, olive, cyan, ]; const container document.querySelector(#example1); new Handsontable(container, { height: auto, licenseKey: non-commercial-and-evaluation, data: [ [BMW, 2017, black, black], [Nissan, 2018, blue, blue], [Chrysler, 2019, yellow, black], [Volvo, 2020, white, gray], ], colHeaders: [Car, Year, Chassis color, Bumper color], columns: [ { type: autocomplete, source: [BMW, Chrysler, Nissan, Suzuki, Toyota, Volvo], strict: false, // 灵活模式允许输入列表外的自定义值 }, { type: numeric }, { type: autocomplete, source: colors, strict: false, visibleRows: 4, // 下拉一次最多显示 4 条其余滚动查看 }, { type: autocomplete, source: colors, strict: false, trimDropdown: false, // 下拉宽度随最宽建议自适应不被单元格宽度截断 }, ], autoWrapRow: true, autoWrapCol: true, });visibleRows控制下拉建议的可见行数visibleRows决定下拉列表不滚动时显示的建议条数默认值为10。示例中Chassis color列设置visibleRows: 4于是下拉只显示四条建议其余建议通过滚动条查看。当source列表很短时少于visibleRows下拉会按实际条数收缩。trimDropdown控制下拉宽度trimDropdown控制下拉的宽度行为默认值为true此时下拉宽度与正在编辑的单元格宽度一致——这可能导致长建议文本被截断如示例中orange and another color。Bumper color列设置trimDropdown: false下拉会扩展以容纳最宽的建议它可以比单元格宽但永远不会比单元格窄。Autocomplete 严格模式Strict Mode严格模式下autocomplete 单元格只接受source中定义的值。其鼠标与键盘绑定与 handsontable cell typeHOT-in-HOT即嵌套表格编辑器完全相同但有以下两处差异只要至少有一个选项可见HOT-in-HOT 中就始终存在一个选中项不会出现无选中状态当第一行被选中时按Arrow Up上箭头不会取消选中HOT-in-HOT而是等同于Enter键——确认当前选中项并把主网格的选择上移一行。allowInvalid严格模式下如何对待手动输入在严格模式下allowInvalid决定用户手动输入非source值时的行为allowInvalid: true可选默认值即 true允许手动输入source中不存在的值该单元格背景会高亮为红色编辑确认后选择自动前进到下一个单元格allowInvalid: false不允许手动输入source中不存在的值此时Enter键被忽略编辑器保持打开等待用户修正输入。const cars [BMW, Chrysler, Nissan, Suzuki, Toyota, Volvo]; new Handsontable(container, { height: auto, licenseKey: non-commercial-and-evaluation, data: [ [BMW, 2017, black, black], [Nissan, 2018, blue, blue], [Chrysler, 2019, yellow, black], [Volvo, 2020, white, gray], ], colHeaders: [Car, Year, Chassis color, Bumper color], columns: [ { type: autocomplete, source: cars, strict: true, // allowInvalid: true // true 是默认值允许输入列表外的值并标记为无效 }, {}, { type: autocomplete, source: colors, strict: true, // 默认 allowInvalid: true }, { type: autocomplete, source: colors, strict: true, allowInvalid: true, // 显式声明true 是默认值 }, ], autoWrapRow: true, autoWrapCol: true, });注意官方示例网格中还配置了sanitizer来过滤列头中的 HTML示例使用自定义的sanitizeHeader白名单函数处理表头标签。这印证了文档中的警告——Handsontable v18 起不再内置 sanitizer如果你要渲染含 HTML 的内容需要自行接入经过验证的净化库如 DOMPurify并参考 安全指南 了解 sanitizer 的覆盖范围。校验器的实现原理严格模式的只接受 source 中的值由 autocompleteValidator.ts 实现。它首先处理空值值为null/undefined或空字符串时直接以allowEmpty选项作为校验结果返回在严格模式且存在source时若source是函数则把原值原样传给函数否则用process()在source数组中查找完全匹配isObjectEqual逐项比对的条目找到即通过校验export function autocompleteValidator( this: CellProperties, value: unknown, callback: (valid: boolean) void): void { validateAgainstSource(this, value, callback, !!this.strict); }值得注意的是严格模式是显式传入而非从 cell meta 读取——因为 dropdown cell type 无论 meta 如何设置都恒为严格模式源码注释中的 DEV-2911两者共用同一套校验逻辑。Autocomplete 严格模式 异步数据Asynchronous DataAutocomplete 同样支持异步数据源把source声明为一个函数即可从远端加载建议。该函数接收两个参数query当前输入的查询字符串process回调函数请求完成后用结果数组调用process(result)。new Handsontable(container, { height: auto, licenseKey: non-commercial-and-evaluation, data: [ [BMW, 2017, black, black], [Nissan, 2018, blue, blue], [Chrysler, 2019, yellow, black], [Volvo, 2020, white, gray], ], colHeaders: [Car, Year, Chassis color, Bumper color], columns: [ { type: autocomplete, source(_query, process) { // 使用 Fetch API 从服务器加载建议 fetch(/docs/scripts/json/autocomplete.json) .then((response) response.json()) .then((response) process(response.data)); }, strict: true, // 严格模式 异步数据 }, {}, {}, {}, // Bumper color 是默认文本列 ], autoWrapRow: true, autoWrapCol: true, });过期响应的处理机制异步场景有一个重要细节Handsontable 会忽略两类过期响应编辑器已关闭后才到达的响应——包括你可能没有察觉的关闭方式比如编辑中的单元格被滚动出视野scroll-hide导致编辑器关闭被更新的查询取代的响应——即用户继续输入触发了新查询旧查询的响应作废。因此文档建议只要请求完成就调用process()哪怕响应已经过期。Handsontable 内部会自行识别并丢弃无用的响应你无需也无法取消一个已经发出去的请求。这个机制在源码中有对应的实现证据在 autocompleteEditor.ts 中编辑器维护了#queryGeneration查询代际令牌每次queryChoices()都会递增用于区分过期查询和#editSession编辑会话令牌在close()和滚动隐藏时通过#dropInFlightQueries()递增用于标记整个编辑会话已被放弃以及#queryTimeouts被延迟的查询定时器集合。当迟到或超期的响应返回时编辑器通过这些令牌即可判断其归属的查询已被取代或放弃从而安全地丢弃。source 选项详解source是 autocomplete 的核心数据来源选项支持两种格式。格式一值数组Array of Values直接提供一个字符串数组作为建议列表const airportKVData [ Los Angeles International Airport, John F. Kennedy International Airport, Chicago OHare International Airport, London Heathrow Airport, Charles de Gaulle Airport, Dubai International Airport, // ... ]; new Handsontable(container, { height: auto, licenseKey: non-commercial-and-evaluation, data: shipmentKVData, // 如 [[Electronics and Gadgets, Los Angeles International Airport], ...] columns: [ { title: Shipment }, // 普通文本列 { type: autocomplete, source: airportKVData, // 值数组作为建议 title: Airport, }, ], autoWrapRow: true, autoWrapCol: true, });单元格存储的就是选中的字符串本身。格式二key value 对象数组Array of Objects将source声明为含key和value属性的对象数组value属性作为下拉建议显示文本整个对象含key作为单元格的值被存储。const airportKVData [ { key: LAX, value: Los Angeles International Airport }, { key: JFK, value: John F. Kennedy International Airport }, { key: ORD, value: Chicago OHare International Airport }, { key: LHR, value: London Heathrow Airport }, // ... ]; new Handsontable(container, { height: auto, licenseKey: non-commercial-and-evaluation, data: shipmentKVData, // 如 [[Electronics and Gadgets, { key: LAX, value: Los Angeles International Airport }], ...] columns: [ { title: Shipment }, { type: autocomplete, source: airportKVData, title: Airport, }, ], autoWrapRow: true, autoWrapCol: true, });这是典型的存代码、显名称store key, display value场景数据库或后端逻辑拿到的是LAX、JFK这样的简短 key而用户看到的是完整机场名。重要提示当source声明为keyvalue对象数组时单元格中的数据也应该是带keyvalue属性的对象二者格式必须一致。API 方法如何读取对象数据使用对象格式的 autocomplete 数据时可用以下 Core 方法获取原始对象格式含key与value的数据getSourceData()getSourceDataAtCell()getSourceDataAtRow()而getData()只返回value属性的值即显示文本不会返回key。写入普通值Writing a plain value你不必手动构造{ key, value }对象。当直接往单元格写入一个普通值plain value时Handsontable 会在source数组的value属性中查找匹配项一旦命中单元格就会存储整个匹配对象连同其key。这一查找适用于所有写入单元格的途径在编辑器下拉中选择某个选项输入选项文本后按Enter粘贴文本——包括从其他应用粘贴以及以纯文本形式粘贴Ctrl/CmdShiftV调用setDataAtCell()或populateFromArray()。若输入值不匹配任何选项则按原样存储在严格模式下这样的值会校验失败。这里的查找比较的是单元格显示的文本因此数值型value也能匹配其字符串形式例如{ key: 1, value: 2 }可用字符串2命中。当source是函数时此查找被跳过——因为选项要等函数返回后才可知。源码级佐证这一普通值 → 完整对象的映射由 valueSetter.ts 实现。它先判断新值本身是否已是 key/value 条目是则直接返回再跳过 UndoRedo 路径撤销/重做要原样恢复旧值避免把纯文本 label 包裹成{ key, value }伪造对象源码注释中的 DEV-57 即此类缺陷随后通过hasKeyValueChoices()快速判断source是否为对象数组并用findChoiceByDisplayedValue()把显示的 label 解析回完整条目若单元格原本存的就是对象则把普通值包装为{ key: newValue, value: newValue }。核心的 label 解析逻辑统一收口在 cellSource.ts 的findChoiceByDisplayedValue()——编辑器路径和 setter 路径共用同一个规则从根本上杜绝了两处实现漂移导致粘贴值变裸字符串的问题。filter 选项是否过滤不匹配的建议默认情况下autocomplete 下拉会隐藏与当前输入不匹配的选项。设置filter: false可以始终显示完整的source列表无论当前输入是什么。这适用于希望用户在输入过程中始终看到全部可选值的场景提供视觉参考。const fruits [ Apple, Apricot, Avocado, Banana, Blueberry, Cherry, Grape, Lemon, Lime, Mango, Orange, Peach, Pear, Pineapple, Plum, Raspberry, Strawberry, Watermelon, ]; new Handsontable(container, { height: auto, licenseKey: non-commercial-and-evaluation, data: [ [Apple, Apple], [Banana, Banana], [Cherry, Cherry], [Mango, Mango], [Orange, Orange], ], colHeaders: [Filter: true (default), Filter: false], columns: [ { type: autocomplete, source: fruits, strict: false, // filter: true 是默认值 —— 只显示匹配的选项 }, { type: autocomplete, source: fruits, strict: false, filter: false, // 不隐藏与查询不匹配的选项 }, ], autoWrapRow: true, autoWrapCol: true, });上例中左列使用默认行为filter: true——输入时选项不断收窄右列filter: false——无论输入什么全部选项始终可见。filteringCaseSensitive 选项大小写敏感过滤默认情况下 autocomplete 的搜索不区分大小写输入bl可以同时匹配Black和blue。设置filteringCaseSensitive: true可以要求精确大小写匹配。const colors [ Black, Blue, brown, cyan, Gray, green, Lime, Magenta, Navy, olive, orange, Pink, Purple, Red, silver, Teal, White, Yellow, ]; new Handsontable(container, { height: auto, licenseKey: non-commercial-and-evaluation, data: [ [Black, Black], [Blue, Blue], [Gray, Gray], [Red, Red], [White, White], ], colHeaders: [Case-insensitive (default), Case-sensitive], columns: [ { type: autocomplete, source: colors, strict: false, // filteringCaseSensitive: false 是默认值 —— 输入 bl 匹配 Black 和 blue }, { type: autocomplete, source: colors, strict: false, filteringCaseSensitive: true, // 搜索建议时区分大小写 }, ], autoWrapRow: true, autoWrapCol: true, });左列是默认的大小写不敏感行为右列开启filteringCaseSensitive: true后只有大小写与输入完全一致的选项才会被显示。sortByRelevance 选项建议排序默认情况下sortByRelevance: true下拉建议按照source数组中的声明顺序展示。设置sortByRelevance: false可以让建议按字母序排列。const statuses [Backlog, In progress, Blocked, Done, Cancelled]; new Handsontable(container, { height: auto, licenseKey: non-commercial-and-evaluation, data: [ [Backlog, Backlog], [In progress, In progress], [Blocked, Blocked], [Done, Done], [Cancelled, Cancelled], ], colHeaders: [Source order (default), Alphabetical order], columns: [ { type: autocomplete, source: statuses, strict: false, // sortByRelevance: true 是默认值 —— 建议保持 source 中的顺序 }, { type: autocomplete, source: statuses, strict: false, sortByRelevance: false, // 按字母序排序建议 }, ], autoWrapRow: true, autoWrapCol: true, });左列保持source原始顺序如 Backlog → In progress → Blocked → Done → Cancelled 的状态流转顺序通常更贴合业务语义右列则按字母序Backlog → Blocked → Cancelled → Done → In progress展示。allowHtml 选项将 source 渲染为 HTML默认情况下autocomplete 下拉列表与单元格渲染器都把source值当作纯文本显示值中携带的 HTML 标签会原样字面显示如显示span style...In stock/span字符串。设置allowHtml: true可以将source值按 HTML 渲染例如显示带颜色的状态标签。const stockStatuses [ span stylecolor: #1a7f37In stock/span, span stylecolor: #b35900Low stock/span, span stylecolor: #c92a2aOut of stock/span, span stylecolor: #495057Backordered/span, span stylecolor: #495057Discontinued/span, ]; new Handsontable(container, { height: auto, licenseKey: non-commercial-and-evaluation, data: [ [stockStatuses[0], stockStatuses[0]], [stockStatuses[1], stockStatuses[1]], [stockStatuses[2], stockStatuses[2]], [stockStatuses[3], stockStatuses[3]], [stockStatuses[4], stockStatuses[4]], ], colHeaders: [allowHtml: false (default), allowHtml: true], columns: [ { type: autocomplete, source: stockStatuses, strict: false, // allowHtml: false 是默认值 —— source 中的 HTML 标签以纯文本显示 }, { type: autocomplete, source: stockStatuses, strict: false, allowHtml: true, // 将 source 值渲染为 HTML —— 仅用于可信的静态数据 }, ], autoWrapRow: true, autoWrapCol: true, });安全警告必读Handsontable 不会对经allowHtml渲染的 HTML 做净化处理sanitizer选项也覆盖不到这里。只有对静态、可信的source数据才应开启此选项。渲染来自用户输入的source值会产生XSS 漏洞。详见 安全指南中What the sanitizer does not cover一节。从源码角度佐证allowHtml同时影响渲染器与 label 解析两条路径——在 cellSource.ts 的toDisplayedText()中每个建议的显示文本先经stringify()处理再依据allowHtml决定是否剥离 HTML 标签stripTags关闭时下拉显示文本与单元格显示都会剥离标签开启时则原样保留用于渲染。结果与行为总结完成以上配置后autocomplete 单元格呈现为一个带建议的文本输入框用户输入时下拉实时展示匹配建议灵活模式允许选择建议也允许输入source之外的任意自定义值严格模式只接受source列表中的值手动输入的非列表值根据allowInvalid决定是红色标记并继续还是拒绝输入。键盘快捷键autocomplete 编辑器与 handsontable 编辑器HOT-in-HOT 共享键盘快捷键在严格模式下部分快捷键行为有所不同上箭头在第一行不取消选中而是等同于 Enter详见前文严格模式一节。相关资源相关指南Cell typeDropdown cell typeSelect cell type配置选项详见各选项 API 文档allowHtml、allowInvalid、filter、filteringCaseSensitive、sortByRelevance、source、strict、trimDropdown、type、visibleRowsCore 方法getCellMeta()、getCellMetaAtRow()、getCellsMeta()、getDataType()、setCellMeta()、setCellMetaObject()、removeCellMeta()HooksafterGetCellMeta、afterSetCellMeta、beforeGetCellMeta、beforeSetCellMeta继续深入源码单元格类型注册autocompleteType.ts编辑器实现含异步查询代际令牌机制autocompleteEditor.ts校验器实现autocompleteValidator.ts键值对 label 解析与显示文本规则cellSource.ts赋值器普通值 → 完整对象映射valueSetter.ts官方配套示例docs/content/guides/cell-types/autocomplete-cell-type/目录下的javascript/example1.js ~ example9.js 及对应.ts、react/、angular/、vue/四套框架示例常见配置速查表配置项默认值作用type: autocomplete—启用 autocomplete 单元格类型source—建议数据源值数组、key/value 对象数组或异步加载函数(query, process) voidstrictfalsefalse为灵活模式可输入自定义值true为严格模式只接受 source 值allowInvalidtrue严格模式下是否允许手动输入非 source 值true红色标记并继续false拒绝输入编辑器保持打开visibleRows10下拉不滚动时显示的建议条数trimDropdowntrue下拉宽度是否与单元格宽度一致false 时扩展到最宽建议filtertrue输入时是否隐藏不匹配的建议false 时始终显示全部filteringCaseSensitivefalse过滤建议时是否区分大小写sortByRelevancetrue建议按 source 顺序true或字母序false排列allowHtmlfalse是否将 source 值渲染为 HTML仅限可信静态数据否则有 XSS 风险结合文档、示例与源码你可以根据业务需求自由组合以上选项枚举录入用strict: true保证数据规范开放式输入用灵活模式需要存代码显名称时用 key/value 对象数组数据量大有远端候选时用source函数 Fetch API需要视觉提示时谨慎使用allowHtml。赞分享前端UI组件【免费下载链接】handsontableJavaScript Data Grid / Data Table with a Spreadsheet Look Feel. Works with React, Angular, and Vue. Supported by the Handsontable team ⚡项目地址https://gitcode.com/gh_mirrors/ha/handsontable点击查看免费下载相关推荐JAX 配置系统完全指南三种设置方式与完整配置项解析JAX 配置系统完全指南三种设置方式与完整配置项解析 JAX 提供了统一的配置系统用以控制从数值精度、后端平台选择到调试检查等各类运行时行为。本文以仓库文档人工智能机器学习深度学习编译器高性能计算Handsontable 自定义 Moment.js 时间单元格类型Cell Type完整实战指南Handsontable 自定义 Moment.js 时间单元格类型Cell Type完整实战指南 本指南基于 Handsontable 官方 Recipe前端UI组件Ragas 安装完全指南从 pip 到源码可编辑安装的三种方式与依赖管理详解Ragas 安装完全指南从 pip 到源码可编辑安装的三种方式与依赖管理详解 本文是 Ragas 官方安装文档 docs/getstarted/instal人工智能大模型模型评测RAG创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考