iter(g296): 修正表单校验失败仍提交
This commit is contained in:
@@ -30,6 +30,10 @@ async function checkRuleAsync(value: string, rule: FormRule): Promise<string | n
|
||||
return r === true ? null : typeof r === 'string' ? r : rule.message ?? '校验未通过';
|
||||
}
|
||||
|
||||
/*** 字段容器里的焦点落点:自绘控件(非搜索式下拉、评分、开关)没有原生 input,只查 input 会拿到 null,退到按钮 / 带 tabindex 的节点 ***/
|
||||
const focusableOf = (box: HTMLElement): HTMLElement | null =>
|
||||
box.querySelector<HTMLElement>('input:not([type="hidden"]), textarea, select, button, [tabindex]:not([tabindex="-1"])');
|
||||
|
||||
/*** 表单字段:label + 控件插槽 + 错误区;返回句柄(同步 / 异步两种校验)供 form 聚合 ***/
|
||||
export function formItem(props: FormItemProps, control: HTMLElement): FormItemHandle {
|
||||
// —— 状态集中声明 ——
|
||||
@@ -120,13 +124,15 @@ export function form(props: FormProps, items: FormItemHandle[]): HTMLElement {
|
||||
if (!msg) continue; // 卫语句:本项通过
|
||||
bad += 1;
|
||||
if (firstBad) continue; // 只把首个错误控件留作焦点目标
|
||||
firstBad = item.el.querySelector('input, textarea, select') as HTMLElement | null;
|
||||
const target = focusableOf(item.el);
|
||||
if (!target) item.el.tabIndex = -1; // 整块无可聚焦控件时把字段容器本身设为焦点落点(-1 不进 Tab 序,只接受程序聚焦)
|
||||
firstBad = target ?? item.el;
|
||||
}
|
||||
submitBtn.disabled = false;
|
||||
running = false;
|
||||
summary.hidden = bad === 0;
|
||||
summary.textContent = bad ? `有 ${bad} 项需要修改,已定位到第一处` : '';
|
||||
if (firstBad) { firstBad.focus(); props.onError?.(bad); return; } // 卫语句:有错误不提交
|
||||
if (bad > 0) { firstBad?.focus(); props.onError?.(bad); return; } // 有错即中止:判据用错误数而非焦点目标,否则自绘控件字段会漏过去直接提交
|
||||
props.onSubmit?.();
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user