I am trying to reuse the following modal (as a fragment) with thymeleaf.
<th:block th:fragment="modalFragment (modalId, labelId, modalTitle, formId, saveButtonId, fields)">
<div class="modal fade" th:id="${modalId}" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1"
th:aria-labelledby="${labelId}" aria-hidden="true">
<div class="modal-dialog modal-dialog-scrollable modal-dialog-centered modal-xl">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" th:id="${labelId}" th:text="${modalTitle}">Título del Modal</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"
aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="container-fluid">
<!-- Renderizar el formulario solo si formId no es null -->
<form th:if="${formId != null and formId != ''}" th:id="${formId}" class="row g-3">
<!-- Espacio reservado para campos del formulario dinámicos, definidos en la página de inclusión -->
<th:block th:replace="~{this :: fields}"></th:block>
</form>
<!-- Renderizar contenido alternativo si formId es null -->
<!-- <th:block th:unless="${formId != null}" th:replace="~{this :: fields}"></th:block>-->
<th:block th:unless="${formId != null and formId != ''}">
<th:block th:replace="~{this :: fields}"></th:block>
</th:block>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cerrar</button>
<!-- Renderizar el botón de guardar solo si saveButtonId está definido -->
<button type="button" th:if="${saveButtonId != null and saveButtonId != ''}" th:id="${saveButtonId}"
class="btn btn-custom">Guardar
</button>
</div>
</div>
</div>
</div>
</th:block>
When I use it this way in my .html it works without problems.
<div th:replace="~{fragments/modalFragment :: modalFragment(
modalId='modalUsuario',
labelId='staticBackdropLabelUsuario',
modalTitle='Usuario',
formId='formularioRegistroUsuario',
saveButtonId='btnGuardarUsuario',
fields='~{this :: fields}')}">
<!-- Campos del formulario definidos directamente dentro de la inclusión del modal -->
<th:block th:fragment="fields">
<div class="col-md-6 offset-6 d-none">
<div class="form-floating">
<input type="text" class="form-control" id="usuId" name="usuId" placeholder="Id"
readonly>
<label for="usuId">Id</label>
</div>
</div>
<div class="col-md-6">
<div class="form-floating">
<select class="form-select componente-select" id="usuActivo" name="usuActivo"
aria-label="Estado"
data-lista="1" data-lista-idioma="1" required>
<option value="" selected>Selecciona una opción</option>
</select>
<label for="usuActivo">Estado</label>
</div>
</div>
<!-- Usamos este div vacío para forzar que la siguiente columna que haya después vaya abajo. -->
<div class="w-100 m-0"></div>
<div class="col-md-6">
<div class="form-floating">
<select class="form-select componente-select" id="roles"
aria-label="Rol"
data-live-search="true" data-url="buscarListaRoles">
<option value="" selected>Selecciona una opción</option>
</select>
<label for="roles">Rol</label>
</div>
</div>
<div class="col-md-6">
<div class="form-floating">
<select class="form-select componente-select"
id="sistemas"
aria-label="Sistemas"
data-url="buscarListaSistemas"
title="Selecciona una opción"
data-live-search="true" data-size="8" multiple
data-actions-box="true">
</select>
<label for="sistemas">Sistemas</label>
</div>
</div>
<div class="col-md-6">
<div class="form-floating">
<input type="text" class="form-control" id="usuUsuario" name="usuUsuario"
placeholder="Usuario" required>
<label for="usuUsuario">Usuario</label>
</div>
</div>
<!-- Usamos este div vacío para forzar que la siguiente columna que haya después vaya abajo. -->
<div class="w-100 m-0"></div>
<div class="col-md-6">
<div class="form-floating d-flex align-items-center bg-white">
<input type="password" class="form-control"
id="usuPassword" name="usuPassword" placeholder="Contraseña">
<label for="usuPassword">Contraseña</label>
<span><i id="btnMostrarPass"
class="bi bi-eye-slash-fill cursor-pointer"></i></span>
</div>
</div>
<div class="col-md-6">
<div class="form-floating d-flex align-items-center bg-white">
<input type="password" class="form-control"
id="usuRepitePassword" placeholder="Contraseña">
<label for="usuRepitePassword">Repite contraseña</label>
<span><i id="btnMostrarRepitePass"
class="bi bi-eye-slash-fill cursor-pointer"></i></span>
</div>
</div>
<div id="mensajeMayusculas" class="col-12 text-center d-none">
<i class="bi bi-exclamation-triangle-fill me-2"></i>
<span>El bloqueo de mayúsculas está activado</span>
</div>
<div class="col-md-6">
<div class="form-floating">
<input type="text" class="form-control" id="usuNombre" name="usuNombre"
placeholder="Nombre" required>
<label for="usuNombre">Nombre</label>
</div>
</div>
<div class="col-md-6">
<div class="form-floating">
<input type="text" class="form-control" id="usuPrimerApellido" name="usuPrimerApellido"
placeholder="Primer apellido" required>
<label for="usuPrimerApellido">Primer apellido</label>
</div>
</div>
<div class="col-md-6">
<div class="form-floating">
<input type="text" class="form-control" id="usuSegundoApellido" name="usuSegundoApellido"
placeholder="Segundo apellido">
<label for="usuSegundoApellido">Segundo apellido</label>
</div>
</div>
<div class="col-md-6">
<div class="form-floating">
<input type="text" class="form-control" id="usuDni" name="usuDni"
placeholder="DNI">
<label for="usuDni">DNI</label>
</div>
</div>
<div class="col-md-6">
<div class="form-floating">
<input type="text" class="form-control" id="usuTelefono" name="usuTelefono"
placeholder="Teléfono">
<label for="usuTelefono">Teléfono</label>
</div>
</div>
<div class="col-md-6">
<div class="form-floating">
<input type="email" class="form-control" id="usuEmail" name="usuEmail"
placeholder="Email">
<label for="usuEmail">Email</label>
</div>
</div>
</th:block>
</div>
But when I want to add a second modal to the same .html it does not work as it should.
<div th:replace="~{fragments/modalFragment :: modalFragment(
modalId='modalUsuario2',
labelId='staticBackdropLabelUsuario2',
modalTitle='Usuario2',
formId='',
saveButtonId='',
fields='~{this :: fields}')}">
<!-- Campos del formulario definidos directamente dentro de la inclusión del modal -->
<th:block th:fragment="fields">
<p>HOLA</p>
</th:block>
</div>
What it does is to put me the same fields in both modals. In the second one they come out without layout maybe because they’re repeated fields, I see the duplicated ids on the DevTools console.
I have tried to change:
fields='~{this :: fields}')}"
with fields='~{this :: fields2}')}"
and <th:block th:fragment="fields2">
but it doesn’t work either.
Do you have any idea why it doesn’t work? I guess it doesn’t resolve the “this” context well or something like that.