今日学习内容:ajax组件
用ajax组件实现弹出对话框添加工单
创建一个有添加按钮的界面,这个不再重复。
1.bootstrap对话框绑定到按钮上的两种方式
(1)用自带的参数
{% extends 'layout.html' %}
{% block content %}
<div class="container">
<input type="button" value="新建订单" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
// 使用input框的参数绑定弹出的对话框
</div>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">Modal title</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
{% endblock %}
(2)用js函数
{% extends 'layout.html' %}
{% block content %}
<div class="container">
<input id="btnAdd" type="button" value="新建订单" class="btn btn-primary">
</div>
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">Modal title</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
{% endblock %}
{% block js %}
<script type="text/javascript">
$(function(){
bindBtnAddEvent();
})
function bindBtnAddEvent(){
$('#btnAdd').click(function(){
//点击新建按钮,显示对话框
$('#myModal').modal('show');
});
}
</script>
{% endblock %}
2.在modal对话框中增加表单
<form id="formAdd" novalidate>
<div class="clearfix">
{% for field in form %}
<div class="col-sm-12">
<label class="form-label"> {{ field.label }} </label>
{{ field }}
<div class="error-msg" style="color: red;"> </div>
</div>
{% endfor %}
</div>
</form>
建立click的js函数接收数据和返回后端:
function bindBtnSaveEvent(){
$('#btnSave').click(function(){
//清空错误信息
$('.error-msg').empty();
//ajax函数
$.ajax({
url:'/order/add/',
type:'post',
data:$('#formAdd').serialize(),
dataType:'JSON',
success: function (res){
if (res.status){
alert("创建成功");
} else {
//把错误信息显示在对话框中
$.each(res.error, function(name, errorList){
$("#id_"+name).next().text(errorList[0]);
})
}
}
})
})
}
3.自动设置订单号并将数据保存到数据库
在views.py中进行如下修改:
from datetime import datetime
import random
@ csrf_exempt
def order_add(request):
""" 新建订单(ajax请求) """
form = OrderModelForm(data=request.POST)
if form.is_valid():
# 额外增加一些不是用户输入的值(自己计算出来)
# form.instance.oid = 'xxxxxxxx' # 用户提交时没有填写订单字段,后端自动生成oid字段
form.instance.oid = datetime.now().strftime("%Y%m%d%H%M%S") + str(random.randint(1000, 9999)) # 年月日时分秒
# 然后再将有了oid的字段全部存储到数据库中
form.save()
return JsonResponse({'status': True})
return JsonResponse({'status': False, 'error': form.errors})
设置管理员自动获取并存储到数据库:
class OrderModelForm(BootstrapModelForm):
class Meta:
model = models.Order
# fields = '__all__'
exclude = ('oid', 'admin') # 获取除了oid和admin以外的字段,这个字段由函数自动生成
def order_list(request):
form = OrderModelForm()
return render(request, 'order_list.html', {'form': form})
@ csrf_exempt
def order_add(request):
""" 新建订单(ajax请求) """
form = OrderModelForm(data=request.POST)
if form.is_valid():
# 额外增加一些不是用户输入的值(自己计算出来)
# 订单号:form.instance.oid = 'xxxxxxxx' # 用户提交时没有填写订单字段,后端自动生成oid字段
form.instance.oid = datetime.now().strftime("%Y%m%d%H%M%S") + str(random.randint(1000, 9999)) # 年月日时分秒
# 固定设置管理员ID
# form.instance.admin_id = '当前登录系统的管理员id'
# 当前的登陆者是谁,创建的id就是谁
form.instance.admin_id = request.session['info']['id']
# 然后再将有了oid的字段全部存储到数据库中
form.save()
return JsonResponse({'status': True})
return JsonResponse({'status': False, 'error': form.errors})
4.提交成功后清空数据内容
修改前端html:
function bindBtnSaveEvent(){
$('#btnSave').click(function(){
//清空错误信息
$('.error-msg').empty();
//ajax函数
$.ajax({
url:'/order/add/',
type:'post',
data:$('#formAdd').serialize(),
dataType:'JSON',
success: function (res){
if (res.status){
// alert("创建成功");
// 清空表单 $('#formAdd') 是jquery对象 -> $('#formAdd')[0] 是DOM对象 DOM对象可以置空
$('#formAdd')[0].reset(); // 取dom对象再清空
//关闭对话框
$('#myModal').modal('hide');
location.reload(); //添加成功页面自动刷新
} else {
//把错误信息显示在对话框中
$.each(res.error, function(name, errorList){
$("#id_"+name).next().text(errorList[0]);
})
}
}
})
})
}
5.对话框删除数据
修改前端html:
(原来的)
<a class="btn btn-primary btn-sm" href="#">编 辑</a>
<a class="btn btn-danger btn-sm" href="#">删 除</a>
修改后:
<a class="btn btn-primary btn-sm" href="#">编 辑</a>
<input uid="{{ obj.id }}" type="button" class="btn btn-danger btn-sm btn-delete" value="删除"> {# 自定义的class btn-delete 用于定位该标签 #}
对应的js函数:
function bindBtnDeleteEvent(){
$('.btn-delete').click(function(){
//显示删除对话框
$('#deleteModel').modal('show');
//获取当前行id并赋值给全局变量
DELETE_ID = $(this).attr("uid");
})
}
function bindBtnbtnConfirmDeleteEvent(){
$('#btnConfirmDelete').click(function(){
// 点击确认删除按钮,将全局变量中的uid发送到后台
$.ajax({
url: '/order/delete/', // => /order/delete/?uid=123
type:'GET',
data:{
uid: DELETE_ID
},
dataType: 'JSON',
success: function (res){
if (res.status){
// 删除成功
// alert('删除成功!')
// 关闭对话框
$('#myModal').modal('hide');
location.reload(); //添加成功页面自动刷新
}else{
// 删除失败
alert(res.error);
}
}
})
})
}
modal对话框(增加在界面任意位置均可)
<!-- 删除对话框 -->
<div class="modal fade" id="deleteModel" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="staticBackdropLabel">是否要删除?</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
请注意:删除后该用户关联信息均会删除!
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button id="btnConfirmDelete" type="button" class="btn btn-danger">确认删除</button>
</div>
</div>
</div>
</div>
后端处理删除的数据,增加views.py的函数:
def order_delete(request):
""" 删除订单 """
uid = request.GET.get('uid')
exist = models.Order.objects.filter(id=uid).exists()
if not exist:
return JsonResponse({'satus': False, 'error': '删除失败,数据不存在!'})
models.Order.objects.filter(id=uid).delete()
return JsonResponse({'status': True})
5.编辑数据
1.复用新建的模态对话框:
修改编辑按钮,然后为编辑按钮绑定事件;
function bindBtnEditEvent(){
$('.btn-edit').click(function (){
var uid = $(this).attr('uid');
EDIT_ID = uid;
//发送ajax请求去后端获取当前行的相关数据
$.ajax({
url: '/order/detail/', // => /order/detail/?uid=123
type:'GET',
data:{
uid: uid
},
dataType: 'JSON',
success: function (res){
if (res.status){ //如果有数据再显示弹窗
//将数据复制到对话框的标签中
$.each(res.data, function (name, value){
$('#id_' + name).val(value); //赋值
})
//修改对话框的标题
$('#exampleModalLabel').text('编辑订单');
//点击编辑按钮,显示对话框
$('#myModal').modal('show');
}else{
// 删除失败
alert(res.error);
}
}
})
})
}
由于这里直接复用了新建的modal,所以需要修改新建按钮的事件函数:
var EDIT_ID;
$(function(){
bindBtnAddEvent();
bindBtnSaveEvent();
bindBtnDeleteEvent();
bindBtnConfirmDeleteEvent();
bindBtnEditEvent();
})
function bindBtnAddEvent(){
$('#btnAdd').click(function(){
//将正在编辑的ID设置为空
EDIT_ID = undefined;
//新建之前清空对话框
$('#formAdd')[0].reset();
//修改对话框的标题
$('#exampleModalLabel').text('新建订单')
//点击新建按钮,显示对话框
$('#myModal').modal('show');
});
}
function bindBtnSaveEvent(){
$('#btnSave').click(function(){
//清空错误信息
$('.error-msg').empty();
//判断edit_id的值
if (EDIT_ID) {
//编辑
doEdit();
}else{
//添加
doAdd();
}
})
}
function doAdd(){
//ajax函数(添加的ajax请求)
$.ajax({
url:'/order/add/',
type:'post',
data:$('#formAdd').serialize(),
dataType:'JSON',
success: function (res){
if (res.status){
// alert("创建成功");
// 清空表单 $('#formAdd') 是jquery对象 -> $('#formAdd')[0] 是DOM对象 DOM对象可以置空
$('#formAdd')[0].reset(); // 取dom对象再清空
//关闭对话框
$('#myModal').modal('hide');
location.reload(); //添加成功页面自动刷新
} else {
//把错误信息显示在对话框中
$.each(res.error, function(name, errorList){
$("#id_"+name).next().text(errorList[0]);
})
}
}
})
}
function doEdit(){
//ajax函数
$.ajax({
url:'/order/edit/' + '?uid=' + EDIT_ID,
type:'post', //用get方式提交
data:$('#formAdd').serialize(),
dataType:'JSON',
success: function (res){
if (res.status){
// alert("创建成功");
// 清空表单 $('#formAdd') 是jquery对象 -> $('#formAdd')[0] 是DOM对象 DOM对象可以置空
$('#formAdd')[0].reset(); // 取dom对象再清空
//关闭对话框
$('#myModal').modal('hide');
location.reload(); //添加成功页面自动刷新
} else {
if (res.tips){
alert(res.tips)
} else{
//把错误信息显示在对话框中
$.each(res.error, function(name, errorList){
$("#id_"+name).next().text(errorList[0]);
})
}
}
}
})
}
后端的views文件接收函数:
@ csrf_exempt
def order_edit(request):
""" 编辑订单 """
uid = request.GET.get('uid') # uid不存在,提示数据不存在
row_object = models.Order.objects.filter(id=uid).first()
if not row_object:
return JsonResponse({'satus': False, 'tips': '操作失败,数据不存在,请刷新重试!'})
form = OrderModelForm(data=request.POST, instance=row_object)
if form.is_valid():
form.save()
return JsonResponse({'status': True})
return JsonResponse({'status': False, 'error': form.errors}) # 这是前端校验的错误提示