如何使用无效的 Django 表单跳转到锚点?
Posted
技术标签:
【中文标题】如何使用无效的 Django 表单跳转到锚点?【英文标题】:How to jump to anchor with invalid Django form? 【发布时间】:2012-11-26 07:03:50 【问题描述】:当我的 Django 表单验证失败时,它会自动返回表单失败的页面,但我希望它转到页面上的 html 锚点。这是我的代码:
def detail(request, post_id):
p = get_object_or_404(Post, pk=post_id)
# get all the comments for the post
comments = p.comment_set.all().order_by('pub_date')
# to add a comment to the post
if request.method=='POST':
form = CommentForm(request.POST)
if form.is_valid():
c = Comment()
c.body = request.POST['body']
c.post = p
c.save()
return HttpResponseRedirect(reverse('journal.views.detail', kwargs='post_id': post_id) + "#comment-" + str(c.id))
else:
form = CommentForm()
return render(request, 'posts/detail.html', 'post': p, 'comments': comments, 'form': form)
该表单是博客文章底部的评论表单。当表单无效时,我希望它跳转到页面底部的评论表单的 html 锚点。现在它转到页面顶部,您必须向下滚动才能注意到有错误。
我尝试了一些不起作用的方法。请帮忙!
【问题讨论】:
【参考方案1】:我认为这很公平:
<script>
function goToId()
if (!window.location.hash) window.location = window.location + '#your-id';
% if form.is_bound %
$(window).on("load", goToId);
% endif %
</script>
【讨论】:
【参考方案2】:一种方法是在 dict 中传递一个额外的键值对来包含锚名称,并在需要时使用模板中的 javascript 跳转到它。
Python 方面:
// ...
return render(request,
'post/detail.html',
// ...
'anchor': 'comment'
)
模板:
function goToOnLoadAnchor()
window.location.hash(' anchor '); // Or something with the same effect
% ... %
<body onload="goToOnLoadAnchor">
% ... %
您还可以利用自定义模板标签来增加灵活性。
【讨论】:
【参考方案3】:CBV 和 jQuery
>表单视图
def form_invalid(self, form):
return self.render_to_response(self.get_context_data(form=form, anchor='my-form'))
模板
<form ... id='my-form'> ... </form>
<script>
$(function ()
% if anchor %
$(document.body).animate(
'scrollTop': $('# anchor ').offset().top
, 2000);
% endif %
);
</script>
使用 jQuery 进行滚动(而不是跳跃)。
【讨论】:
【参考方案4】:使用原生 JavaScript:
% if form.is_bound %
<script>
document.addEventListener("DOMContentLoaded", function ()
document.getElementById("your_id").scrollIntoView();
);
</script>
% endif %
它适用于addEventListener("DOMContentLoaded")
监听器。否则会产生一些奇怪的结果。
【讨论】:
以上是关于如何使用无效的 Django 表单跳转到锚点?的主要内容,如果未能解决你的问题,请参考以下文章