Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I insert a django form in twitter-bootstrap modal window?

Someone has asked the exact same question in April, without any answer. But since he provided too little information; the question was abandoned.

I have the same problem. Within a main_page.html I have this line:

<a href="/contact/edit/{{ item.id }}" title="Edit">edit</a> 

Once you click there, the edit template shall appear inside a twitter bootstrap modal.

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) 

This is usually how the contact.html would look like:

        <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> 

I could put that inside a <div class="modal-body">. But then how do I open the modal from view?

like image 317
Houman Avatar asked Jun 30 '12 17:06

Houman


People also ask

How do I submit a bootstrap modal form?

You CAN include a modal within a form. In the Bootstrap documentation it recommends the modal to be a "top level" element, but it still works within a form. You create a form, and then the modal "save" button will be a button of type="submit" to submit the form from within the modal.

How do I use bootstrap modal plugins?

To invoke the modal window, you need to have some kind of a trigger. You can use a button or a link. Here we have used a button. If you look in the code above, you will see that in the <button> tag, the data-target = "#myModal" is the target of the modal that you want to load on the page.

How do I show a bootstrap modal inside a div?

To show a bootstrap modal inside a div the logic behind the above code is to append the HTML code of the modal as well as the modal-backdrop inside that specific div(blue div whose position is relative) and then making the CSS for modal and modal-backdrop to position:absolute so that the modal and its background gets ...


1 Answers

Unless you need to use the contact form outside of the modal, this should work for you. If you do need to use it elsewhere, maintain two versions (one modal, one not). Also, a tip - give django-crispy-forms a lookover - it helps you render forms with twitter-bootstrap classes.

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> 

Edit:

Ok, so now that I know that you have potentially multiple forms, it's probably a bad idea to render each form hidden within the html. You probably want to go to an ajax-y version, and load each form on demand. I'm assuming here that on form submit, the whole page will reload. If you want to asynchronously submit the form, there are answers elsewhere.

We'll start by re-defining the contact.html fragment. It should render within a modal, and contain all the markup necessary to play nice with the modal. The contact view that you have originally is fine - except that if the form is invalid, you'll end up rendering the contact.html and nothing else.

<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> 

And now, your 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> 

This is all untested, but it should give you a good place to start/iterate from.

like image 73
Josh Smeaton Avatar answered Sep 18 '22 03:09

Josh Smeaton