代码拉取完成,页面将自动刷新
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>学生</title>
<link rel="stylesheet" href="./bootstrap/bootstrap.min.css" />
<link rel="stylesheet" href="./bootstrap/bootstrap-icons.css" />
<link rel="stylesheet" href="./css/common.css" />
<style>
.text {
font-size: 12px;
margin: 0;
padding: 5px 20px;
color: #999;
}
.card i:hover {
cursor: pointer;
}
.bt-1 {
margin-top: 4px;
}
.card-fluid {
border: none;
padding: 15px;
}
.card .table th {
border-color: transparent;
}
.form-group {
display: flex;
align-items: center;
height: calc(1.5em + 1.5rem + 2px);
}
.form-group>label {
width: 100px;
text-align: right;
padding-right: 10px;
margin-bottom: 0;
}
.form-group>input {
flex: 1;
}
.form-group .input {
flex: 1;
padding-left: 10px;
display: flex;
}
.form-group .form-check {
margin-bottom: 0;
margin-right: 30px;
}
.form-group .input select {
width: 140px;
margin-right: 20px;
}
.custom-select {
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23999999' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");
background-size: 12px 12px;
}
</style>
</head>
<body class="application application-offset">
<div class="container-fluid container-application">
<div class="sidenav show" id="sidenav-main">
<!-- Sidenav header -->
<div class="sidenav-header d-flex align-items-center">
<a class="navbar-brand" href="./index.html">
<span class="logo">·ITCAST·</span>
</a>
</div>
<!-- User mini profile -->
<div class="sidenav-user d-flex flex-column align-items-center justify-content-between text-center">
<!-- Avatar -->
<div>
<a href="#" class="avatar rounded-circle avatar-xl">
<img alt="Image placeholder" src="https://yanxuan-item.nosdn.127.net/8b27deb1670c53e67c42ca3e1ed6fd12.jpg"
class="" />
</a>
<div class="mt-5">
<h5 class="mb-0 text-white">黑马前端</h5>
<span class="d-block text-sm text-white opacity-8 mb-3">数据可视化</span>
<a href="javascript:;" class="btn btn-sm btn-white btn-icon rounded-pill shadow hover-translate-y-n3">
<span class="btn-inner--text">学前端来黑马</span>
</a>
</div>
</div>
</div>
<!-- Application nav -->
<div class="nav-application clearfix">
<a href="./index.html" class="btn btn-square text-sm">
<span class="btn-inner--icon d-block"><i class="bi bi-house bi-2x"></i></span>
<span class="btn-inner--icon d-block pt-2">首页</span>
</a>
<a href="./student.html" class="btn btn-square text-sm active">
<span class="btn-inner--icon d-block"><i class="bi bi-people bi-2x"></i></span>
<span class="btn-inner--icon d-block pt-2">学生</span>
</a>
<a href="javascript:;" class="btn btn-square text-sm">
<span class="btn-inner--icon d-block"><i class="bi bi-columns bi-2x"></i></span>
<span class="btn-inner--icon d-block pt-2">排版</span>
</a>
<a href="javascript:;" class="btn btn-square text-sm">
<span class="btn-inner--icon d-block"><i class="bi bi-files bi-2x"></i></span>
<span class="btn-inner--icon d-block pt-2">资料</span>
</a>
<a href="javascript:;" class="btn btn-square text-sm">
<span class="btn-inner--icon d-block"><i class="bi bi-receipt bi-2x"></i></span>
<span class="btn-inner--icon d-block pt-2">就业</span>
</a>
<a href="javascript:;" class="btn btn-square text-sm">
<span class="btn-inner--icon d-block"><i class="bi bi-gear bi-2x"></i></span>
<span class="btn-inner--icon d-block pt-2">设置</span>
</a>
</div>
<!-- Misc area -->
<div class="card bg-gradient-warning">
<div class="card-body">
<h5 class="text-white">哈喽, 朋友!</h5>
<p class="text-white mb-4">为什么不现在开始学习前端,创造一些令人惊叹的东西呢?</p>
<a href="http://itcast.cn" class="btn btn-sm btn-block btn-white rounded-pill" target="_blank">Get started</a>
</div>
</div>
</div>
<div class="main-content position-relative">
<nav class="navbar navbar-main navbar-expand-lg navbar-dark navbar-border" id="navbar-main">
<div class="container-fluid">
<!-- Navbar nav -->
<div class="collapse navbar-collapse navbar-collapse-fade" id="navbar-main-collapse">
<ul class="navbar-nav align-items-lg-center">
<!-- Home -->
<li class="nav-item">
<a class="nav-link pl-lg-0" href="./index.html"> 首页 </a>
</li>
<li class="nav-item">
<a class="nav-link pl-lg-0" href="./index.html"> 传智教育 </a>
</li>
<li class="nav-item">
<a class="nav-link pl-lg-0" href="./index.html"> 黑马程序员 </a>
</li>
<li class="nav-item">
<a class="nav-link pl-lg-0" href="./index.html"> 文档 </a>
</li>
</ul>
<!-- Right menu -->
<ul class="navbar-nav ml-lg-auto align-items-center d-none d-lg-flex">
<li class="nav-item dropdown dropdown-animate">
<a class="nav-link pr-lg-0" href=".dropdown-menu" role="button" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
<div class="media media-pill align-items-center">
<span class="avatar rounded-circle">
<img alt="Image placeholder"
src="https://yanxuan-item.nosdn.127.net/8b27deb1670c53e67c42ca3e1ed6fd12.jpg" />
</span>
<div class="ml-2 d-none d-lg-block">
<span class="username mb-0 text-sm font-weight-bold">Admin</span>
</div>
</div>
</a>
</li>
<li class="nav-item">
<a class="nav-link pl-lg-0" id="logout" href="javascript:;"> 退出 </a>
</li>
</ul>
</div>
</div>
</nav>
<div class="page-content">
<div class="page-title mb-3">
<div class="row justify-content-between align-items-center">
<div class="col-md-6 mb-3 mb-md-0">
<h5 class="h3 font-weight-400 mb-0 text-white">Students</h5>
<span class="text-sm text-white opacity-8">一共有 <b class="total">0</b> 位学员</span>
</div>
<div class="col-md-6 d-flex align-items-center justify-content-between justify-content-md-end">
<a id="openModal" href="javascript:;" class="btn btn-sm btn-white btn-icon-only rounded-circle ml-4">
<span class="btn-inner--icon"><i class="bi bi-plus bi-2x"></i></span>
</a>
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="card card-fluid">
<div class="table-responsive" style="min-height: 1000px">
<table class="table align-items-center">
<thead>
<tr>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>组号</th>
<th>期望薪资</th>
<th>就业薪资</th>
<th>籍贯</th>
<th>操作</th>
</tr>
</thead>
<tbody class="list">
<!-- <tr>
<td>张杰</td>
<td>20</td>
<td>男</td>
<td>第2组</td>
<td>10000</td>
<td>13000</td>
<td>北京北京市东城区</td>
<td>
<a href="javascript:;" class="text-success mr-3"><i class="bi bi-pen"></i></a>
<a href="javascript:;" class="text-danger"><i class="bi bi-trash"></i></a>
</td>
</tr> -->
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- footer -->
<div class="footer pt-5 pb-4 footer-light" id="footer-main">
<div class="row text-center text-sm-left align-items-sm-center">
<div class="col-sm-6">
<p class="text-sm mb-0">© 2022 <a href="https://itcast.cn" class="h6 text-sm" target="_blank">前端学科</a>.
All rights reserved.</p>
</div>
<div class="col-sm-6 mb-md-0">
<ul class="nav justify-content-center justify-content-md-end">
<li class="nav-item">
<a class="nav-link" href="#">Support</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Terms</a>
</li>
<li class="nav-item">
<a class="nav-link pr-0" href="#">Privacy</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- add Modal -->
<div class="modal fade" id="modal">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">添加学员</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form id="form" class="g-3 row" autocomplete="off" novalidate>
<div class="col-sm-6">
<div class="form-group">
<label class="input-group-label">姓名:</label>
<input type="text" name="name" class="form-control" placeholder="请输入姓名" />
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label class="input-group-label">性别:</label>
<div class="input">
<div class="form-check d-inline-block">
<input value="0" checked id="cb01" class="form-check-input" type="radio" name="gender" />
<label for="cb01" class="form-check-label">男</label>
</div>
<div class="form-check d-inline-block">
<input value="1" id="cb02" class="form-check-input" type="radio" name="gender" />
<label for="cb02" class="form-check-label">女</label>
</div>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label class="input-group-label">年龄:</label>
<input type="text" name="age" class="form-control" placeholder="请输入年龄" />
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label class="input-group-label">组号:</label>
<input type="text" name="group" class="form-control" placeholder="请输入1-8组号" />
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label class="input-group-label">期望薪资:</label>
<input type="text" name="hope_salary" class="form-control" placeholder="请输入期望薪资" />
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label class="input-group-label">就业薪资:</label>
<input type="text" name="salary" class="form-control" placeholder="请输入就业薪资" />
</div>
</div>
<div class="col-sm-12">
<div class="form-group">
<label class="input-group-label">籍贯:</label>
<div class="input pl-0">
<select class="form-select custom-select" name="province">
<option value="">--省份--</option>
</select>
<select class="form-select custom-select" name="city">
<option value="">--城市--</option>
</select>
<select class="form-select custom-select" name="area">
<option value="">--地区--</option>
</select>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-blue" id="submit">确认</button>
</div>
</div>
</div>
</div>
<script src="./bootstrap/bootstrap.min.js"></script>
<script src="./lib/axios.js"></script>
<script src="./lib/form-serialize.js"></script>
<script src="./js/common.js"></script>
<script src="./js/permission.js"></script>
<script>
const tbody = document.querySelector('.list')
// 目标1: 渲染学生列表
// 1.1 封装函数发请求获取数据
// 1.2 渲染总数
// 1.3 渲染表格数据
async function getStudents() {
// 1.1 封装函数发请求获取数据
const res = await axios({ url: '/students' })
// console.log(res)
// 1.2 渲染总数
document.querySelector('.total').innerHTML = res.data.length
// // 1.3 渲染表格数据
tbody.innerHTML = res.data.map(item => `<tr>
<td>${item.name}</td>
<td>${item.age}</td>
<td>${item.gender ? '女' : '男'}</td>
<td>第${item.group}组</td>
<td>${item.hope_salary}</td>
<td>${item.salary}</td>
<td>${item.province}${item.city}${item.area}</td>
<td>
<a href="javascript:;" class="text-success mr-3"><i data-id="${item.id}" class="bi bi-pen"></i></a>
<a href="javascript:;" class="text-danger"><i data-id="${item.id}" class="bi bi-trash"></i></a>
</td>
</tr>`).join('')
}
getStudents()
//目标2:删除学生
//2.1 通过事件委托删除按钮绑定点击事件
//2.2 获取当前被点击的学生 id (自定义属性)
//2.3 发请求删除数据
//2.4重新渲染
//2.1通过事件委托给删除按钮绑定点击事件
tbody.addEventListener('click', async e => {
if (e.target.classList.contains('bi-trash')) {
//2.2获取当前被点击的学生 id (自定义属性)
const id = e.target.dataset.id
// console.log('删除:', id)
//2.3发请求删除数据
//注意: 必须要加 await, 要等待删除成功后再渲染
await axios({ url: `/students/${id}`, method: 'delete' })
//2.4重新渲染
getStudents()
}
})
// 创建模态框对象
const modal = new bootstrap.Modal('#modal', {
backdrop: 'static', // 默认值为 true, 模态框的遮罩层是否显示, 还可以设置为 static, 显示但无法点击
keyboard: false // 按 esc 键是否关闭模态框, 默认值为 true
})
const form = document.querySelector('#form')
const modalTitle = document.querySelector('.modal-title')
const province = document.querySelector('[name=province]')
const city = document.querySelector('[name=city]')
const area = document.querySelector('[name=area]')
// 目标3: 添加学生
// 3.1 给添加按钮绑定点击事件, 打开模态框
// 3.2 设置标题
// 3.3 清空表单
// 3.4 设置模态框的 options 实现按 esc 不关闭 / 点击遮罩层不关闭
// 3.5 打开模态框后获取省份列表
// 3.6 监听用户选择省份, 获取并渲染城市列表
// 3.7 监听用户选择城市, 获取并渲染地区列表
document.querySelector('#openModal').addEventListener('click', async () => {
//打开添加框需要清空 id
id = null
// 打开模态框
modal.show()
// 设置标题
modalTitle.innerHTML = '添加学员'
// 清空表单
form.reset()
// 获取省份列表
const res = await axios({ url: 'http://hmajax.itheima.net/api/province' })
// console.log(res)
// 渲染省份
province.innerHTML = '<option value="">--省份--</option>' + res.list.map(item => `<option value="${item}">${item}</option>`).join('')
})
// 监听 province 的 change 事件
province.addEventListener('change', async () => {
// console.log(province.value)
const res = await axios({ url: 'http://hmajax.itheima.net/api/city', params: { pname: province.value } })
// console.log(res)
city.innerHTML = '<option value="">--城市--</option>' + res.list.map(item => `<option value="${item}">${item}</option>`).join('')
// 注意: 省份切换时需要清空地区
area.innerHTML = '<option value="">--地区--</option>'
})
// 监听 city 的 change 事件
city.addEventListener('change', async () => {
const res = await axios({ url: 'http://hmajax.itheima.net/api/area', params: { pname: province.value, cname: city.value } })
area.innerHTML = '<option value="">--地区--</option>' + res.list.map(item => `<option value="${item}">${item}</option>`).join('')
})
document.querySelector('#submit').addEventListener('click', async () => {
// 由于我们添加学生和编辑学生的模态框是同一个, 那么确认按钮也是同一个
// 在点击确认后, 我们需要判断当前打开的模态框是添加还是编辑, 来决定具体的业务
const data = serialize(form, { hash: true, empty: true })
// console.log(data)
// 转换数据类型
data.age = +data.age
data.gender = +data.gender
data.salary = +data.salary
data.hope_salary = +data.hope_salary
data.group = +data.group
// 发请求
// await axios({
// url: '/students',
// method: 'post',
// data
// })
// 如果 id 有值说明当前正在编辑, 否则说明是添加
if (id) {
await axios({
url: `/students/${id}`,
method: 'put',
data
})
} else {
// 发请求
await axios({
url: '/students',
method: 'post',
data
})
}
// 隐藏模态框
modal.hide()
// 重新渲染
getStudents()
})
//3.1 给即将要被点击的 i标签添加自定义属性 data-id
//3.2 使用事件委托绑定事件
//3.3 点击编辑按钮时获取到当前点击的标签 id
//3.4 显示并初始化模态框
//标题设置为编辑学员
//清空表单
//3.5 发请求获取当前学生信息
//3.6 数据回显
//获取所有的省份并渲染
//获取所有的城市并渲染
//获取所有的地区并渲染
//使用循环来一一对应渲染
//对 gender 单独处理
// 3.7 点击时记录 id 放到全局 (用作判断添加 or 编辑)
// 3.8 打开确认框需要将 id 清空
// 3.9 点击确定按钮时用 id 来判断是添加还是编辑
// 3.10 添加逻辑不变, 如果是编辑就发送编辑请求
// 3.11 最终都是关闭模态框并重新渲染
// id 的作用是用于分辨当前模态框是添加还是编辑
let id
tbody.addEventListener('click', async e => {
if (e.target.classList.contains('bi-pen')) {
id = e.target.dataset.id
console.log('编辑:', id)
//打开模态框
modal.show()
//设置标题
modalTitle.innerHTML = '修改学员'
//清空表单
form.reset()
// 发请求获取当前学生信息
const res = await axios({ url: `/students/${id}` })
// 还要发请求获取所有的省份 / 城市 / 地区
const pRes = await axios({ url: 'http://hmajax.itheima.net/api/province' })
// 渲染省份
province.innerHTML = '<option value="">--省份--</option>' + pRes.list.map(item => `<option value="${item}">${item}</option>`).join('')
// 获取所有城市
const cRes = await axios({ url: 'http://hmajax.itheima.net/api/city', params: { pname: res.data.province } })
city.innerHTML = '<option value="">--城市--</option>' + cRes.list.map(item => `<option value="${item}">${item}</option>`).join('')
// 获取所有地区
const aRes = await axios({ url: 'http://hmajax.itheima.net/api/area', params: { pname: res.data.province, cname: res.data.city } })
area.innerHTML = '<option value="">--地区--</option>' + aRes.list.map(item => `<option value="${item}">${item}</option>`).join('')
// console.log(res)
Object.keys(res.data).forEach(k => {
// console.log(k)
// 判断: 如果是 gender 要单独处理
// 0 表示男 1 表示女
if (k === 'gender') {
const code = res.data[k]
// console.log('我要回显性别:', code)
document.querySelector(`[value="${code}"]`).checked = true
} else {
const ele = document.querySelector(`[name=${k}]`)
if (ele) {
ele.value = res.data[k]
}
}
})
}
})
</script>
</body>
</html>
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。