使用 bootstrap 和 django 的异步表单
Posted
技术标签:
【中文标题】使用 bootstrap 和 django 的异步表单【英文标题】:Asynchronous forms with bootstrap and django 【发布时间】:2012-10-05 23:03:40 【问题描述】:所以我试图使这种形式异步。理想情况下,我使用此表单添加单位,然后动态更新表格。我不希望整个页面刷新。我不太擅长 javascript,我可以使用一些指针来了解正在发生的事情:
发生了一些我不想发生的事情:
-
整个页面都在刷新
request.is_ajax() 为 False。
大多数情况下,我只是想了解发生了什么,但问题是,如何更改以下内容以解决上述两个问题? (如果它们是问题,那就是问题。)
以下部分代码取自这个问题:
How do I insert a django form in twitter bootstrap modal window?
作为记录,我在 request.POST 中看到帖子很好,我只是想让它异步工作,这就是我的问题与上述问题的不同之处。
% block scripts %
<script type="text/javascript">
$(document).ready(function()
modalConnect();
);
</script>
<script type="text/javascript">
$( document ).ajaxStop( function()
modalConnect();
);
</script>
<script type="text/javascript">
function modalConnect()
//unbind the click event. If not done we will end up with multiple click event bindings, since binding is done after each ajax call.
$(".editItem").unbind('click');
//bind the click event
$(".editItem").click(function(ev) // for each edit item <a>
ev.preventDefault(); // prevent navigation
var url = this.href; //get the href from the <a> element
$.get(url, function(results)
//get the form
var itemForm = $("#ajax_form_modal_result", results);
//get the update URL
var formUpdateURLDiv = $("#formUpdateURL", results);
//get the inner html of the div
var formUpdateURL = formUpdateURLDiv.html();
//update the dom with the received form
$('#inventory').html(itemForm);
//show the bootstrap modal
$("#inventory").modal('show');
$(document).ready(function ()
//bind the form to an ajax call. ajax call will be set to the received update url
submitItemModalFormBind(formUpdateURL);
);
, "html");
return false; // prevent the click propagation
)
</script>
<script type="text/javascript">
function submitItemModalFormBind(url)
//bind the form. prevent default behavior and submit form via ajax instead
$('#ajax_form_modal_result').submit(function(ev)
$.ajax(
type: "POST",
url: url,
data: $(this).serialize(),
success:function(response, textStatus, jqXHR)
var form = $("#ajax_form_modal_result_div", response);
//form is returned if it is not valid. update modal with returned form
//change this "if" to check for a specific return code which should be set in the view
if (form.html())
console.log('Form was invalid and was returned');
//update modal div
$('#ajax_form_modal_result_div').html(form);
$("#inventory").modal('show');
//form is not returned if form submission succeeded
else
//update the entire document with the response received since we received a entire success page and we want to reload the entire page
//sort by modified date descending
//var notificationDiv = $("#notification", response);
//$('#notification').html(notificationDiv.html());
console.log('Form was valid and was not returned');
$("#inventory").modal('hide');
,
error: function (request, status, error)
var div = $("ajax_form_modal_result_div", request.responseText);
$('#ajax_form_modal_result_div').html(div);
//implement proper error handling
console.log("failure");
console.log(request.responseText);
);
return false;
);
</script>
% endblock %
% block content %
<div class="row">
<div class="span8 offset4">
<div class="row">
<div class="span3">
<h1>
Acquisitions
</h1>
</div>
<div class="span3 offset2">
<h1>
<a id="editItem" href="#inventory" role="button" class="icon-plus-sign" data-toggle="modal"></a>
Add Units
</h1>
</div>
</div>
<table class="table table-hover table-striped">
<thead>
<tr>
<th>
lolcats
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
lolcats
</td>
</tr>
<tr>
<td>
test
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="modal hide fade" id="inventory" >
<form id="#ajax_form_modal_result" class="well" method="post" action="">
<div id="ajax_form_modal_result_div">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3>Add units</h3>
</div>
<div class="modal-body">
% csrf_token %
inventory.as_p
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
<input class="btn btn-primary" type="submit" value="Save" />
</div>
</div>
</form>
</div>
【问题讨论】:
【参考方案1】:由于缺乏 JS 经验,当我开始使用 Django 时,我在 AJAX 上苦苦挣扎。
我会给你一个我用来添加选项和显示选项的 aync 表单的例子。
我的模板模态代码如下,它可以与正在呈现的表单而不是我的懒惰硬编码 html 一起工作。
<div class="modal" id="AddOptions" style="display:none;">
<div class="modal-header">
<button class="close" data-dismiss="modal">X</button>
<h3>Add Options</h3>
</div>
<div class="modal-body">
<form id="OptionForm" action="." method='POST'>
<div id="OptionValueError" class="control-group">
<span class="help-inline"></span><br>
<br>Value <input type="text" name="OptionValue" id="id_OptionValue" /><br>Label <input type="text" name="OptionLabel" id="id_OptionLabel"/><input type="hidden" name="VariableID">
</div>
<div id="divid_OptionTable">
<table class="table table-condensed" id="OptionTable">
<thead>
<th>Value</th>
<th colspan="2">Label</th>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<div class="modal-footer">
<input type="submit" class="btn btn-primary" value="Add"> <button type="reset" class="btn">Reset</button>
</form>
</div>
</div>
接下来,请确保您有以下内容来处理 CSRF 令牌问题。
<script type="text/javascript">
jQuery(document).ajaxSend(function(event, xhr, settings)
function getCookie(name)
var cookieValue = null;
if (document.cookie && document.cookie != '')
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++)
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '='))
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
return cookieValue;
function sameOrigin(url)
// url could be relative or scheme relative or absolute
var host = document.location.host; // host + port
var protocol = document.location.protocol;
var sr_origin = '//' + host;
var origin = protocol + sr_origin;
// Allow absolute or scheme relative URLs to same origin
return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
(url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
// or any other URL that isn't scheme relative or absolute i.e relative.
!(/^(\/\/|http:|https:).*/.test(url));
function safeMethod(method)
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
if (!safeMethod(settings.type) && sameOrigin(settings.url))
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
);
</script>
其次,这是使用 jQuery 的基本 AJAX POST 的样子。请注意,它是基于防止我们模式中的表单的默认提交行为。成功后,我将新添加的值附加到表中。添加值作为捕获表单的一部分会不那么麻烦,但我希望确保在添加到表格之前所有内容都已保存和处理。
$(document).ready(function()
$("#OptionForm").submit(function(event)
event.preventDefault();
$.ajax(
type:"POST",
url:"% url builder.views.addoption %",
data: VariableID: $('input:hidden[name=VariableID]').val(), OptionLabel: $('input:text[name=OptionLabel]').val(), OptionValue: $('input:text[name=OptionValue]').val(),
success: function(data)
console.log(data['OptionID']);
$("#OptionValueError").removeClass("error");
$("#OptionValueError span").text("");
$("#OptionValueError span").removeClass("error");
$('#OptionTable > tbody:last').append('<tr id=Option_'+data['OptionID']+'><td>'+data['OptionValue']+'</td><td>'+data['OptionLabel']+'</td><td><a href="#" onClick="deleteOption('+data['OptionID']+')"><i class="icon icon-remove"></i></a>');
$('input:text[name=OptionValue]').val('');
$('input:text[name=OptionLabel]').val('');
);
);
);
最后,您只需要捕获此 AJAX 请求的视图,如下所示。
def addoption(request):
if request.is_ajax():
OptionValue = int(request.POST['OptionValue'])
OptionLabel = request.POST['OptionLabel']
VariableID = int(request.POST['VariableID'])
getVar = Variable.objects.get(id=VariableID)
newOption = Option(VariableID=getVar,
Value=OptionValue,
Label=OptionLabel)
newOption.save()
response = 'OptionValue': OptionValue, 'OptionLabel': OptionLabel, 'OptionID': newOption.id
json = simplejson.dumps(response)
return HttpResponse(json, mimetype="text/json")
else:
pass
我们正在 json 序列化的响应字典是作为数据反馈的,随后用于将值附加到表中。无需重新加载主页。
希望这个例子有所帮助。如果您还有其他问题,请告诉我。
京东
【讨论】:
我喜欢你的回答,但我的问题最终是一个非常愚蠢的错字,如果你看上面的一个 id 是 #ajax_form_modal_result 而它应该是 ajax_form_modal_result :/以上是关于使用 bootstrap 和 django 的异步表单的主要内容,如果未能解决你的问题,请参考以下文章
在本地使用 jQuery 和 Bootstrap for Django 不会响应
Django 和 Bootstrap:知道哪个选项卡处于活动状态