Forms in Bootstrap 4 Modals?

266 views
Skip to first unread message

Alexander Joseph

unread,
Jun 19, 2018, 3:08:59 PM6/19/18
to Django users
I've posted this before but havent gotten any response. If more information is needed let me know and I'll get you anything I can.

I basically want to use forms in Bootstrap 4 modals for my CRUD operations but cant really find a good tutorial or references to work from. I'm newer to Django still. I'm sure this is a common question/application so theres got to be some material out there that can help a novice like me. Has anyone had some success with implementing this? I'm using CBVs so something that works with CBVs would be ideal. Any help, advice, or suggestions would be much appreciated

C. Kirby

unread,
Jun 19, 2018, 4:26:59 PM6/19/18
to Django users
What do you seem to be having trouble with?

-Showing the form in a modal?
-Dynamically loading a form based on how the modal is launched?
-Using the modal to handle ajax loaded/submitted forms?
-Generally building abootstrap4 modal?

I have done this and am happy to help, just give me some direction in helping you

Alexander Joseph

unread,
Jun 19, 2018, 5:13:19 PM6/19/18
to django...@googlegroups.com
Thanks very much!

I've followed a few tutorials and had mixed results - 

This tutorial I got the closest with

I got to the point where it says " The data was invalid. No hard refresh no anything. Just this tiny part changed with the validation. This is what happened:"

I was able to get the form to load in the modal via ajax and the form information submitted and the database updated with the new record, however upon submission it would just show the ajax in a blank page rather than just close the modal and show the updated table with the information. Also when you submit the form and its invalid it will show the blank page with ajax code rather than the validation errors in the modal. I'd much rather be using CBVs though and this tutorial was for FBVs. Being such a noob it would be another project altogether to turn the FBVs into CBVs and still get it to work.

I've tried other tutorials like this one 

I liked this one best because it uses CBVs and Bootstrap4, but I could never even get the form to load in the modal. I checked the Javascript Console and everything seemed to be fine - no missing files or errors related to the modal or functioning of the modal so I'm not sure where the problem was but this is my main problem right now - getting the form to even show in the modal to begin with. It seems like most of these tutorials use jquery/ajax to load the html form file in the modal content, is that the way you did it as well?

Is there a tutorial or reference you used to get it working for you? 
If it would be easiest I can go through this tutorial again 
and give you any errors I get, if that tutorial looks like it will work to you. In the comments it seems like theres a lot of people that had the same issue I was running into with that one though.

Thanks again for your help!



--
You received this message because you are subscribed to a topic in the Google Groups "Django users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/django-users/CPspzgE33Dk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/ac24306b-96d0-4eaa-ba23-3fedfa0a48ae%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Best Regards,

Alexander Joseph

C. Kirby

unread,
Jun 20, 2018, 12:28:40 PM6/20/18
to Django users
Ok, great. I am more versed with FBVs than CBVs, but if you are doing a one form trial run I can figure it out.

It sounds like you are correctly rendering javascript to the client when they do a GET for the form, but when they do a POST (either correct or with validation errors) you are returning an HttpResponse, which will redirect to a new page. (It could be something different, but that is my first guess) .
It would be easiest to debug with you if I could see the code, could you share it here, or even better on a public code repository (github, gitlab, bitbucket, etc). If you can share the code I am happy to work with you on either tutorial.

I'm sorry, I don't have any tutorials to point to - I've been doing this for a long time and just pieced it together from the underlying components.

Kirby
To unsubscribe from this group and all its topics, send an email to django-users...@googlegroups.com.

To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.

Alexander Joseph

unread,
Jun 20, 2018, 12:49:19 PM6/20/18
to django...@googlegroups.com
No problem! Thanks so much for your help, I've been struggling with this for longer than I'd like to say and havent been able to find any help.

Since I'm using a lot of mixins that I'd like to use with this view I'll work my way through the CBV-based tutorial up until the spot where I'm having the trouble, and then start a new github repo for this and give you access here soon

Thanks again!

To unsubscribe from this group and all its topics, send an email to django-users+unsubscribe@googlegroups.com.

To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.

For more options, visit https://groups.google.com/d/optout.

Alexander Joseph

unread,
Jun 20, 2018, 4:25:07 PM6/20/18
to Django users
Actually on second thought, since this is a private github repo and theres a lot of stuff in there i wouldnt want to make public, copying it/cleaning it up to make it a public repo would be a bit of an ordeal so I'll just post my code here.

So going through this tutorial - 

below is my url

url(r'^gaas-wafer-designs/create/$', gaas_wafer_designs.GaasWaferDesignCreateView.as_view(), name='gaas_wafer_design_create'),


below is my view

