Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/val20-11/Pagina-de-Seminarios-y-Eventos-UIM/llms.txt

Use this file to discover all available pages before exploring further.

Each seminar card includes an Inscribirme ahora button. Clicking it opens a modal overlay (#inscripcionModal) pre-selected to that seminar. The form collects the visitor’s details, detects whether they belong to FES Acatlán, and conditionally reveals an account number field with a smooth CSS animation.

Opening the modal

Every .btn-inscripcion button fires openModal(titulo) with the seminar title as argument. The function is wired in two places to survive re-renders:
js/seminarios.js
function openModal(titulo) {
    modalSelect.value = titulo;          // pre-select the seminar in the <select>
    modal.classList.add('active');       // .modal-overlay.active { display: flex }
    document.body.style.overflow = 'hidden';  // prevent background scroll
}
The #modalSeminario select element is populated on page load by iterating over the full seminarios array:
js/seminarios.js
seminarios.forEach(s => {
    const opt = document.createElement('option');
    opt.value       = s.titulo;
    opt.textContent = s.titulo;
    modalSelect.appendChild(opt);
});

Form fields

The form #formInscripcion is declared in reestructuracion.html:
reestructuracion.html
<form id="formInscripcion" class="modal-form" novalidate>

    <div class="form-group">
        <label for="inputNombre">Nombre completo</label>
        <input type="text" id="inputNombre" placeholder="Tu nombre completo" required>
    </div>

    <div class="form-group">
        <label for="inputCorreo">Correo electrónico</label>
        <input type="email" id="inputCorreo" placeholder="tu@correo.com" required>
    </div>

    <div class="form-group">
        <label for="inputTipoUsuario">
            Tipo de usuario
            <span class="tipo-badge" id="tipoBadge"></span>
        </label>
        <select id="inputTipoUsuario" required>
            <option value="">-- Selecciona tu tipo de usuario --</option>
            <option value="interno">Interno (FES Acatlán)</option>
            <option value="externo">Externo</option>
        </select>
    </div>

    <!-- Conditional: visible only when tipo === 'interno' -->
    <div class="form-group" id="grupo-numero-cuenta">
        <label for="inputNumeroCuenta">Número de cuenta</label>
        <input type="text" id="inputNumeroCuenta"
               placeholder="Ej. 420012345"
               maxlength="9" pattern="[0-9]{8,9}" inputmode="numeric">
    </div>

    <div class="form-group">
        <label for="modalSeminario">Seminario</label>
        <select id="modalSeminario" required></select>
    </div>

    <div class="form-group">
        <label for="inputMotivo">Motivo de inscripción</label>
        <textarea id="inputMotivo" rows="4"
                  placeholder="¿Por qué deseas inscribirte a este seminario?" required></textarea>
    </div>

    <button type="submit" class="btn-submit">
        <i class="fas fa-paper-plane"></i> Enviar inscripción
    </button>
</form>
FieldElementValidation
Nombre completoinput[type=text]#inputNombrerequired
Correo electrónicoinput[type=email]#inputCorreorequired, email format
Tipo de usuarioselect#inputTipoUsuariorequired
Número de cuentainput[type=text]#inputNumeroCuentarequired only when interno; pattern [0-9]{8,9}, max 9 chars
Seminarioselect#modalSeminariorequired; pre-populated from seminarios array
Motivo de inscripcióntextarea#inputMotivorequired

User type detection and the conditional account number field

When the visitor selects a user type, a separate inline script (after seminarios.js) reacts to the change event on #inputTipoUsuario:
reestructuracion.html (inline script)
(function () {
    const selectTipo  = document.getElementById('inputTipoUsuario');
    const grupoCuenta = document.getElementById('grupo-numero-cuenta');
    const inputCuenta = document.getElementById('inputNumeroCuenta');
    const badge       = document.getElementById('tipoBadge');

    selectTipo.addEventListener('change', function () {
        const tipo = this.value;

        if (tipo === 'interno') {
            grupoCuenta.classList.add('visible');          // animate in
            inputCuenta.setAttribute('required', 'required');
            badge.textContent = 'FES Acatlán';
            badge.className   = 'tipo-badge interno';      // blue badge

        } else {
            grupoCuenta.classList.remove('visible');       // animate out
            inputCuenta.removeAttribute('required');
            inputCuenta.value = '';

            if (tipo === 'externo') {
                badge.textContent = 'Externo';
                badge.className   = 'tipo-badge externo';  // gold badge
            } else {
                badge.textContent = '';
                badge.className   = 'tipo-badge';          // no badge
            }
        }
    });
})();

Badge styles

The .tipo-badge span sits inline next to the label text and changes appearance to reflect the selected type:
reestructuracion.html (inline style)
.tipo-badge {
    display: inline-block;
    font-size: 0.7rem;
    font-weight: 700;
    padding: 2px 8px;
    border-radius: 20px;
    margin-left: 6px;
    transition: background 0.3s, color 0.3s;
}

.tipo-badge.interno { background: #003B6F; color: #fff; }  /* dark blue */
.tipo-badge.externo { background: #B38633; color: #fff; }  /* gold */

Interno (FES Acatlán)

Badge turns dark blue (#003B6F) with text FES Acatlán. The account number field slides in and becomes required.

Externo

Badge turns gold (#B38633) with text Externo. The account number field slides out, its required attribute is removed, and its value is cleared.

Animated show/hide of the account number field

The transition uses max-height and opacity rather than display toggling, which allows CSS to animate between the two states:
reestructuracion.html (inline style)
#grupo-numero-cuenta {
    overflow: hidden;
    max-height: 0;
    opacity: 0;
    transition: max-height 0.35s ease,
                opacity    0.30s ease,
                margin     0.30s ease;
    margin-bottom: 0;
}

#grupo-numero-cuenta.visible {
    max-height: 120px;
    opacity: 1;
    margin-bottom: 1rem;
}
Adding .visible triggers the transition from max-height: 0 to max-height: 120px over 350 ms. Removing .visible reverses the animation, collapsing the field back to zero height.

Closing the modal

Three actions close the modal and reset the form:
1

X button

Clicking #modalClose calls closeModal(), which removes .active from the overlay and calls modalForm.reset().
2

Clicking the overlay

A click listener on .modal-overlay checks e.target === modal. If the user clicks the dark backdrop (not the white content box), closeModal() is called.
3

Submitting the form

The submit event calls e.preventDefault() then closeModal(). The form data is not sent anywhere — submission currently serves only as a close trigger.
js/seminarios.js
function closeModal() {
    modal.classList.remove('active');   // hide overlay
    document.body.style.overflow = '';  // restore background scroll
    modalForm.reset();                  // clear all inputs
}

modalClose.addEventListener('click', closeModal);

modal.addEventListener('click', (e) => {
    if (e.target === modal) closeModal();
});

modalForm.addEventListener('submit', (e) => {
    e.preventDefault();
    closeModal();
});
A separate resetTipoUsuario() function in the inline script also fires on the close button click and on the form’s reset event, restoring the user-type select, hiding the account number field, and clearing the badge:
reestructuracion.html (inline script)
function resetTipoUsuario() {
    selectTipo.value = '';
    grupoCuenta.classList.remove('visible');
    inputCuenta.removeAttribute('required');
    inputCuenta.value = '';
    badge.textContent = '';
    badge.className   = 'tipo-badge';
}

if (btnCerrar)  btnCerrar.addEventListener('click', resetTipoUsuario);
if (formulario) formulario.addEventListener('reset', resetTipoUsuario);
modalForm.reset() (called inside closeModal) triggers the form’s native reset event, which in turn fires resetTipoUsuario. This means the user-type state is always cleaned up, even if the modal is closed via the overlay click path.
The .modal-content panel slides in from above using a CSS keyframe animation that runs once each time the overlay becomes visible:
css/components.css
@keyframes modalIn {
    from { transform: translateY(-20px); opacity: 0; }
    to   { transform: translateY(0);     opacity: 1; }
}

.modal-content {
    animation: modalIn 0.2s ease;
}

Build docs developers (and LLMs) love