在每个字段旁显示它的错误
机器翻译
本页由英文原文机器翻译而来,尚未经过母语审校,欢迎在 GitHub 上提出修改。内容如有出入,以英文原文为准。
任务: 拒绝一个错误的表单,并在每个字段旁说明它哪里不对。
yaml
# Recipe: the rules live on the action; the form shows each refusal on its field.
paths:
components: ./components
migrations: ./migrations
datasources:
db:
driver: sqlite
database: ./data/guests.dbsql
CREATE TABLE guests (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT NOT NULL,
age INTEGER NOT NULL
);规则只写一次,写在动作的 q:param 上。ui:form 读取它们并放到自己的字段上 (required、minlength、type="number"、min……),所以浏览器先检查。 服务器会再检查一次,所有字段一起检查:只要有一个失败,动作就不会运行,页面返回, 每个字段显示自己的消息。
xml
<q:component name="Guests">
<!-- The rules are written once, on the action. The form reads them (UI-9)
and the server checks them again (ACT-2), every field at once. -->
<q:action name="register" method="POST">
<q:param name="name" required="true" minlength="2" maxlength="60" />
<q:param name="email" type="email" required="true" />
<q:param name="age" type="integer" required="true" min="18" max="120" />
<q:query name="added" datasource="db">
INSERT INTO guests (name, email, age) VALUES (:name, :email, :age)
<q:param name="name" value="{name}" type="string" />
<q:param name="email" value="{email}" type="string" />
<q:param name="age" value="{age}" type="integer" />
</q:query>
<q:redirect url="/" flash="{name} is on the list." />
</q:action>
<ui:window title="Guest list">
<q:if condition="flash">
<ui:alert variant="{flashType == 'error' and 'danger' or 'success'}">{flash}</ui:alert>
</q:if>
<ui:form on-submit="register">
<ui:formitem label="Name"><ui:input bind="name" /></ui:formitem>
<ui:formitem label="E-mail"><ui:input bind="email" /></ui:formitem>
<ui:formitem label="Age"><ui:input bind="age" /></ui:formitem>
<ui:button variant="primary">Add guest</ui:button>
</ui:form>
</ui:window>
</q:component>在测试中,error="field" 检查该字段被拒绝,message= 检查它旁边显示的文本:
xml
<q:test name="a valid guest is added" page="/">
<test:submit action="register" name="Ana" email="ana@example.com" age="30" />
<test:expect redirect="/" flash="Ana is on the list." />
<test:expect table="guests" count="1" where="name = 'Ana' AND age = 30" />
</q:test>
<q:test name="every broken field gets its own message" page="/">
<test:submit action="register" name="A" email="not an address" age="12" />
<test:expect redirect="/" />
<test:expect error="name" message="Must be at least 2 characters" />
<test:expect error="email" message="Must be a valid email" />
<test:expect error="age" message="Must be at least 18 (got 12)" />
<test:expect text="Must be at least 2 characters" />
<test:expect table="guests" count="0" />
</q:test>
<q:test name="a missing field is refused as Required" page="/">
<test:submit action="register" name="Ana" email="ana@example.com" />
<test:expect error="age" message="Required" />
<test:expect table="guests" count="0" />
</q:test>text
tests/guests.test.q
PASS a valid guest is added
PASS every broken field gets its own message
PASS a missing field is refused as Required
3 passed, 0 failed