templates/_partials/courses/_modal_solicitud.html.twig line 1

Open in your IDE?
  1. <div class="modal fade" id="solicitudModal" tabindex="-1" role="dialog" aria-labelledby="solicitudModalLabel" aria-hidden="true">
  2. <div class="modal-dialog" role="document">
  3. <div class="modal-content">
  4. <div class="modal-header">
  5. <h5 class="modal-title" id="solicitudModalLabel">{{ 'modal.solicitud.title'|trans({}, 'courses')|default('Solicitar información sobre el curso') }}</h5>
  6. <button type="button" class="close" data-dismiss="modal" aria-label="Close">
  7. <span aria-hidden="true">&times;</span>
  8. </button>
  9. </div>
  10. <div class="modal-body">
  11. <form id="solicitudForm">
  12. <input type="hidden" id="actividadId" name="actividadId" value="">
  13. <input type="hidden" id="actividadTipo" name="actividadTipo" value="">
  14. <div class="form-group">
  15. <label for="nombre">{{ 'modal.solicitud.nombre'|trans({}, 'courses')|default('Nombre completo') }} *</label>
  16. <input type="text" class="form-control" id="nombre" name="nombre" required>
  17. <div class="invalid-feedback" id="error-nombre"></div>
  18. </div>
  19. <div class="form-group">
  20. <label for="email">{{ 'modal.solicitud.email'|trans({}, 'courses')|default('Correo electrónico') }} *</label>
  21. <input type="email" class="form-control" id="email" name="email" required>
  22. <div class="invalid-feedback" id="error-email"></div>
  23. </div>
  24. <div class="form-group">
  25. <label for="telefono">{{ 'modal.solicitud.telefono'|trans({}, 'courses')|default('Teléfono') }} *</label>
  26. <input type="tel" class="form-control" id="telefono" name="telefono" required>
  27. <div class="invalid-feedback" id="error-telefono"></div>
  28. </div>
  29. <div class="form-group">
  30. <label for="comentario">{{ 'modal.solicitud.comentario'|trans({}, 'courses')|default('Comentarios o consultas') }}</label>
  31. <textarea class="form-control" id="comentario" name="comentario" rows="3"></textarea>
  32. <div class="invalid-feedback" id="error-comentario"></div>
  33. </div>
  34. </form>
  35. </div>
  36. <div class="modal-footer">
  37. <button type="button" class="btn btn-secondary" data-dismiss="modal">
  38. {{ 'modal.solicitud.cancel'|trans({}, 'courses')|default('Cancelar') }}
  39. </button>
  40. <button type="button" class="btn btn-primary" id="submitSolicitud">
  41. {{ 'modal.solicitud.submit'|trans({}, 'courses')|default('Enviar solicitud') }}
  42. </button>
  43. </div>
  44. </div>
  45. </div>
  46. </div>
  47. <script>
  48. document.addEventListener('DOMContentLoaded', function() {
  49. // Inicializar los botones de solicitud
  50. const solicitudBtns = document.querySelectorAll('.btn-apply');
  51. const solicitudModal = document.getElementById('solicitudModal');
  52. // Ya no necesitamos manejar los botones de solicitud a través de JavaScript
  53. // para usuarios logueados, pero sí mantener la funcionalidad para usuarios no logueados
  54. solicitudBtns.forEach(btn => {
  55. // Solo manejamos los botones que no tienen atributo href (los que no se han convertido en enlaces)
  56. if (!btn.hasAttribute('href')) {
  57. btn.addEventListener('click', function() {
  58. const actividadId = this.dataset.actividadId;
  59. const actividadTipo = this.dataset.actividadTipo;
  60. // Mostrar el modal solo para usuarios no registrados
  61. if (!document.body.classList.contains('logged-in')) {
  62. document.getElementById('actividadId').value = actividadId;
  63. document.getElementById('actividadTipo').value = actividadTipo;
  64. $('#solicitudModal').modal('show');
  65. }
  66. });
  67. }
  68. });
  69. // Manejar el envío del formulario
  70. document.getElementById('submitSolicitud').addEventListener('click', function() {
  71. const form = document.getElementById('solicitudForm');
  72. const actividadId = document.getElementById('actividadId').value;
  73. const actividadTipo = document.getElementById('actividadTipo').value;
  74. // Limpiar mensajes de error previos
  75. form.querySelectorAll('.is-invalid').forEach(el => el.classList.remove('is-invalid'));
  76. form.querySelectorAll('.invalid-feedback').forEach(el => el.textContent = '');
  77. // Recoger datos del formulario
  78. const formData = {
  79. nombre: document.getElementById('nombre').value,
  80. email: document.getElementById('email').value,
  81. telefono: document.getElementById('telefono').value,
  82. comentario: document.getElementById('comentario').value
  83. };
  84. // Enviar solicitud
  85. enviarSolicitudUsuarioNoRegistrado(actividadTipo, actividadId, formData);
  86. });
  87. // Función para enviar solicitud de usuario no registrado
  88. function enviarSolicitudUsuarioNoRegistrado(tipo, id, formData) {
  89. fetch(`/${document.documentElement.lang}/courses/ajax/muestra-interes/${tipo}/${id}`, {
  90. method: 'POST',
  91. headers: {
  92. 'X-Requested-With': 'XMLHttpRequest',
  93. 'Content-Type': 'application/json'
  94. },
  95. body: JSON.stringify(formData),
  96. credentials: 'same-origin'
  97. })
  98. .then(response => response.json())
  99. .then(data => {
  100. if (data.success) {
  101. $('#solicitudModal').modal('hide');
  102. mostrarMensajeExito(data.message);
  103. // Limpiar formulario
  104. document.getElementById('solicitudForm').reset();
  105. } else {
  106. // Mostrar errores en el formulario
  107. if (data.errors) {
  108. Object.keys(data.errors).forEach(field => {
  109. const fieldName = field.replace(/\[|\]/g, '');
  110. const inputElement = document.getElementById(fieldName);
  111. const errorElement = document.getElementById(`error-${fieldName}`);
  112. if (inputElement && errorElement) {
  113. inputElement.classList.add('is-invalid');
  114. errorElement.textContent = data.errors[field];
  115. }
  116. });
  117. } else {
  118. mostrarMensajeError(data.message);
  119. }
  120. }
  121. })
  122. .catch(error => {
  123. console.error('Error:', error);
  124. mostrarMensajeError('{{ 'error.general'|trans({}, 'courses')|default('Ha ocurrido un error. Inténtelo de nuevo más tarde.') }}');
  125. });
  126. }
  127. // Función para mostrar mensaje de éxito
  128. function mostrarMensajeExito(mensaje) {
  129. const alertDiv = document.createElement('div');
  130. alertDiv.className = 'alert alert-success alert-dismissible fade show mt-3';
  131. alertDiv.innerHTML = `
  132. ${mensaje}
  133. <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  134. <span aria-hidden="true">&times;</span>
  135. </button>
  136. `;
  137. // Insertar alerta después del primer elemento con clase container
  138. const container = document.querySelector('.container');
  139. if (container) {
  140. container.prepend(alertDiv);
  141. // Desaparecer después de 5 segundos
  142. setTimeout(() => {
  143. alertDiv.classList.remove('show');
  144. setTimeout(() => alertDiv.remove(), 150);
  145. }, 5000);
  146. }
  147. }
  148. // Función para mostrar mensaje de error
  149. function mostrarMensajeError(mensaje) {
  150. const alertDiv = document.createElement('div');
  151. alertDiv.className = 'alert alert-danger alert-dismissible fade show mt-3';
  152. alertDiv.innerHTML = `
  153. ${mensaje}
  154. <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  155. <span aria-hidden="true">&times;</span>
  156. </button>
  157. `;
  158. // Insertar alerta después del primer elemento con clase container
  159. const container = document.querySelector('.container');
  160. if (container) {
  161. container.prepend(alertDiv);
  162. // Desaparecer después de 5 segundos
  163. setTimeout(() => {
  164. alertDiv.classList.remove('show');
  165. setTimeout(() => alertDiv.remove(), 150);
  166. }, 5000);
  167. }
  168. }
  169. });
  170. </script>