表单验证会根据一组预定义规则检查用户输入。当使用 AJAX 框架 时,表单验证无需任何特殊配置即可进行,其中,无效字段将获得焦点并显示错误消息(通常以警告窗口形式)。
对于基本验证,在HTML表单标签上包含data-request-flash 属性提供了一个简洁的界面,用于显示验证消息,并且通常足以满足大多数实现的需求。
<form data-request="onSubmit" data-request-flash>
<div>
<label>Name</label>
<input name="name" />
</div>
<button data-attach-loading>
Submit
</button>
</form>在您的 AJAX 处理程序 中,您可以使用 ValidationException 类抛出 验证异常 来使字段无效。所提供的数组(第一个参数)应该使用字段名作为键,错误消息作为值。
function onSubmit()
{
if (!post('name')) {
throw new ValidationException(['name' => 'You must give a name!']);
}
}当 AJAX 框架遇到 ValidationException 时,它将自动聚焦第一个无效字段并显示错误消息,如果已配置。
为了获得更全面的验证体验,可以通过在 HTML 表单标签上包含 data-request-validate 属性来启用内联验证。下面是一个使用这种方法进行表单验证的最小示例,错误消息显示在表单内部。
<form data-request="onSubmit" data-request-validate>
<div class="alert alert-danger" data-validate-error>
<!-- Validation Message -->
</div>
<div>
<label>Name</label>
<input name="name" />
</div>
<button data-attach-loading>
Submit
</button>
</form>在某些情况下,您可能希望在值更改时验证单个字段。 通过在 data-track-input 属性旁边包含 data-request 属性,当用户在字段中输入内容时,AJAX 框架将提交一个请求。
<form data-request-validate>
<div>
<label>Username</label>
<input name="username" data-request="onCheckUsername" data-track-input />
</div>
</form>一个专用的 AJAX 处理程序可用于验证该字段。如果未抛出异常,即可视为有效。
function onCheckUsername()
{
if (true) {
throw new ValidationException(['username' => 'Username is taken!']);
}
}查看 验证文章 以了解您可以在此处使用的不同规则。
对于更复杂的验证,您可以利用 Request facade 批量地对用户输入应用规则。该 validate 方法使用指定的规则(第一个参数)执行验证,并以数组形式返回已验证的属性和值。如果验证失败,它还会抛出 ValidationException。
function onSubmit()
{
$data = Request::validate([
'name' => 'required',
'email' => 'required|email',
]);
// The code will not reach here if validation fails
Flash::success('Jobs done!');
}要更改默认的验证消息,你可以向 validate 方法传递自定义消息。消息数组(第三个参数)中的键遵循 attribute.rule 格式。
$messages = [
'email.required' => 'Please type something for the email...',
'email.email' => 'That email is not an email...!'
];
$data = Request::validate($rules, $messages);如果您想保留默认的验证消息,并且只更改使用的:attribute名称,将自定义属性作为数组(第四个参数)传递。
$attributeNames = [
'email' => 'e-mail address'
];
$data = Request::validate($rules, [], $attributeNames);在表单内部,你可以通过在一个容器元素上使用 data-validate-error 属性来显示第一个错误消息。容器内部的内容将被设置为错误消息,并且该元素将变得可见。
<div data-validate-error></div>要显示多个错误消息,请包含一个带有 data-message 属性的元素。在此示例中,段落标签将被复制,并为每个存在的错误消息设置其内容。
<div class="alert alert-danger" data-validate-error>
<p data-message></p>
</div>如果您更喜欢为单个字段显示验证消息,定义一个使用 data-validate-for 属性的元素,并将字段名称作为值传递。
<!-- Input field -->
<input name="phone" />
<!-- Validation message for the field -->
<div data-validate-for="phone"></div>如果该元素留空,它将填充来自服务器的验证文本。否则,你可以指定任何你喜欢的文本,它将代替显示。
<div data-validate-for="phone">
Oops.. phone number is invalid!
</div>当 data-request-validate 属性与 data-request-flash 属性 结合使用时,验证错误会优先显示并抑制闪存消息。要同时显示两者,请将属性设置为通配符 (*) 以显示所有闪存消息类型,包括验证信息。
<form
data-request-validate
data-request-flash="*">要为错误消息实现自定义功能,请挂接到 ajax:invalid-field 事件以显示字段以及 ajax:promise 以在新提交时重置表单。所使用的 JavaScript 事件可在 AJAX JavaScript API 中找到。
addEventListener('ajax:invalid-field', function(event) {
const { element, fieldName, errorMsg, isFirst } = event.detail;
element.classList.add('has-error');
});
addEventListener('ajax:promise', function(event) {
event.target.closest('form').querySelectorAll('.has-error').forEach(function(el) {
el.classList.remove('has-error');
});
});下方是一个完整的表单验证示例。它调用 onSubmitForm 事件处理程序,该程序会触发一个加载中的提交按钮,对表单字段执行验证,然后显示一条成功的闪存消息。
data-request-flash 属性用于为成功消息启用闪存消息并显示验证消息。data-attach-loading 属性用于显示加载指示器并防止因误点击而导致的重复提交。
<form
data-request="onSubmitForm"
data-request-validate
data-request-flash>
<div>
<label>Username</label>
<input name="username"
data-request="onCheckUsername"
data-track-input
data-attach-loading />
<span data-validate-for="username"></span>
</div>
<div>
<label>Email</label>
<input name="email" />
<span data-validate-for="email"></span>
</div>
<button data-attach-loading>
Submit
</button>
<div class="alert alert-danger" data-validate-error>
<p data-message></p>
</div>
</form>onSubmitForm AJAX 事件处理器查看客户端发送的 POST 数据,并对验证器应用一些规则。如果验证失败,则抛出 ValidationException,否则返回 Flash::success 消息。
onCheckUsername 检查用户名是否可用,当前硬编码为防止用户名 admin 和 jeff 被输入。 它被检查两次,当用户输入内容时和当用户提交表单时。
function onSubmitForm()
{
$data = Request::validate([
'username' => 'required',
'email' => 'required|email',
]);
$this->onCheckUsername();
Flash::success('Jobs done!');
}
function onCheckUsername()
{
$username = strtolower(trim(post('username')));
$isTaken = in_array($username, ['admin', 'jeff']);
if ($isTaken) {
throw new ValidationException(['username' => 'Username is taken!']);
}
}