使用django和ajax制作修改功能的模态对话框
自学的小白总是挖坑给自己跳!如下图所示,我想制作修改的模态对话框,并点击修改的时候,原先的数据能够在模态对话框中显示,修改并保存,刷新页面!
设计思路:
- 首先,我要让点击每个修改的按钮都能弹出模态对话框,用for循环整一条td(当然循环之后只能点击第一行修改的按钮,这是可以用一个div包裹这个按钮的事件)
- 我的模态对话框里边要有原先页面的值,也就是可以用js拿到当前点击的那个按钮的上个div的title值,刚好就是用上边包裹的那个div,获取到之后用js添加到模态对话框的input框里边
- 我要获取模态对话框中修改前的内容发到后台,由后台找到原先的id传到前端(后来写这博客我才想起来,可以将修改前的title值保存赋值一下,然后修改后的将这两个值一起传递过去,再根据修改前的title获取到id再修改title,而我是将id值传递到后台再返回给前端,),咋就这么傻,小白又走远路
- 再找到模态对话框修改后的内容,和之前后台传递过来的id值一起传递到后台,由后台修改之后返回消息修改页面
这是模态对话框的代码以及按钮的代码
{#修改的模态对话框#}
<!-- Modal -->
<div class="modal fade" id="EditModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">修改职业方向</h4>
</div>
<div class="modal-body">
<input type="text" class="form-control" placeholder="", id="subject">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal" id="Close_Btn1">取消</button>
<button type="button" class="btn btn-primary" id="SavaBtn1">保存</button>
</div>
</div>
</div>
</div>
{#按钮#}
<table class="table table-hover" id="content_title">
{% for item in direction_list %}
<tr nid="{{ item.id }}">
<td>{{ item.title }}</td>
<td><a onclick="remove(this);" href="#">删除</a></td>
<td><div class="EditBtn" title="{{ item.title }}"><button class="btn btn-primary">修改</button></div></td>
{#这里使用div包裹着点击事件#}
{% endfor %}
</table>
下边是html的ajax代码
<script>
$(function () {
EditEvent();
});
{#修改#}
function EditEvent() {
$('.EditBtn').click(function () {
var tdArr = $(this)
title1 = tdArr.attr('title') {#拿到当前点击得那个按钮的div里边的title值#}
{#console.log(title1)#}
$('#EditModal').find('.modal-body').children().attr("value", title1); {# 添加到模态对话框的input里边 #}
$('#EditModal').modal('show');
var data = {};
data["subject"]=title1
var data_str = JSON.stringify(data) {#将字典转为字符串#}
{#定义一个json字符串#}
console.log(data) {# Object {subject: "python开发"}#}
console.log(data_str) {# {"subject":"python开发"} #}
$.ajax({
url: '/edit_direction.html',
type: 'POST',
data: data_str,
success:function (arg) {
$('#SavaBtn1').click(function () {
title_id = arg
var edit_title = $('#EditModal').find('input').val();
console.log(edit_title) {# python开发 #}
PostData = { title_id, edit_title }
{#title_id是数字,edit_title是中文#}
console.log(PostData) {# Object {title_id: "2", edit_title: "python开发"} #}
$.ajax({
url: '/edit1_direction.html',
type: 'POST',
data: {PostData,},
success:function (arg) {
if (arg=="ok"){
window.location.reload()
{#后台返回ok页面刷新一次#}
}
}
})
})
}
})
})
}
</script>
这是后台views.py代码
def edit_direction(request):
if request.is_ajax():
print("get ajax")
a = request.body
title_result = str(a, encoding="utf-8") #将前端发来的bytes类型转为str类型
print(title_result)
title_dic = eval(title_result) #注意将前端传来的str类型转为字典类型 {"subject":"PHP开发"}
title = title_dic["subject"]
#print(title) #输出字典对应的值
title_id_obj = models.Direction.objects.filter(title=title).first() #根据传来的title找出id返回给前端
title_id = title_id_obj.id
return HttpResponse(title_id)
#这是两个函数,第一个是前端发修改前的title,查询到id值返回给前端,第二个是将前端将id和修改后的title传到后台(后来才知道其实可以不用先传到后端获取id,可以将修改前的title赋值,在提交时一起提交,再根据修改前的title获取到id再修改title,这样就不用写两个函数)这里需要去url下添加url
def edit2_direction(request):
m1 = request.body #拿到前端ajax传来的数据
m = str(m1, encoding="utf-8") #将传来的bytes类型的数据转化为str类型
mm = urllib.parse.unquote(m) #将类似PostData%5Btitle_id%5D=30&PostData%5Bedit_title%5D=%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1得转编码为中文
q_title_id = re.findall('.*=(\d+)', mm) #通过正则表达式拿到前端传递得title和id
q_edit_title = re.match('.*=(.*)', mm)
title_id = q_title_id[0] #正则表达式拿出来的数字是一个列表形式的值
edit_title = q_edit_title.group(1) #正则表达式拿到第一个括号里边的值
models.Direction.objects.filter(id=title_id).update(title=edit_title)
#print(mm, title_id, edit_title) #PostData[title_id]=3&PostData[edit_title]=PHP开发 3 PHP开发
return HttpResponse("ok")
当我要循环遍历出每个修改按钮的时候,做ajax点击的时候,只能弹出一个,其余的无法弹出,因为在bootstrap里边模态对话框,使用同一个点击事件时,无法调用同一个模态框,以至于在这地方添加一个div包裹着
<td><div class="EditBtn" title="{{ item.title }}"><button class="btn btn-primary">修改</button></div></td>
$('.EditBtn').click(function () {
$('#EditModal').modal('show');
})
#这样全部的修改按钮就都能弹出模态对话框
接着获取我点击这个按钮时,获取到这个按钮的div包裹的那个title值,并在模态对话框弹出之前将title用js添加到模态对话框的input标签中的valul属性中
jqery添加元素
- append() - 在被选元素的结尾插入内容
- prepend() - 在被选元素的开头插入内容
- after() -在被选元素之后插入内容
- before() - 在被选元素之前插入内容
给元素添加属性可以用attr属性
$(selector).attr(attribute,value)
实例给div添加value的属性
$(‘div’).attr(“value”, title1);
function EditEvent() {
$('.EditBtn').click(function () {
var tdArr = $(this)
title1 = tdArr.attr('title') {#拿到当前点击得那个按钮的div里边的title值#}
{#console.log(title1)#}
$('#EditModal').find('.modal-body').children().attr("value", title1); {# 添加到模态对话框的input里边 #}
$('#EditModal').modal('show');
var data = {};
data["subject"]=title1
var data_str = JSON.stringify(data)
{#定义一个json字符串#}
console.log(data) {# Object {subject: "python开发"}#}
console.log(data_str) {# {"subject":"python开发"} #}
$.ajax({
url: '/edit_direction.html',
type: 'POST',
data: data_str,
success:function (arg) {
{#省略,上边已经有全部代码#}
}
})
})
}
这样在点击修改时就已经能在模态对话框中显示要修改的那一行数据,在这里我为什么还有将取到的前端的title值传到后台呢,这是因为我需要获取到这行数据的id,由后台处理好之后传递到前端,这样在下面做提交时,可以将id和title做个字典形式传递到后台,这里就不贴views的代码,可以上边看
主要问题是js在传递中文时,会进行两次的encodeURI将中文进行编码,在后台,可以用decodeURI,在python3中用的是unquote 进行解码,但是在python我们接受前端传来的数据时,都是bytes类型的数据,我们需要先转化为str的类型,例:==title_result = str(test, encoding=“utf-8”)==这样就能提取到我们需要用的数据
**
注:
**
当str需要转json时,需要保持最外层时大括号,里边是""包含的元素,不然会发生错误
如果有其它类型的需要转json,可以使用eval转为str类型,再进行转换
在python中:
字符串=json.dumps(json对象)------------>将json对象转为字符串
json对象=json.loads(字符串)------------->将字符串转为json对象
在javascript中:
字符串=JSON.stringify(json对象)---------------->将json对象转为字符串
json对象=JSON.parse(字符串)------------------->将字符串转为json对象
果然做了总结,才发现自己的路走的有点多