stark組件4_pop功能
阿新 • • 發佈:2018-08-17
viewport close att 是否 instance 參考 頁面 elm select pop功能模仿Django-Admin中添加頁面的pop功能
pop功能需要實現的功能和問題
1 如何在一對多和多對多字段後渲染 +
2 +對應的跳轉路徑是什麽
3 保存添加記錄同時,將原頁面的對應的下拉菜單中添加該記錄
具體實現(只在添加頁面實現功能)
添加頁面代碼邏輯(包含pop功能):
此處請參考ModleForm相關內容
def add(self, request): #ModelFormDemo等同於得到了DemoModelForm這個類 ModelFormDemo = self.get_modelForm() #實例化出來一個form對象 form = ModelFormDemo() #通過循環判斷沒有個字段類是否是判斷form對象是否是一對多或多對多,並做相應處理 for bfield in form: from django.forms.models import ModelChoiceField #ModelMultipleChoiceField繼承ModelChoiceField,因此一對多和多對多都是ModelChoiceField #如果當前對象是一對多或多對多 if isinstance(bfield.field, ModelChoiceField): #添加一個屬性,用於在模板中判斷是否渲染頁面時加上加號 bfield.is_pop = True # print("====>",bfield.field.queryset.model) # == == > < class ‘app01.models.Publish‘> # == == > < class ‘app01.models.Author‘> #獲取app名字和關聯表的名稱 related_model_name = bfield.field.queryset.model._meta.model_name related_app_lable = bfield.field.queryset.model._meta.app_label #利用反向解析找到url _url = reverse("%s_%s_add" % (related_app_lable, related_model_name)) # print(_url) # / stark / app01 / publish / add / # / stark / app01 / author / add / #構建url值,這個值要傳給模板用 bfield.url = _url+"?pop_res_id=id_%s" %bfield.name #bfield.url == > / stark / app01 / author / add /?pop_res_id = id_authors # 如果收到POST請求則修改數據 # 這裏有兩種情況,一種是通過pop添加數據,此時url帶有pop_res_id,一種是在查看頁面點添加,url裏是沒有pop_res_id的 if request.method == "POST": #將request.POST放到form中進行校驗 form = ModelFormDemo(request.POST) if form.is_valid(): obj = form.save() # print("obj==>", obj) #obj==> Django 第二版 # print("type==>", type(obj)) #type==> <class ‘app01.models.Book‘> #獲取(pop功能提交的post請求時)url中的pop_res_id值 pop_res_id = request.GET.get("pop_res_id") #如果此處有值就將數據返回給pop.html頁面 if pop_res_id: res = {"pk": obj.pk, "text": str(obj), "pop_res_id": pop_res_id} return render(request, "pop.html", {"res": res}) else: #如果此次無值則直接跳轉到相應頁面 return redirect(self.get_list_url()) # return redirect("/stark/app01/book/") return render(request, "add.html", locals())
添加頁面渲染(form.html)
<div class="container"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <form action="" method="post" novalidate> {% csrf_token %} {% for field in form %} <div style="position: relative" class="form-group"> <label for="">{{ field.label }}</label> {{ field }} <span class="error pull-right">{{ field.errors.0 }}</span> <!-- 下面判斷field是否有is_pop屬性為True --> <!-- 有的話就在輸入框後面添加一個加號,並綁定pop事件 --> {% if field.is_pop %} <a onclick="pop(‘{{ field.url }}‘)" style="position: absolute;right: -30px;top: 20px"><span style="font-size: 32px">+</span></a> {% endif %} </div> {% endfor %} <input type="submit" class="btn btn-default"> </form> </div> </div> </div> <!-- 點擊加號就觸發pop函數 --> <script> function pop(url) { // 打開一個獨立的添加窗口 window.open(url, "", "width=600,height=400,top=100,left=100") } </script>
pop頁面
<!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"> <title>Title</title> </head> <body> <script> // 觸發父頁面的pop_response函數,並且把參數傳過去 window.opener.pop_response(‘{{ res.pk }}‘, ‘{{ res.text }}‘, ‘{{ res.pop_res_id }}‘); // 之後立即關閉這個頁面 window.close() </script> </body> </html>
add頁面body示例代碼(是pop頁面的父頁面)
<body>
<h3>添加數據</h3>
{% include ‘form.html‘ %}
<script>
function pop_response(pk, text, id) {
// 選擇哪個select標簽
// option的文本值和value值
// 生成一個空的option標簽
var $option=$(‘<option>‘);
// 往option標簽中添加內容
$option.html(text);
$option.val(pk);
$option.attr("selected", "selected");
// 按id找位置,將標簽添加進去
$("#"+id).append($option)
}
</script>
</body>
stark組件4_pop功能