class GaasWaferDesignCreateView(LoginRequiredMixin, CreateView):
    fields = ("design_ui", "emitting", "contact_location", "optical_power", "design_date", "designer", "design_document", "designer_ui", "in_trash", "inactive_date", "notes")
    model = GaasWaferDesign
    template_name = 'engineering/gaas_wafer_designs/gaas_wafer_design_form_inner.html'

    def form_valid(self, form):
        self.object = form.save()
        return render(self.request, 'engineering/gaas_wafer_designs/create_success.html', {'gaas_wafer_designs': self.object})


and below is my gaas_wafer_design_list.html (the template with the modal frame and modal button along with the jquery to handle the ajax) -

{% extends "pages/list_template.html" %}{% load static from staticfiles %}
{% load widget_tweaks %}

{% block title %}GaAs Wafer Design List{% endblock %}
{% block list_title %}GaAs Wafer Designs{% endblock %}
{% block list_title_2 %}Design Inventory{% endblock %}

{% block extra_js%}
{% endblock %}

{% block buttons %}
  <div class="btn-group" role="group" aria-label="Button group with nested dropdown" style="margin-bottom: -150px; z-index:1000;">
      <!--<a class="btn btn-secondary js-create"><i class="fa fa-plus-circle fa-fw"></i> Add GaAs Wafer Design</a>-->
      <div class="btn-group" role="group">
        <a id="btnGroupDrop1" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            View
        </a>
        <div class="dropdown-menu" aria-labelledby="btnGroupDrop1">
            <a class="dropdown-item" href="#">Recycling Bin</a>
        </div>
      </div>
  </div>
  <p>Click <a data-toggle="modal" data-target="#modal" href="{% url 'engineering:gaas_wafer_design_create' %}">here</a> to show the modal</p>
  <div class="modal fade" id="modal"></div>
{% endblock %}

{% block table %}
  <thead>
      <tr>
          <th>
              Wafer Design UI
          </th>
          <th>
              Emitting Type
          </th>
          <th>
              Contact Location
          </th>
          <th>
              Optical Power
          </th>
          <th>
              Design Date
          </th>
          <th>
              Designer
          </th>
          <th>
              Designer UI
          </th>
          <th>
              Created At
          </th>
      </tr>
  </thead>
  <tfoot>
      <tr>
          <th>
              Wafer Design UI
          </th>
          <th>
              Emitting Type
          </th>
          <th>
              Contact Location
          </th>
          <th>
              Optical Power
          </th>
          <th>
              Design Date
          </th>
          <th>
              Designer
          </th>
          <th>
              Designer UI
          </th>
          <th>
              Created At
          </th>
      </tr>
  </tfoot>
  <tbody>
      {% for gaas_wafer_design in gaas_wafer_designs %}
      <tr>
          <td><a href="{% url 'engineering:gaas_wafer_design_detail' pk=gaas_wafer_design.pk %}">{{ gaas_wafer_design.design_ui }}</a></td>
          <td>{{ gaas_wafer_design.get_emitting_display }}</td>
          <td>{{ gaas_wafer_design.contact_location }}</td>
          <td>{{ gaas_wafer_design.optical_power }}</td>
          <td>{{ gaas_wafer_design.design_date|date:"m/d/y" }}</td>
          <td>{{ gaas_wafer_design.designer }}</td>
          <td>{{ gaas_wafer_design.designer_ui }}</td>
          <td>{{ gaas_wafer_design.created_at }}</td>
      </tr>
      {% endfor %}
  </tbody>

  <script>
    $('#modal').on('show.bs.modal', function (event) {
        var modal = $(this)
        $.ajax({
            url: "{% url 'engineering:gaas_wafer_design_create' %}",
            context: document.body
        }).done(function(response) {
            modal.html(response);
        });
    })
  </script>
{% endblock %}
{% block modal %}

{% endblock %}


below is my gaas_wafer_design_form.html (the modal content/form) - 

{% load i18n widget_tweaks %}
<div class="modal-dialog modal-lg" role="document">
    <form action="{% url 'engineering:gaas_wafer_design_create' %}" method="post" id="gaas-create" class="form">{% csrf_token %}
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">×</span>
                    <span class="sr-only">Close</span>
                </button>
                <h4 class="modal-title">Add News</h4>
            </div>
            <div class="modal-body">
                Test
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                <input type="submit" class="btn btn-primary" value="Save changes" />
            </div>
        </div><!-- /.modal-content -->
    </form>
</div><!-- /.modal-dialog -->
<script>
    var form_options = { target: '#modal', success: function(response) {} };
    $('#gaas-create').ajaxForm(form_options);
</script>


below is my create_success.html

