创建联系表单页面并通过 Ajax 提交表单请求数据
回顾下上篇教程更新主题后的博客系统,可以看到顶部右上角导航菜单有两个链接,分别指向关于页面和联系表单页面:
对应的 HTML 模板代码位于 resources/views/header.php
中:
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link" href="/">首页</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/about">关于</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/contact">联系</a>
</li>
</ul>
</div>
现在我们来为这两个页面定义 URL 路由和对应的页面渲染逻辑。在 app/routes/web.php
中注册路由:
$router->register('get', 'about', 'HomeController@about');
$router->register(['get', 'post'], 'contact', 'HomeController@contact');
我们将请求处理逻辑都放到了 HomeController
控制器对应的 Action 方法中实现。
关于页面
对于关于页面而言,我们直接对应的路由定义为重定向到外部链接:
class HomeController extends Controller
{
...
// 关于页面
public function about()
{
$response = new Response('', 301, ['Location' => 'https://laravel.geekai.co/about-us']);
$response->send();
}
...
}
渲染联系表单页面
对于联系表单页面,需要分两块处理,首先是渲染联系表单,这是一个 GET 请求:
// 联系表单页面
public function contact()
{
if ($this->request->getMethod() == 'GET') {
$pageTitle = '联系我 - ' . $this->container->resolve('app.name');
$siteName = $this->container->resolve('app.name');
$this->view->render('contact.php', compact('pageTitle', 'siteName'));
} else {
// @todo 处理表单请求数据(放到下一篇教程详细介绍)
}
}
我们通过 $this->request->getMethod()
获取 HTTP 请求方法,并以此作为依据进行下一步处理:如果是 GET 请求,则渲染联系表单页面,如果是 POST 请求,则处理表单请求数据。
渲染联系表单页面对应的视图模板是 resources/views/contact.php
,我们创建这个视图文件,并初始化代码如下:
<?php include 'header.php';?>
<!-- Page Header -->
<header class="masthead" style="background-image: url('/image/contact.jpg')">
<div class="overlay"></div>
<div class="container">
<div class="row">
<div class="col-lg-8 col-md-10 mx-auto">
<div class="page-heading">
<h1>联系我</h1>
<span class="subheading">你有问题?我有答案。</span>
</div>
</div>
</div>
</div>
</header>
<!-- Main Content -->
<div class="container">
<div class="row">
<div class="col-lg-8 col-md-10 mx-auto">
<p>你可以通过填写并提交下面的表单给我发送反馈消息,我会尽快给你回复!</p>
<form name="sentMessage" id="contactForm" novalidate>
<div class="control-group">
<div class="form-group floating-label-form-group controls">
<label>用户名</label>
<input type="text" class="form-control" placeholder="Name" id="name" required data-validation-required-message="请输入你的用户名">
<p class="help-block text-danger"></p>
</div>
</div>
<div class="control-group">
<div class="form-group floating-label-form-group controls">
<label>邮箱地址</label>
<input type="email" class="form-control" placeholder="Email Address" id="email" required data-validation-required-message="请输入你的邮箱">
<p class="help-block text-danger"></p>
</div>
</div>
<div class="control-group">
<div class="form-group col-xs-12 floating-label-form-group controls">
<label>手机号码</label>
<input type="tel" class="form-control" placeholder="Phone" id="phone" required data-validation-required-message="请输入你的手机号码">
<p class="help-block text-danger"></p>
</div>
</div>
<div class="control-group">
<div class="form-group floating-label-form-group controls">
<label>消息内容</label>
<textarea rows="5" class="form-control" placeholder="Message" id="message" required data-validation-required-message="请输入你要发聩的消息内容"></textarea>
<p class="help-block text-danger"></p>
</div>
</div>
<br>
<div id="success"></div>
<button type="submit" class="btn btn-primary" id="sendMessageButton">发送</button>
</form>
</div>
</div>
</div>
<hr>
<?php include 'footer.php';?>
<script src="/js/contact.js"></script>
</body>
</html>
这里主要包含的是一个联系表单,参照 node_modules/startbootstrap-clean-blog/contact.html
编写即可。
提交表单请求
在上面的视图模板中,可以看到最后额外引入了 /js/contact.js
文件,这个文件是联系表单页面需要额外用到的 JavaScript 脚本文件,目前还不存在,需要编写对应的前端处理代码,并通过 Laravel Mix 组件编译打包生成。
在 resources/js
目录下新建 contact.js
,并初始化代码如下:
require('./bootstrap')
require('startbootstrap-clean-blog/js/jqBootstrapValidation')
$(function() {
$("#contactForm input,#contactForm textarea").jqBootstrapValidation({
preventSubmit: true,
submitError: function($form, event, errors) {
// additional error messages or events
},
submitSuccess: function($form, event) {
event.preventDefault(); // prevent default submit behaviour
// get values from FORM
var name = $("input#name").val();
var email = $("input#email").val();
var phone = $("input#phone").val();
var message = $("textarea#message").val();
var firstName = name; // For Success/Failure Message
// Check for white space in name for Success/Fail message
if (firstName.indexOf(' ') >= 0) {
firstName = name.split(' ').slice(0, -1).join(' ');
}
$this = $("#sendMessageButton");
$this.prop("disabled", true); // Disable submit button until AJAX call is complete to prevent duplicate messages
$.ajax({
url: "/contact",
type: "POST",
data: {
name: name,
phone: phone,
email: email,
message: message
},
cache: false,
success: function(resp) {
// Success message
$('#success').html("<div class='alert alert-success'>");
$('#success > .alert-success').html("<button type='button' class='close' data-dismiss='alert' aria-hidden='true'>×")
.append("</button>");
$('#success > .alert-success')
.append("<strong>消息已发送。</strong>");
$('#success > .alert-success')
.append('</div>');
//clear all fields
$('#contactForm').trigger("reset");
},
error: function(resp) {
// Fail message
$('#success').html("<div class='alert alert-danger'>");
$('#success > .alert-danger').html("<button type='button' class='close' data-dismiss='alert' aria-hidden='true'>×")
.append("</button>");
$('#success > .alert-danger').append($("<strong>").text(resp.responseText));
$('#success > .alert-danger').append('</div>');
//clear all fields
$('#contactForm').trigger("reset");
},
complete: function() {
setTimeout(function() {
$this.prop("disabled", false); // Re-enable submit button when AJAX call is complete
}, 1000);
}
});
},
filter: function() {
return $(this).is(":visible");
},
});
$("a[data-toggle=\"tab\"]").click(function(e) {
e.preventDefault();
$(this).tab("show");
});
});
/*When clicking on Full hide fail/success boxes */
$('#name').focus(function() {
$('#success').html('');
});
这里我们首先通过 require('./bootstrap')
引入 jQuery 及 Bootstrap 模块,然后引入 jqBootstrapValidation
组件对表单请求数据进行简单验证,比如字段不能为空等,最后编写了一段 jQuery 代码处理表单数据的异步提交(Ajax 请求),关于代码实现细节就不展开介绍了,重点关注 submitSuccess
的情况下,$.ajax({...})
中的处理代码。
访问联系表单页面
完成以上工作后,在项目根目录下的 webpack.mix.js
中添加 contact.js
编译代码:
mix.js('resources/js/app.js', 'public/js')
.js('resources/js/contact.js', 'public/js/contact.js')
.sass('resources/sass/app.scss', 'public/css');
运行 npm run dev
重新编译打包前端代码,成功后就可以在 public/js
目录下看到 contact.js
了。
在浏览器中访问 http://localhost:9000/contact
,就可以看到联系表单页面了:
我们可以尝试提交空表单,会显示报错信息,这就是 jqBootstrapValidation
组件生效的效果:
这个处理逻辑是前端的,表单数据前端验证通过发送给后端的验证和处理逻辑,我们放到下篇教程介绍。
No Comments