我想让我的用户写内容,我希望他们指定他们想要拥有的标题的部分。我已经创建了一个小的Javascript函数来将新元素插入到将要提交的现有表单中。目前看起来像这样:
openTextarea.js
var i = 1;
function opentextarea() {
"use strict";
var hr = document.createElement('hr');
var title = document.createElement('input');
title.type = 'text';
title.name = 'title_'+i;
title.placeholder = 'Your section title!';
title.className = 'form-control';
var input = document.createElement('textarea');
input.name = 'section_'+i;
input.className = 'tiny-mce-init';
var button = document.createElement('button');
var newSection = document.getElementById('newSection');
var form = document.getElementById('guide_form');
form.appendChild(hr);
form.appendChild(title);
form.appendChild(input);
loadTinyMCEEditor();
i++;
}
模板
{% extends "base.html" %}
{% load staticfiles %}
{% block body %}
<script type="text/javascript" src="{% static "tinymce/js/tinymce/tinymce.min.js" %}"></script>
<script type="text/javascript" src="{% static "javascripts/openTextarea.js" %}"></script>
<script type="text/javascript" src="{% static "javascripts/loadTinyMCEEditor.js" %}"></script>
<div style="width: 60%; margin: 0 auto;">
<hr>
<form id="guide_form" class="form-horizontal" method="POST" action="{{ request.get_full_path }}"> {% csrf_token %}
<fieldset>
{% if form.title.errors %}
<div class="class-group error">
<div class="controls">{{ field }}
<span class="help-inline">
{% for error in form.title.errors %}{{ error }}{% endfor %}
</span>
</div>
</div>
{% else %}
<div class="control-group">
<div class="controls">{{ form.title }}</div>
</div>
{% endif %}
<hr>
{% if form.public.errors %}
<div class="class-group error">
<div class="controls">Check, if you want to make your guide public {{ field }}
<span class="help-inline">
{% for error in form.public.errors %}{{ error }}{% endfor %}
</span>
</div>
</div>
{% else %}
<div class="control-group">
<div class="controls">Check, if you want to make your guide public {{ form.public }}</div>
</div>
{% endif %}
<hr>
Neutral cards
<hr>
{% for card in form.cards %}
{{ card }}
{% endfor %}
<hr>
</fieldset>
</form>
<hr>
<div id="newSection"></div>
<button class="btn btn-primary" type="button"
onclick="opentextarea();">
Add Section!
</button>
<hr>
<div class="form-actions" style="margin-top: 4px;">
<button type="submit" form="guide_form" class="btn btn-success">Submit</button>
</div>
</div>
{% endblock %}
当我检查元素时,新部分会出现在表单中。
显然新部分不在form.cleaned_data
中,因为当我打印出来时,我只是收到我最初使用表单创建的字段:
class CreateGuide(FormView):
template_name = 'hsguides/guide_create.html'
form_class = GuideForm
success_url = '/guides/search-guide/'
def get_form_kwargs(self, *args, **kwargs):
form_kwargs = super(CreateGuide, self).get_form_kwargs(**kwargs)
form_kwargs['hero'] = self.kwargs['hero']
return form_kwargs
def form_valid(self, form, *args, **kwargs):
# TODO
# - check if cards are actually from selected class...
# - implement sections
form.instance.author = self.request.user
form.instance.hero = Hero.objects.get(name=self.kwargs['hero'])
dust = 0
for card in form.cleaned_data['cards']:
dust += Card.objects.get(id=card.id).dust
for foo in form.cleaned_data:
print(foo)
form.instance.dust = dust
form.save()
return super(CreateGuide, self).form_valid(form)
结果
卡
公共
标题
这是有道理的,因为我的表单看起来像这样
class GuideForm(BootstrapModelForm):
class Meta:
model = Guide
exclude = ('author', 'created', 'modified', 'hero', 'dust', 'rating',)
def __init__(self, *args, **kwargs):
hero = kwargs.pop('hero', None)
super(GuideForm, self).__init__(*args, **kwargs)
if hero:
self.fields['cards'].queryset = Card.objects.filter(Q(card_class='neutral') |
Q(card_class=hero))
self.fields['title'].widget.attrs['placeholder'] = 'Title of your awesome guide!'
self.fields['public'].widget.attrs.update({'class': 'checkbox'})
如何在django中动态地将新元素添加到表单中?任何帮助或建议高度赞赏!
答案 0 :(得分:3)
您可以在调用super之后添加它们。
class GuideForm(BootstrapModelForm):
class Meta:
model = Guide
exclude = ('author', 'created', 'modified', 'hero', 'dust', 'rating',)
def __init__(self, *args, **kwargs):
hero = kwargs.pop('hero', None)
super(GuideForm, self).__init__(*args, **kwargs)
# add your fields here
self.fields['title_1'] = forms.CharField()