<div class="modal-dialog modal-lg" role="document">
    <div class="modal-content">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                <span aria-hidden="true">×</span>
                <span class="sr-only">Test</span>
            </button>
            <h4 class="modal-title">Test</h4>
        </div>
        <div class="modal-body">
            <p class="alert alert-info">Succesfully created!</p>
        </div><!-- /.modal-body -->
     </div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
<script>
    // close the modal after 3 seconds
    setTimeout(function() {
        $('#modal').modal('hide');
    }, 3000);
</script>


The first problem I'm running into with this is when I click on the link to show the modal the screen darkens from the modal fade but no modal shows up at all. I checked the javascript console (see below) and it doesnt look like anything is missing. I'm thinking its probably somewhere in the ajax thats messed up

Thanks again

C. Kirby

unread,
Jun 21, 2018, 12:12:41 PM6/21/18
to Django users
Ok, this is good to work with. Let us tackle this issue by issue. The first issue is that your modal is not showing up. I see several possible issues:

Replace
  <p>Click <a data-toggle="modal" data-target="#modal" href="{% url 'engineering:gaas_wafer_design_create' %}">here</a> to show the modal</p>
 with

<button data-toggle="modal" data-target="#modal" %}">Create a new wafer design</button>

Having the href in the a tag makes it want to load to a new page, but also load the modal, I think. Since you reference the form url in the ajax call you don't need it in an a tag. Also in the bootstrap4 api reference it only launches modals from buttons, not from <a> tags

Next/if that doesn't get you a further I would check to make sure teh modal structure is correct before worrying about the ajax call.
 
Put the contents of the gaas_wafer_design_form.html into the modal in gaas_wafer_design_list.html. Remove the form elements and just have a complete, static bootstrap modal on the page. Also comment out the on(show.bs.modal). Noting the date on the tutorial it looks like it might be using an alpha or beta version of bootstrap4. If you can't get a static modal to show up this way then you will have to go take a look at the bootstrap4 api and match the modal structure.

If you have the same/new issues after trying those we can tackle them next

Kirby

Alexander Joseph

unread,
Jun 21, 2018, 12:23:58 PM6/21/18
to django...@googlegroups.com
Awesome! Thanks Kirby, I will try that out and let you know

--
You received this message because you are subscribed to a topic in the Google Groups "Django users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/django-users/CPspzgE33Dk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to django-users+unsubscribe@googlegroups.com.

To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.

For more options, visit https://groups.google.com/d/optout.

Melvyn Sopacua

unread,
Jun 21, 2018, 3:04:15 PM6/21/18
to django...@googlegroups.com

I have a lot of this stuff worked out, but for Bootstrap 3. I've done this in a UX library I've used for various projects, so it's kinda of a need-driven collection of widgets, CBV's and form components - not exactly something for general use.

 

I've made it available on Gitlab, so you can see how you add various modals to a single view. In my case I mostly used a context menu to launch the modals, but I never bothered with the Ajax part, instead the forms get submitted normally, generating a page reload. That part you have to do yourself, but there's a lot in there you can build on:

 

- Wrapper for a Form

- Mixins to handle addtional forms

- Template tags to render a bootstrap 3 modal

- etcetera...

 

 

And here's an example of a view from a project management tool that I wrote with it:

 

class ProjectDetailView(DefaultPageMixin, AdditionalFormsMixin,

ContextMenuMixin, generic.DetailView):

model = models.Project

context_object_name = 'project'

template_name = 'view/project.html'

 

def generate_context_menu(self) -> None:

self.add_active_menu_link('view_project', _('View Project'), icon='eye')

self.add_context_menu_modal(

'edit_project', _('Edit Project'), 'edit-project', icon='pencil',

title=_('Edit current project')

)

self.add_context_menu_modal(

'add_task', _('Add Milestone'), 'add-task', icon='plus-square',

)

 

def generate_additional_forms(self):

proj_update_url = reverse('core:project_edit',

kwargs={'slug': self.object.slug})

task_create_url = reverse('core:project_task_create')

self.add_additional_form(

'project_update_form', forms.ProjectForm, proj_update_url,

model_instance=self.object,

)

self.add_additional_form(

'add_milestone_form', forms.NewProjectTaskForm, task_create_url,

initial={'project': self.object, 'is_milestone': True},

)

 

def get_context_data(self, **kwargs):

context = super().get_context_data(**kwargs)

del context['object']

project = self.object # type: models.Project

context['has_milestones'] = project.has_milestones

context['milestones'] = project.milestones.order_by('sequence', 'title')

 

return context

 

I may clean up the library for more general use, but in the mean time, hope this helps you along with your quest.

> > To post to this group, send email to django...@googlegroups.com.

