这是学习案例的前端部分。前端使用layui UI框架,使用其layui table组件实现员工信息增删改操作。
Http Server
前端也设计成一个Verticle,启动一个Http server,监听8080端口,实现代码如下:
public class HrWebServer extends AbstractVerticle {
private static final Logger LOGGER = Logger.getLogger(HrWebServer.class.getName());
@Override
public void start(Promise<Void> startPromise) throws Exception {
HttpServer server = vertx.createHttpServer();
Router router = Router.router(vertx);
StaticHandler staticHander = StaticHandler
.create()
.setCachingEnabled(true)
.setDirectoryListing(false)
.setIndexPage("index.html");
router.route("/hr/*").handler(staticHander).failureHandler(routingContext -> {
HttpServerRequest request = routingContext.request();
String uri = request.absoluteURI();
LOGGER.log(Level.SEVERE, request.method().name() +" "+ uri, routingContext.failure());
});
server.requestHandler(router).listen(8080).onComplete(ar -> {
if (ar.succeeded()) {
startPromise.complete();
} else {
LOGGER.log(Level.SEVERE, "", ar.cause());
startPromise.fail(ar.cause());
}
});
}
}
HTML页面
首先引入响应得JS库文件。
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>Vert.x HR System</title>
<script src="./static/jquery/jquery.min.js"></script>
<link rel="stylesheet" href="./static/layui/css/layui.css">
<script src="./static/layui/layui.js"></script>
</head>
渲染layui table
通过调用后端获取员工列表接口,来渲染表格。
<div class="layui-row">
<table class="layui-table" lay-even id="employeetable"></table>
</div>
<script>
layui.use(['table', 'form', 'dropdown'], function () {
var table = layui.table;
渲染表格
table.render({
elem: '#employeetable', // 对应表格employeetable;
method: 'get', // 请求方法为HTTP GET
url: 'http://localhost:8081/api/v1/hr/employees', //Restful接口地址
cols: [[ // 表列, filed对应data数据的条目的对应值。
{ field: 'empno', title: '员工号', sort: true, align: "center" },
{ field: 'ename', title: '姓名' },
{ field: 'job', title: '职位' },
{ fixed: 'right', title: '操作', width: 134, minWidth: 125, templet: '#rowTool' }
]],
page: true, // 支持分页
limit: 5, // 默认5条记录一页
limits: [5, 10, 15], // 可以选5, 10, 15条记录一页
toolbar: '#mytoolbar',
defaultToolbar: ['exports', 'print'],
error: function (res) { // 请求失败回调函数
console.log(res);
/*
var code = res.status;
var responseText = res.responseText;
layer.msg(code + ": "+responseText);
*/
},
parseData: function (res) { // 将API结果解析成以符合layui table需要的数据格式
console.log(res);
return {
//"code": 0,
"code": res.successful ? 0 : -1,
"msg": "",
"count": res.count,
"data": res.data
}
}
});
});
</script>
新员工信息录入
在layui table的toolbar中添加一个"新建"按钮,点击弹出一个弹出层(表单),录入新员工信息,点击按钮进行提交。
var form = layui.form;
form.on('submit(newEmpSubmit)', function (data) {
//var jsonData = JSON.stringify(data.field);
//console.log(jsonData);
关闭(用户信息录入)弹出层,通过ajax提交
layer.close(layer.index);
// 获取表单信息
var enameValue = data.field["newEmpDivEmpName"];
var jobValue = data.field["newEmpDivJob"];
var jsonData = { "ename": enameValue, "job": jobValue };
$.ajax({
async: false,
type: 'post',
url: "http://127.0.0.1:8081/api/v1/hr/employees",
dataType: 'json',
data: JSON.stringify(jsonData),
success: function (response) {
layer.alert('新员工创建成功,员工编号: ' + response.empno, { title: "信息框标题", skin: "layui-layer-molv" });
table.reload('employeetable');
},
error: function (xhr) {
console.log(xhr);
var msg =
"<div class=\"layui-card\">" +
" <div class=\"layui-card-header\">" + xhr.status + ": " + xhr.statusText + "</div>" +
" <div class=\"layui-card-body\">" +
" <p>" + xhr.responseText + "</p>" +
" </div>" +
"</div>";
layer.alert(msg, { title: "信息框标题", skin: "layui-layer-molv" }); //
}
});
// 重置(清空)表单信息
$("#newEmpForm")[0].reset();
layui.form.render();
// 已经通过ajax提交表单,所以这里需要返回false,阻止表单重复提交。
return false;
});
页面执行效果如下:
完整代码
总的思路就是通过ajax调用Restful接口,前端通过js解析返回的json数据解析并进行展示。增删改查不一一列举(多是度娘出来的,就不献丑了),以下是html完整代码供参考。整个前,后端程序也打包上传在文章内,感兴趣的也可以下载。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>Vert.x HR System</title>
<script src="./static/jquery/jquery.min.js"></script>
<link rel="stylesheet" href="./static/layui/css/layui.css">
<script src="./static/layui/layui.js"></script>
</head>
<body>
<div class="layui-container" style="padding: 16px;">
<!-- 表格 -->
<div class="layui-row">
<table class="layui-table" lay-even id="employeetable"></table>
</div>
<!-- 新增员工弹出弹出层 -->
<div style="display: none; padding: 16px" id="newEmpDiv">
<form class="layui-form" id="newEmpForm">
<div class="layui-form-item">
<label class="layui-form-label">员工姓名: </label>
<div class="layui-inline">
<!--<input type="hidden" name="newEmpDivEmpNo"> -->
<input type="text" name="newEmpDivEmpName" lay-verify="required" placeholder="请输入员工姓名"
autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">员工职位: </label>
<div class="layui-input-block">
<select name="newEmpDivJob" lay-verify="required">
<option value="">请选择工种</option>
<option value="CLERK">CLERK</option> <!--selected-->
<option value="SALESMAN">SALESMAN</option>
<option value="2MANAGER">MANAGER</option>
<option value="ANALYST">ANALYST</option>
<option value="PRESIDENT">PRESIDENT</option>
</select>
</div>
</div>
<div class="layui-form-item">
<button type="submit" class="layui-btn" lay-submit lay-filter="newEmpSubmit">提 交</button>
<button type="reset" class="layui-btn layui-btn-primary">重 置</button>
<button type="button" id='newEmpClose' class="layui-btn layui-btn-primary">取 消</button>
<!--
Button按钮的type有三个可选属性: Button, submit, reset;
Button按钮的type属性默认值是submit, 所以在没有指定type属性的情况下, 点击Button按钮会触发提交form表单
放在表单中的button将其type设置为button, 则不会自动提交。
-->
</div>
</form>
</div>
<!--修改员工弹出框的代码 -->
<div style="display: none; padding: 16px" id="editPopup">
<form class="layui-form" action="">
<div class="layui-form-item">
<label class="layui-form-label">员工姓名</label>
<div class="layui-input-block">
<input type="text" id="ename" lay-verify="required" placeholder="请输入员工姓名" autocomplete="off"
class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">职位</label>
<div class="layui-input-block">
<input type="text" id="job" lay-verify="required" placeholder="请输入员工职位" autocomplete="off"
class="layui-input">
</div>
</div>
</form>
</div>
</div>
<!--表头工具栏-->
<script type="text/html" id="mytoolbar">
<div class="layui-btn-container layui-clear-space">
<a class="layui-btn layui-btn-sm layui-btn-primary layui-border" lay-event="add"> <i class="layui-icon layui-icon-add-1"></i>新增</i></a>
</div>
</script>
<!--行内工具栏-->
<script type="text/html" id="rowTool">
<div class="layui-clear-space">
<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
<a class="layui-btn layui-btn-xs" lay-event="more">更多<i class="layui-icon layui-icon-down"></i></a>
</div>
</script>
<script>
$("#newEmpClose").click(function () {
$("#newEmpForm")[0].reset();
layui.form.render();
layer.close(layer.index);
});
layui.use(['table', 'form', 'dropdown'], function () {
var form = layui.form;
form.on('submit(newEmpSubmit)', function (data) {
//var jsonData = JSON.stringify(data.field);
//console.log(jsonData);
关闭弹出图层
layer.close(layer.index);
var enameValue = data.field["newEmpDivEmpName"];
var jobValue = data.field["newEmpDivJob"];
var jsonData = { "ename": enameValue, "job": jobValue };
$.ajax({
async: false,
type: 'post',
url: "http://127.0.0.1:8081/api/v1/hr/employees",
dataType: 'json',
data: JSON.stringify(jsonData),
success: function (response) {
layer.alert('新员工创建成功,员工编号: ' + response.empno, { title: "信息框标题", skin: "layui-layer-molv" });
table.reload('employeetable');
},
error: function (xhr) {
console.log(xhr);
var msg =
"<div class=\"layui-card\">" +
" <div class=\"layui-card-header\">" + xhr.status + ": " + xhr.statusText + "</div>" +
" <div class=\"layui-card-body\">" +
" <p>" + xhr.responseText + "</p>" +
" </div>" +
"</div>";
layer.alert(msg, { title: "信息框标题", skin: "layui-layer-molv" }); //
}
});
$("#newEmpForm")[0].reset();
layui.form.render();
return false;
});
var table = layui.table;
渲染表格
table.render({
elem: '#employeetable',
method: 'get',
url: 'http://localhost:8081/api/v1/hr/employees',
cols: [[
{ field: 'empno', title: '员工号', sort: true, align: "center" },
{ field: 'ename', title: '姓名' },
{ field: 'job', title: '职位' },
{ fixed: 'right', title: '操作', width: 134, minWidth: 125, templet: '#rowTool' }
]],
page: true,
limit: 5,
limits: [5, 10, 15],
toolbar: '#mytoolbar',
defaultToolbar: ['exports', 'print'],
error: function (res) {
console.log(res);
/*
var code = res.status;
var responseText = res.responseText;
layer.msg(code + ": "+responseText);
*/
},
parseData: function (res) {
console.log(res);
return {
//"code": 0,
"code": res.successful ? 0 : -1,
"msg": "",
"count": res.count,
"data": res.data
}
}
});
//头部工具栏事件
table.on('toolbar(employeetable)', function (obj) {
//var checkStatus = table.checkStatus(obj.config.id);
switch (obj.event) {
case 'add':
//var data = checkStatus.data;
//layer.alert(JSON.stringify(data));
layer.open({
type: 1,
area: ['380px', '480px'],
skin: 'layui-layer-win10', //样式类名
title: "添加新员工",
content: $("#newEmpDiv")
});
break;
};
});
var dropdown = layui.dropdown;
/ 行内工具栏事件
table.on('tool(employeetable)', function (obj) {
var data = obj.data; // 获得当前行数据
if (obj.event === 'edit') { // '编辑'
layer.open({
type: 1, // layer提供了5种Page层类型。可传入的值有: 0(信息框, 默认), 1(页面层), 2(iframe层), 3(加载层), 4(tips层)
area: ['380px', '270px'],
//title: ['编辑员工信息','font-size:18px'],
title: '编辑员工信息',
content: $("#editPopup"),
btn: ['确定', '取消'],
success: function (layero, index) {
$('#ename').val(data.ename);
$('#job').val(data.job);
},
yes: function (index, layero) {
var empno = data.empno;
var enameValue = $('#ename').val();
var jobValue = $('#job').val();
var jsonData = { "ename": enameValue, "job": jobValue };
$.ajax({
url: "http://127.0.0.1:8081/api/v1/hr/employees/" + empno,
contentType: "application/json",
type: 'put',
dataType: 'json',
crossDomain: true,
data: JSON.stringify(jsonData),
success: function (response) {
//console.log("success: " + response)
table.reload('employeetable');
layer.close(index);
},
error: function (xhr) {
console.log(xhr);
}
});
}
});
} else if (obj.event === 'more') { '更多'下拉菜单
dropdown.render({
elem: this, // 触发事件的DOM对象
show: true, // 外部事件触发即显示
data: [
{ title: '查看', id: 'detail' },
{ title: '删除', id: 'del' }
],
click: function (menudata) {
var empno = data.empno;
if (menudata.id === 'detail') {
$.ajax({
url: "http://127.0.0.1:8081/api/v1/hr/employees/" + empno,
type: 'get',
crossDomain: true,
success: function (response) {
const jsonStr = JSON.stringify(response);
var jsonArr = $.parseJSON(jsonStr);
/*
$.each(jsonArr, function(index, value) {
console.log(index + ": " + value.ename);
});*/
//console.log("array[0]: " +jsonArr[0].ename);
//console.log("length: " +jsonArr.length);
var jsonObj = jsonArr[0];
var resultContent = "<div style=\"padding: 16px;\">" +
"<div class=\"layui-row\"><div class=\"layui-col-xs6\">员工编号</div><div class=\"layui-col-xs6\">" + jsonObj.empno + "</div></div>" +
"<div class=\"layui-row\"><div class=\"layui-col-xs6\">员工名称</div><div class=\"layui-col-xs6\">" + jsonObj.ename + "</div></div>" +
"<div class=\"layui-row\"><div class=\"layui-col-xs6\">员工职位</div><div class=\"layui-col-xs6\">" + jsonObj.job + "</div></div>" +
"</div>";
layer.open({
type: 1,
offset: 'auto' || ['200px', '280px'], // 居中
id: 'ID-demo-layer-offset-auto',
content: resultContent,
area: '240px',
btn: '关闭全部',
btnAlign: 'c', // 按钮居中
shade: 0, // 不显示遮罩
yes: function () {
layer.closeAll();
}
});
},
error: function (xhr) {
console.log(xhr);
}
});
} else if (menudata.id === 'del') {
layer.confirm('真的删除行 [员工信息: ' + empno + '] 么?', function (index) {
layer.close(index);
$.ajax({
url: "http://127.0.0.1:8081/api/v1/hr/employees/" + empno,
type: 'delete',
crossDomain: true,
success: function (response) {
table.reload('employeetable');
//layer.alert("done!");
},
error: function (xhr) {
console.log(xhr);
}
});
});
}
},
align: 'right', // 右对齐弹出
style: 'box-shadow: 1px 1px 10px rgb(0 0 0 / 12%);' // 设置额外样式
});
}
});
});
</script>
</body>
</html>