使用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對象
果然做了總結,才發現自己的路走的有點多