> > Visit this group at https://groups.google.com/group/django-users.

> > To view this discussion on the web visit https://groups.google.com/d/

> > msgid/django-users/53d50894-98f7-4d92-a1c2-0a9d61e19fea%40googlegroups.com

> >

> > For more options, visit https://groups.google.com/d/optout.

 

 

--

Melvyn Sopacua

Alexander Joseph

unread,
Jun 21, 2018, 3:11:11 PM6/21/18
to django...@googlegroups.com
Thanks Melvyn! I will definitely take a look at that. From some of the tutorials it sounds like there are some differences between Bootstrap3/4 in how the ajax calls would need to be structured but I'm interesting in seeing your approach

> > To post to this group, send email to django...@googlegroups.com.

> > Visit this group at https://groups.google.com/group/django-users.

> > To view this discussion on the web visit https://groups.google.com/d/

> > msgid/django-users/53d50894-98f7-4d92-a1c2-0a9d61e19fea%40googlegroups.com

--
You received this message because you are subscribed to a topic in the Google Groups "Django users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/django-users/CPspzgE33Dk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to django-users+unsubscribe@googlegroups.com.

To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.

For more options, visit https://groups.google.com/d/optout.



--

Alexander Joseph

unread,
Jun 21, 2018, 3:17:35 PM6/21/18
to Django users
So I changed the link to the button as you suggested, and put the static modal in the gaas_wafer_design_list.html file, and commented out the javascript at the bottom, and the modal is showing up as it should now. Heres my gaas_wafer_design_list.html file, highlighted with the changes


{% extends "pages/list_template.html" %}{% load static from staticfiles %}
{% load widget_tweaks %}

{% block title %}GaAs Wafer Design List{% endblock %}
{% block list_title %}GaAs Wafer Designs{% endblock %}
{% block list_title_2 %}Design Inventory{% endblock %}

{% block extra_js%}
<!--<script src="{% static 'js/jscreate.js' %}"></script>-->
{% endblock %}

{% block buttons %}
  <div class="btn-group" role="group" aria-label="Button group with nested dropdown" style="margin-bottom: -150px; z-index:1000;">
    <button class="btn btn-secondary" data-toggle="modal" data-target="#modal" %}>Create a new wafer design</button>
    <div class="btn-group" role="group">
      <a id="btnGroupDrop1" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
          View
      </a>
      <div class="dropdown-menu" aria-labelledby="btnGroupDrop1">
          <a class="dropdown-item" href="#">Recycling Bin</a>
      </div>
    </div>
  </div>

{% endblock %}

{% block table %}
<div class="modal fade" id="modal">
  <div class="modal-dialog modal-lg" role="document">
      <form action="{% url 'engineering:gaas_wafer_design_create' %}" method="post" id="gaas-create" class="form">{% csrf_token %}
          <div class="modal-content">
              <div class="modal-header">
                  <h4 class="modal-title">Add Wafer Design</h4>
                  <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                      <span aria-hidden="true">×</span>
                      <span class="sr-only">Close</span>
                  </button>
              </div>
              <div class="modal-body">
                  Test
              </div>
              <div class="modal-footer">
                  <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                  <input type="submit" class="btn btn-primary" value="Save changes" />
              </div>
          </div><!-- /.modal-content -->
      </form>
  </div><!-- /.modal-dialog -->
</div>
  <script>/*
  $('#modal').on('show.bs.modal', function (event) {
    var modal = $(this)
    $.ajax({
      url: "create/",
      context: document.body
    }).done(function(response) {
      modal.html(response);
    });
  })
  </script>
{% endblock %}

And a screenshot of what I'm seeing




So at least we know the modal itself works now. Thanks!

Alexander Joseph

unread,
Jun 26, 2018, 10:29:34 PM6/26/18
to Django users
Hey Kirby,

Any ideas on where I should take this next? Thanks

Syed .Sayem

unread,
May 1, 2019, 11:28:55 AM5/1/19
to Django users
Can you check does it work? Make change as you required

" By container = By.xpath("//*[@id=\"wishlistlogin\"]/div");
        WebDriverWait wait = new WebDriverWait(driver, 10);
        wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(container));
               
        WebElement textElement = driver.findElement(By.className("add-to-wishlist"));
        String textBeforeAjax = textElement.getText().trim();
        System.out.println(textBeforeAjax);
        driver.findElement(By.className("add-to-wishlist")).click();
       
        By loader = By.className("widgetPickup");
        wait.until(ExpectedConditions.invisibilityOfElementLocated(loader)); "




On Tuesday, June 19, 2018 at 3:08:59 PM UTC-4, Alexander Joseph wrote:
Reply all
Reply to author
Forward
0 new messages