Tomas: añadir tipo de examen inline sin página separada

- Botón "Añadir tipo de examen…" debajo del selector _c8j2g16
- Al escribir y guardar, añade la opción vía API y la selecciona al instante
- api/lab/add_exam_option.php: guarda la nueva opción en el esquema del formulario
- Migración actualizada: solo elimina condiciones de separadores (no toca el selector)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-07-10 11:05:45 -05:00
co-authored by Claude Sonnet 4.6
parent 4e6da5d7eb
commit be55a087aa
3 changed files with 140 additions and 10 deletions
+96
View File
@@ -994,6 +994,28 @@ function esc2(mixed $v): string {
<label class="form-check-label"><?= esc2($opt) ?></label>
</div>
<?php endforeach; ?>
<?php if ($cid === '_c8j2g16'): ?>
<div class="mt-2" id="add-exam-wrap-<?= esc2($cid) ?>">
<button type="button" class="btn btn-link btn-sm p-0 text-muted"
onclick="toggleAddExam('<?= esc2($cid) ?>')">
<i class="fas fa-plus-circle me-1"></i>Añadir tipo de examen…
</button>
<div id="add-exam-box-<?= esc2($cid) ?>" class="d-none mt-1 d-flex gap-2">
<input type="text" id="add-exam-input-<?= esc2($cid) ?>"
class="form-control form-control-sm" style="max-width:260px"
placeholder="Nombre del tipo de examen">
<button type="button" class="btn btn-success btn-sm"
onclick="guardarNuevoExamen('<?= esc2($cid) ?>')">
<i class="fas fa-check me-1"></i>Guardar
</button>
<button type="button" class="btn btn-outline-secondary btn-sm"
onclick="toggleAddExam('<?= esc2($cid) ?>')">
<i class="fas fa-times"></i>
</button>
</div>
<div id="add-exam-msg-<?= esc2($cid) ?>" class="small mt-1"></div>
</div>
<?php endif; ?>
</div>
<?php continue; endif;
if ($tipo === 'checkbox' || $tipo === 'lista_marcable'):
@@ -1013,6 +1035,28 @@ function esc2(mixed $v): string {
</div>
<?php endforeach; ?>
</div>
<?php if ($cid === '_c8j2g16'): ?>
<div class="mt-2" id="add-exam-wrap-<?= esc2($cid) ?>">
<button type="button" class="btn btn-link btn-sm p-0 text-muted"
onclick="toggleAddExam('<?= esc2($cid) ?>')">
<i class="fas fa-plus-circle me-1"></i>Añadir tipo de examen…
</button>
<div id="add-exam-box-<?= esc2($cid) ?>" class="d-none mt-1 d-flex gap-2">
<input type="text" id="add-exam-input-<?= esc2($cid) ?>"
class="form-control form-control-sm" style="max-width:260px"
placeholder="Nombre del tipo de examen">
<button type="button" class="btn btn-success btn-sm"
onclick="guardarNuevoExamen('<?= esc2($cid) ?>')">
<i class="fas fa-check me-1"></i>Guardar
</button>
<button type="button" class="btn btn-outline-secondary btn-sm"
onclick="toggleAddExam('<?= esc2($cid) ?>')">
<i class="fas fa-times"></i>
</button>
</div>
<div id="add-exam-msg-<?= esc2($cid) ?>" class="small mt-1"></div>
</div>
<?php endif; ?>
</div>
<?php continue; endif;
if ($tipo === 'select'):
@@ -1283,6 +1327,58 @@ document.addEventListener('DOMContentLoaded', function() {
})();
<?php endif; ?>
<?php endif; ?>
/* ── Añadir tipo de examen inline ── */
function toggleAddExam(cid) {
var box = document.getElementById('add-exam-box-' + cid);
if (!box) return;
box.classList.toggle('d-none');
if (!box.classList.contains('d-none')) {
var inp = document.getElementById('add-exam-input-' + cid);
if (inp) inp.focus();
}
}
function guardarNuevoExamen(cid) {
var inp = document.getElementById('add-exam-input-' + cid);
var msg = document.getElementById('add-exam-msg-' + cid);
if (!inp) return;
var name = inp.value.trim();
if (!name) { if (msg) msg.innerHTML = '<span class="text-danger">Ingrese un nombre.</span>'; return; }
var base = window.location.href.split('/ver_formulario_enviado.php')[0];
fetch(base + '/api/lab/add_exam_option.php', {
method: 'POST', headers: {'Content-Type': 'application/json'},
body: JSON.stringify({exam_name: name})
})
.then(function(r) { return r.json(); })
.then(function(d) {
if (d.ok) {
// Añadir radio button al grupo y seleccionarlo
var wrap = document.querySelector('[data-campo-id="' + cid + '"]');
if (wrap) {
var div = document.createElement('div');
div.className = 'form-check';
div.innerHTML = '<input class="form-check-input" type="radio" name="' + cid + '" value="' + name.replace(/"/g, '&quot;') + '" checked>'
+ '<label class="form-check-label">' + name.replace(/</g, '&lt;') + '</label>';
// Insertar antes del bloque add-exam-wrap
var addWrap = document.getElementById('add-exam-wrap-' + cid);
wrap.insertBefore(div, addWrap);
// Disparar evento change para condiciones de visibilidad
div.querySelector('input').dispatchEvent(new Event('change', {bubbles: true}));
}
inp.value = '';
if (msg) msg.innerHTML = '<span class="text-success"><i class="fas fa-check me-1"></i>Añadido.</span>';
setTimeout(function() {
toggleAddExam(cid);
if (msg) msg.innerHTML = '';
}, 1500);
} else {
if (msg) msg.innerHTML = '<span class="text-danger">' + (d.error || 'Error') + '</span>';
}
})
.catch(function() {
if (msg) msg.innerHTML = '<span class="text-danger">Error de conexión.</span>';
});
}
window._muestrasMap = <?= json_encode($_mpMap, JSON_UNESCAPED_UNICODE) ?>;
window._mpSavedFirmas = {};