Opening a modal with an ajax call

Description

Make a Bootstrap Modal open as a result of an ajax call. For example, by clicking on an "Edit" button a modal opens with a form to edit the chosen element. The modal content is generated on the server. The browser just opens it.

A modal
Figure 1. A modal

The implementation needs the following parts:

HTML for the ajax call

The ajax call can be made in many ways: with a DataTable button, with an ajax link, via custom javascript …​

Java for the @Controller

The modal must be returned by a @RequestMapping method of a @Controller.

HTML of the modal

It specifies the title, header, body, footer and script sections (all are optional). It can also have <head> elements that are added to the page <head> while the modal is open and removed on close.

HTML for the ajax call

The modal can be opened with any ajax call performed by Yada.

In this example we show an ajax link:

<a href="/myModal" class="yadaAjax">Click here</a>

In this example we show an ajax javascript call:

var data = {name: 'john', surname: 'Doe'};
yada.ajax(url, data, null, "POST");

Java for the @Controller

The Java @Controller must return a full Bootstrap Modal. The node with class="modal" will be added to the <body> and shown. It will be removed from the <body> on close. Any other open modal of this type will be removed unless "sticky" (see below).

@RequestMapping("/myModal")
public String myModal(Model model, Locale locale) {
	return "/myModal"; // There must be a myModal.html file
}

HTML of the modal

You can use your own Bootstrap Modal html or take advantage of the Yada Generic Modal template. With the Yada Generic Modal you only define the section fragments that you need, producing a full Bootstrap Modal.

The fragments are:

modal title

Visible in the modal header as an <h4> when no custom modal header fragment is given

custom modal header

A full Boostrap modal-header fragment. The modal title is ignored when using this fragment

modal body

The body content

modal footer

The html for the bottom part of the modal. Usually Submit and Close buttons are located here. By default, there’s just the close button.

modal script

Some custom script to be run when the modal code is inserted on page.

extra dialog classes

You can add a class to the modal-dialog div to set the modal size, the position, or anything that can be set there: modal-dialog-centered, 'modal-sm', 'modal-lg', 'modal-xl' and so on. You can also use an empty string '' or the empty fragment ~{}

The code uses standard Thymeleaf fragment syntax. To remove a fragment from the modal, use the ~{} expression. To keep the default value use the _ character:

In the following example, three fragments have been defined in the same html file and the footer has been removed.

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
        <meta charset="UTF-8"/>
</head>
<body>

<div th:replace="/yada/modalGeneric::fragment(~{::modalTitle},_,~{::modalBody},~{},~{::modalScript},'modal-lg')">

        <div th:fragment="modalTitle">This is the title</div>

        <th:block th:fragment="modalBody">
                <div class="modal-body">
                        This is the body
                </div>
        </th:block>

        <script th:fragment="modalScript">
                /* This is the script */
        </script>

</div>
</body>
</html>
A modal without footer
Figure 2. A modal without footer

Anything inside the <head> section will be added to the <head> of the page while the modal is open. This could be used to load some external js or css files for example.

Sticky Modals

Normally, when you open an ajax modal, all existing modals are closed. This is both convenient and compliant with the Bootstrap guidelines.

A "sticky modal" is an ajax-loaded modal that can stay open behind anyother ajax modal that is opened afterwards. You create a sticky modal by adding the yadaStickyModal class to the modal-dialog, for example:

<div th:replace="/yada/modalGeneric::fragment(~{::modalTitle},_,~{::modalBody},~{},~{::modalScript},'modal-lg yadaStickyModal')">

The modal will not close when another normal ajax modal is opened but will stay behind: it can only be closed with a data-dismiss button or with a call to .modal("hide"). There can only be one sticky modal at a time: opening a new sticky modal on top of another will hide the new one behind the existing one.

It might be convenient to increase the size of a sticky modal so that it remains partially visible behind a normal one. You can achieve this via the standard modal-lg or modal-fullscreen classes, or you could implement your own full-screen modal with the following css:

.modal-dialog {
        margin: 0;
        max-width: 100vw;
}