Как вставить форму django в модальное окно twitter-bootstrap?
Кто-то задал точный тот же вопрос в апреле, без какого-либо ответа. Но поскольку он предоставил слишком мало информации; вопрос был оставлен.
У меня та же проблема. В пределах main_page.html
у меня есть эта строка:
<a href="/contact/edit/{{ item.id }}" title="Edit">edit</a>
После того, как вы нажмете там, шаблон редактирования появится внутри твитер-бутстрапа.
url.py
(r'^contact/edit/(?P<contact_id>\d+)/$', contact_view),
view.py
def contact_view(request, contact_id=None):
profile = request.user.get_profile()
if contact_id is None:
contact = Contact(company=profile.company)
template_title = _(u'Add Contact')
else:
contact = get_object_or_404(profile.company.contact_set.all(), pk=contact_id)
template_title = _(u'Edit Contact')
if request.POST:
if request.POST.get('cancel', None):
return HttpResponseRedirect('/')
form = ContactsForm(profile.company, request.POST, instance=contact)
if form.is_valid():
contact = form.save()
return HttpResponseRedirect('/')
else:
form = ContactsForm(instance=contact, company=profile.company)
variables = RequestContext(request, {'form':form, 'template_title': template_title})
return render_to_response("contact.html", variables)
Обычно это выглядит как contact.html:
<form class="well" method="post" action=".">
{% csrf_token %}
{{form.as_p}}
<input class="btn btn-primary" type="submit" value="Save" />
<input name="cancel" class="btn" type="submit" value="Cancel"/>
</form>
Я мог бы разместить это внутри <div class="modal-body">
.
Но как мне открыть модальный вид?
Ответы
Ответ 1
Если вам не нужна форма контакта вне модальности, это должно сработать для вас. Если вам нужно использовать его в другом месте, поддерживайте две версии (один модальный, один нет). Кроме того, подсказка - дайте django-crispy-forms просмотр - это поможет вам визуализировать формы с помощью классов twitter-bootstrap.
contact.html:
<div class="modal hide" id="contactModal">
<form class="well" method="post" action="/contact/edit/{{ item.id }}">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h3>Editing Contact</h3>
</div>
<div class="modal-body">
{% csrf_token %}
{{form.as_p}}
</div>
<div class="modal-footer">
<input class="btn btn-primary" type="submit" value="Save" />
<input name="cancel" class="btn" type="submit" value="Cancel"/>
</div>
</form>
</div>
main_page.html
<html>
...
<a data-toggle="modal" href="#contactModal">Edit Contact</a>
{% include "contact.html" %}
...
</html>
Изменить:
Хорошо, теперь, когда я знаю, что у вас есть потенциально несколько форм, вероятно, это плохая идея, чтобы каждая форма была скрыта в html. Вероятно, вы захотите перейти к версии ajax-y и загрузите каждую форму по требованию. Я предполагаю, что при отправке формы вся страница перезагрузится. Если вы хотите асинхронно отправить форму, есть ответы в другом месте.
Начнем с повторного определения фрагмента contact.html
. Он должен визуализироваться в рамках модальности и содержать всю разметку, необходимую для игры с модальным. Представление contact
, которое вы изначально прекрасно, за исключением того, что если форма недействительна, вы получите рендеринг contact.html
и ничего больше.
<form class="well contact-form" method="post" action="/contact/edit/{{ item.id }}">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h3>Editing Contact</h3>
</div>
<div class="modal-body">
{% csrf_token %}
{{form.as_p}} <!-- {{form|crispy}} if you use django-crispy-forms -->
</div>
<div class="modal-footer">
<input class="btn btn-primary" type="submit" value="Save" />
<input name="cancel" class="btn" type="submit" value="Cancel"/>
</div>
</form>
И теперь ваш main_page.html
:
<html>
.. snip ..
<a class="contact" href="#" data-form="/contact/edit/{{ item.id }}" title="Edit">edit</a>
<a class="contact" href="#" data-form="/contact/edit/{{ item.id }}" title="Edit">edit</a>
<a class="contact" href="#" data-form="/contact/edit/{{ item.id }}" title="Edit">edit</a>
<div class="modal hide" id="contactModal">
</div>
<script>
$(".contact").click(function(ev) { // for each edit contact url
ev.preventDefault(); // prevent navigation
var url = $(this).data("form"); // get the contact form url
$("#contactModal").load(url, function() { // load the url into the modal
$(this).modal('show'); // display the modal on url load
});
return false; // prevent the click propagation
});
$('.contact-form').live('submit', function() {
$.ajax({
type: $(this).attr('method'),
url: this.action,
data: $(this).serialize(),
context: this,
success: function(data, status) {
$('#contactModal').html(data);
}
});
return false;
});
</script>
.. snip ..
</html>
Это все непроверено, но оно должно дать вам хорошее место для запуска/повторения.
Ответ 2
У меня была такая же проблема, когда я столкнулся с этим сообщением. Я пробовал это решение, но на самом деле это не работало для меня (но это дало мне направление). Я придумал решение, которое работает для меня, но оно чувствует себя взломанным, и я хотел бы получить некоторые указания о том, как сделать это лучше.
Проблема такая же: покажите форму внутри twitter boostrap modal и django form (редактируйте/добавьте модель для меня, используя общие представления формы django)
Итак, что я сделал:
main.html
<script type="text/javascript">
function genericLoadDialog(form_selector, dialog_selector, matchString){
$.ajax({
url: $(form_selector).attr('action'),
type: 'POST',
data: $(form_selector).serialize(),
success: function(data, textStatus, jqXHR){
if(data.match(matchString)){
// We got errors in form
$(dialog_selector).html(data).modal('show');
return false;
}
$(dialog_selector).modal('hide');
},
})
}
</script>
<body>
<div class="modal hide" id="{{ editor_dialog_id }}"></div>
<a data-toggle="modal" href="#{{ editor_dialog_id }}" onclick="$('#{{ editor_dialog_id }}').load('/create/form');">Title</a>
<body>
editor.html
<form id="{{ editor_form_id }}" action="{{ submit_url }}" method="POST">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h3>Modal header</h3>
</div>
<div class="modal-body" id="editor-dialog-body">
{% if not form.is_valid %}
<div class='hide'>invalid_form</div>
{% endif %}
{% csrf_token %}
{{ form.as_p }}
</div>
<div class="modal-footer">
<a href="#" class="btn" data-dismiss="modal">Cancel</a>
<a href="#" data-toggle="modal" class="btn btn-primary" onclick="genericLoadDialog('#{{ editor_form_id }}', '#{{ editor_dialog_id }}', null, 'invalid_form');">Save</a>
</div>
</form>
Итак, поток таков:
- Нажмите на тег, загрузив форму из формы формы формы в модальный div
- нажмите кнопку сохранения в модальном (submit), который запускает функцию genericLoadDialog. Эта загрузка делает запрос POST для URL-адреса формы с данными, собранными из формы
- Если форма недействительна, она перезагружает модальный html и показывает поля ошибки, иначе закрывает модальный, а django должен сохранять/перенаправлять (я использую метод get_success_url в представлении формы django, но почему-то не работает для меня. объект)
Мне неудобно с тем, как я проверяю, является ли форма действительной или нет в genericLoadDialog, если кто-то лучше понимает, было бы хорошо.