iter(g280): 表单项支持条件显示
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { h } from '@ui-arch/frame';
|
||||
import { effect, h } from '@ui-arch/frame';
|
||||
import { button } from './button.js';
|
||||
import { grid } from './grid.js';
|
||||
import type { FormItemHandle, FormItemProps, FormProps, FormRule } from './types.js';
|
||||
@@ -40,6 +40,8 @@ export function formItem(props: FormItemProps, control: HTMLElement): FormItemHa
|
||||
const label = h('label', { class: 'ua-form-label' }, props.label, props.required ? h('i', { class: 'ua-form-req' }, '*') : null);
|
||||
const el = h('div', { class: 'ua-form-item' }, label, h('div', { class: 'ua-form-control' }, control, hint, error));
|
||||
if (props.span) el.style.gridColumn = `span ${props.span}`; // 多列布局里跨列;单列容器下由 CSS 还原为整行
|
||||
// 条件显示:隐藏时顺带清掉错误态,否则「看不见的红框」会拦住提交
|
||||
if (props.visible) effect(() => { el.hidden = !props.visible?.(); if (el.hidden) paint(null); });
|
||||
let seq = 0; // 校验轮次:异步结论回来时若已有更新的一轮,丢弃旧结果(防乱序覆盖)
|
||||
|
||||
/*** 错误态落点:控件根 + 内部原生控件,保证 select / checkbox 这类包裹式控件也能标红 ***/
|
||||
@@ -58,6 +60,7 @@ export function formItem(props: FormItemProps, control: HTMLElement): FormItemHa
|
||||
|
||||
/*** 同步校验:异步规则不结论,保证 blur / input 路径不被 Promise 拖慢 ***/
|
||||
const validate = (): string | null => {
|
||||
if (el.hidden) return null; // 隐藏项不参与校验:没显示的字段不该拦住提交
|
||||
const value = props.value();
|
||||
let msg: string | null = null;
|
||||
for (const rule of rules) {
|
||||
@@ -70,6 +73,7 @@ export function formItem(props: FormItemProps, control: HTMLElement): FormItemHa
|
||||
|
||||
/*** 异步校验:按序 await 每条规则,结论按轮次取舍,过期结果不动 UI ***/
|
||||
const validateAsync = async (): Promise<string | null> => {
|
||||
if (el.hidden) return null; // 隐藏项不参与异步校验,与同步版同一口径
|
||||
seq += 1;
|
||||
const mine = seq; // 本轮编号
|
||||
const value = props.value();
|
||||
|
||||
@@ -462,6 +462,7 @@ export interface FormItemProps {
|
||||
validateOn?: 'input' | 'blur' | 'submit'; // 校验时机;缺省 blur
|
||||
hint?: string; // 控件下方辅助说明(格式提示等);报错时让位给错误文案
|
||||
span?: number; // 多列表单里本字段占几列(如整宽的多行文本);单列布局下无效
|
||||
visible?: Signal<boolean>; // 条件显示信号:为假时整项隐藏且不参与校验(未显示的字段不该拦住提交)
|
||||
}
|
||||
|
||||
/*** 表单字段句柄:form 聚合校验用 ***/
|
||||
|
||||
@@ -1859,6 +1859,11 @@
|
||||
"t": "number",
|
||||
"d": "多列表单里本字段占几列(如整宽的多行备注);单列布局或窄屏下自动退回整行"
|
||||
},
|
||||
{
|
||||
"n": "(formItem)visible",
|
||||
"t": "Signal<boolean>",
|
||||
"d": "条件显示信号:为假时整项隐藏且不参与校验(未显示的字段不该拦住提交)"
|
||||
},
|
||||
{
|
||||
"n": "onReset",
|
||||
"t": "() => void",
|
||||
@@ -1891,7 +1896,8 @@
|
||||
"formItem 返回 { el, validate, validateAsync } 句柄:validate 只跑同步规则(供 blur/input 即时反馈),validateAsync 逐条 await 供 form 聚合提交",
|
||||
"需要给字段加格式说明就传 hint:平时显示在控件下方,校验失败时自动让位给错误文案,同一位置不堆两行",
|
||||
"字段多的编辑页传 columns: 2 或 3 走多列栅格:列间距与窄屏堆叠沿用 grid,按钮区始终整行;单列表单不要传(默认 1)",
|
||||
"多列表单里想整宽就传 span:formItem({ span: 2 }, textarea(...)) 会占满两列,窄屏单列时自动忽略跨列(否则会撑出横向滚动)"
|
||||
"多列表单里想整宽就传 span:formItem({ span: 2 }, textarea(...)) 会占满两列,窄屏单列时自动忽略跨列(否则会撑出横向滚动)",
|
||||
"字段要按另一个字段的值决定是否出现(选了「其他」才出现输入框),给 formItem 传 visible 信号:隐藏项自动清掉错误态并退出校验,不用自己在 items 数组里增删"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user