Search code examples
flaskjinja2bootstrap-modalflask-wtforms

Jinja2 modal popup (Bootstrap 5) not appearing, no error


I've seen a few versions of this question posted but none with exactly the same parameters or with solutions that work for me, so here goes: within Jinja2 templating, I call a modal-popup in a form, to confirm the shutdown of a peripheral device. The issue is that the modal popup 1. does not display and 2. has not output whatsoever in the terminal or log.

The code for the modal call (last 2 lines in the else):

 <form class="form form-horizontal" method="post" role="form" style="text-align: center;">
                    {{ power_form.hidden_tag() }}
                    
                    {% if power_status == "None" %}
                    {{ power_form.power_on(class_="btn btn-default") }}
                    {{ power_form.power_cycle(class_="btn btn-default") }}
                    {{ power_form.power_off(class_="btn btn-default") }}

                    {% else %}
                    {{ power_form.power_on(class_="btn btn-success") }}
                    {{ power_form.power_cycle(class_="btn btn-warning") }}
                    {{ power_form.power_off(type="button", class_="btn btn-danger", 
                    data_toggle="modal", data_target="#modalConfirm") }}

                    {% endif %}
                </form>

I have checked that the function within Flask allows for both POST and GET calls, and used a default instantiation of the modal according to Bootstrap documentation. I have also ensured that the required libraries (JQuery, Bootstrap) are requested, and changed the syntax from bs_data_toggle to data_toggle (for trigger as well), neither of which worked.

Please let me know if this is enough information! I am very new to developing for web and would appreciate any pointers in the right direction. Thanks, H.

P.S: Here is the code for the modal:

<div class="modal fade" id="modalConfirm" tabindex="-1" aria-labelledby="modalConfirmLabel" aria-hidden="true">
<div class="modal-dialog">
  <div class="modal-content">
    <div class="modal-header">
      <h5 class="modal-title" id="modalConfirmLabel">Shutdown Confirmation</h5>
      <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
    </div>
    <div class="modal-body">
      ...
    </div>
    <div class="modal-footer">
      <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
      <button type="button" class="btn btn-primary">Save changes</button>
    </div>
  </div>
</div>

P.S (2): The relevant CSS / JS inclusions. Within head, here are the CSS includes:

<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet" />
 <link href="{{ url_for('static', filename='css/light-bootstrap-dashboard.css') }}" rel="stylesheet" />
 <link href="{{ url_for('static', filename='css/spectrum.css') }}" rel="stylesheet"/>

Within a separate block of scripts after the body are the JS includes:

 <script src="{{ url_for('static', 
  filename='js/core/jquery.3.2.1.min.js') }}" type="text/javascript"> 
 </script>
 <script src="{{ url_for('static', filename='js/core/popper.min.js') }}" 
 type="text/javascript"></script>
 <script src="{{ url_for('static', filename='js/core/bootstrap.min.js') 
 }}" type="text/javascript"></script>

Solution

  • You have included the Bootstrap v5 library, but accidentally used the v4 syntax (and documentation) for the modal. There's was a change in the new version: the data attribute got a -bs- suffix (not a prefix). So we have to use e.g. data-bs-toggle HTML attribute to pass the information to Bootstrap:

    {{ power_form.power_off(type="button", class_="btn btn-danger", 
                            data_bs_toggle="modal", data_bs_target="#modalConfirm") }}