fix: mostrar canvas para todos los campos firma en modo turnero
Antes solo el primer campo (consentimiento) tenía canvas; el segundo (desistimiento) se omitía. Ahora cada campo firma tiene su propio widget usando clases CSS en vez de IDs hardcodeados. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
597ec87964
commit
0c68dff307
+39
-39
@@ -481,13 +481,13 @@ function esc2(mixed $v): string {
|
||||
$fLabel = htmlspecialchars($campo['label'] ?? ($isPro ? 'Firma profesional' : 'Firma paciente'));
|
||||
|
||||
// Campo paciente sin firma:
|
||||
// - En turnero pendiente: el PRIMER campo firma muestra el canvas, los demás se omiten.
|
||||
// - En turnero pendiente: todos los campos firma muestran canvas (consentimiento + desistimiento).
|
||||
// - En vista normal: omitir campos sin firma.
|
||||
if (!$fSvg && !$fFoto && !$isPro) {
|
||||
if ($modoTurnero && $modoEditar && !$_esquemaTieneFirmaPaciente) {
|
||||
$_esquemaTieneFirmaPaciente = true; // solo el primero muestra canvas
|
||||
if ($modoTurnero && $modoEditar) {
|
||||
$_esquemaTieneFirmaPaciente = true;
|
||||
} else {
|
||||
continue; // campos firma adicionales (desistimiento) sin firma → omitir
|
||||
continue; // no-turnero: omitir campos sin firma
|
||||
}
|
||||
}
|
||||
|
||||
@@ -510,20 +510,20 @@ function esc2(mixed $v): string {
|
||||
<img src="<?= htmlspecialchars($fFoto) ?>" alt="Foto - <?= $fLabel ?>">
|
||||
</div>
|
||||
<?php elseif (!$isPro && $modoTurnero && $modoEditar): ?>
|
||||
<div id="turneroFirmaWidget">
|
||||
<div class="turnero-firma-item no-print" data-cid="<?= esc2($cid) ?>">
|
||||
<p class="text-muted small mb-2"><i class="fas fa-pen me-1"></i>He leído el documento. Dibuje su firma:</p>
|
||||
<canvas id="turneroCv" width="500" height="160"
|
||||
<canvas class="turnero-cv" width="500" height="160"
|
||||
style="border:2px solid #1565c0;border-radius:8px;background:#f0f4ff;
|
||||
cursor:crosshair;display:block;max-width:100%;touch-action:none"></canvas>
|
||||
<div class="mt-2 d-flex gap-2 flex-wrap">
|
||||
<button id="turneroLimpiar" class="btn btn-outline-secondary btn-sm">
|
||||
<button class="btn btn-outline-secondary btn-sm turnero-limpiar">
|
||||
<i class="fas fa-eraser me-1"></i>Limpiar
|
||||
</button>
|
||||
<button id="turneroFirmar" class="btn btn-success fw-semibold">
|
||||
<i class="fas fa-check-circle me-1"></i>Confirmar y firmar consentimiento
|
||||
<button class="btn btn-success fw-semibold turnero-firmar">
|
||||
<i class="fas fa-check-circle me-1"></i>Confirmar: <?= $fLabel ?>
|
||||
</button>
|
||||
</div>
|
||||
<div id="turneroMsg" class="mt-2 small"></div>
|
||||
<div class="turnero-msg mt-2 small"></div>
|
||||
</div>
|
||||
<?php elseif ($isPro): ?>
|
||||
<?php if (!$modoTurnero && !$modoPublico && !$yaHayCanvasPro): ?>
|
||||
@@ -736,7 +736,7 @@ function esc2(mixed $v): string {
|
||||
|
||||
<!-- ── Widget firma turnero (fallback si el esquema no tiene campo firma) ── -->
|
||||
<?php if ($modoTurnero && $envio['estado'] !== 'firmado' && !$_esquemaTieneFirmaPaciente): ?>
|
||||
<div class="mt-4 no-print" id="turneroFirmaWidget">
|
||||
<div class="mt-4 no-print turnero-firma-item" data-cid="__firma_global">
|
||||
<div class="section-title" style="color:#1565c0">
|
||||
<i class="fas fa-pen me-1"></i>Firma del paciente / responsable
|
||||
</div>
|
||||
@@ -744,19 +744,19 @@ function esc2(mixed $v): string {
|
||||
He leído y comprendido el contenido de este documento.
|
||||
Por favor dibuje su firma en el recuadro:
|
||||
</p>
|
||||
<canvas id="turneroCv" width="500" height="160"
|
||||
<canvas class="turnero-cv" width="500" height="160"
|
||||
style="border:2px solid #1565c0;border-radius:8px;background:#f0f4ff;
|
||||
cursor:crosshair;display:block;max-width:100%;touch-action:none">
|
||||
</canvas>
|
||||
<div class="mt-2 d-flex gap-2 flex-wrap">
|
||||
<button id="turneroLimpiar" class="btn btn-outline-secondary btn-sm">
|
||||
<button class="btn btn-outline-secondary btn-sm turnero-limpiar">
|
||||
<i class="fas fa-eraser me-1"></i>Limpiar
|
||||
</button>
|
||||
<button id="turneroFirmar" class="btn btn-success fw-semibold">
|
||||
<i class="fas fa-check-circle me-1"></i>Confirmar y firmar consentimiento
|
||||
<button class="btn btn-success fw-semibold turnero-firmar">
|
||||
<i class="fas fa-check-circle me-1"></i>Confirmar y firmar
|
||||
</button>
|
||||
</div>
|
||||
<div id="turneroMsg" class="mt-2 small"></div>
|
||||
<div class="turnero-msg mt-2 small"></div>
|
||||
</div>
|
||||
<?php elseif ($modoTurnero && $envio['estado'] === 'firmado'): ?>
|
||||
<div class="alert alert-success mt-4 d-flex align-items-center gap-2 no-print">
|
||||
@@ -888,16 +888,17 @@ function esc2(mixed $v): string {
|
||||
});
|
||||
})();
|
||||
|
||||
/* ── Firma de consentimiento turnero ────────────────────────────────── */
|
||||
(function () {
|
||||
var canvas = document.getElementById('turneroCv');
|
||||
var widget = document.getElementById('turneroFirmaWidget');
|
||||
/* ── Firma de consentimiento turnero (soporta múltiples campos firma) ── */
|
||||
document.querySelectorAll('.turnero-firma-item').forEach(function(widget) {
|
||||
var canvas = widget.querySelector('.turnero-cv');
|
||||
if (!canvas) return;
|
||||
var cid = widget.dataset.cid || '__firma';
|
||||
var ctx = canvas.getContext('2d');
|
||||
var btnLimp = document.getElementById('turneroLimpiar');
|
||||
var btnFirm = document.getElementById('turneroFirmar');
|
||||
var msgEl = document.getElementById('turneroMsg');
|
||||
var btnLimp = widget.querySelector('.turnero-limpiar');
|
||||
var btnFirm = widget.querySelector('.turnero-firmar');
|
||||
var msgEl = widget.querySelector('.turnero-msg');
|
||||
var drawing = false;
|
||||
var btnLabel = btnFirm ? btnFirm.innerHTML : '';
|
||||
|
||||
(function scaleCanvas() {
|
||||
var ratio = window.devicePixelRatio || 1;
|
||||
@@ -928,12 +929,12 @@ function esc2(mixed $v): string {
|
||||
canvas.addEventListener('touchmove', function(e){ e.preventDefault(); if(!drawing) return; var p=getPos(e); ctx.lineTo(p.x,p.y); ctx.stroke(); }, {passive:false});
|
||||
canvas.addEventListener('touchend', function(){ drawing=false; });
|
||||
|
||||
btnLimp.addEventListener('click', function() {
|
||||
if (btnLimp) btnLimp.addEventListener('click', function() {
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
msgEl.textContent = '';
|
||||
});
|
||||
|
||||
btnFirm.addEventListener('click', function() {
|
||||
if (btnFirm) btnFirm.addEventListener('click', function() {
|
||||
var png = canvas.toDataURL('image/png');
|
||||
if (png.length < 1500) {
|
||||
msgEl.innerHTML = '<span class="text-danger"><i class="fas fa-exclamation-triangle me-1"></i>Por favor dibuje su firma antes de confirmar.</span>';
|
||||
@@ -943,23 +944,20 @@ function esc2(mixed $v): string {
|
||||
btnFirm.innerHTML = '<i class="fas fa-spinner fa-spin me-1"></i>Guardando...';
|
||||
msgEl.textContent = '';
|
||||
|
||||
// Recopilar respuestas de campos interactivos
|
||||
var campos = {};
|
||||
document.querySelectorAll('[name]').forEach(function(el) {
|
||||
var rawName = el.name;
|
||||
var isArr = rawName.slice(-2) === '[]';
|
||||
var name = isArr ? rawName.slice(0, -2) : rawName;
|
||||
if (el.type === 'checkbox') {
|
||||
if (el.checked) {
|
||||
if (!Array.isArray(campos[name])) campos[name] = [];
|
||||
campos[name].push(el.value);
|
||||
}
|
||||
if (el.checked) { if (!Array.isArray(campos[name])) campos[name] = []; campos[name].push(el.value); }
|
||||
} else if (el.type === 'radio') {
|
||||
if (el.checked) campos[name] = el.value;
|
||||
} else if (el.value !== '') {
|
||||
campos[name] = el.value;
|
||||
}
|
||||
});
|
||||
campos[cid + '_svg'] = png; // identificar qué campo firmó
|
||||
|
||||
fetch(window.location.href, {
|
||||
method: 'POST',
|
||||
@@ -969,26 +967,28 @@ function esc2(mixed $v): string {
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
if (data.ok) {
|
||||
widget.outerHTML =
|
||||
'<div class="alert alert-success mt-4 d-flex align-items-center gap-2 no-print">' +
|
||||
'<i class="fas fa-check-circle fs-4"></i>' +
|
||||
'<div><strong>Consentimiento firmado correctamente.</strong><br>' +
|
||||
'Puede cerrar esta ventana.</div></div>';
|
||||
// Notificar ventana padre si está en iframe/modal
|
||||
// Ocultar todos los demás widgets de firma (ya no se puede firmar dos veces)
|
||||
document.querySelectorAll('.turnero-firma-item').forEach(function(w) {
|
||||
w.style.display = 'none';
|
||||
});
|
||||
var ok = document.createElement('div');
|
||||
ok.className = 'alert alert-success mt-4 d-flex align-items-center gap-2 no-print';
|
||||
ok.innerHTML = '<i class="fas fa-check-circle fs-4"></i><div><strong>Firmado correctamente.</strong><br>Puede cerrar esta ventana.</div>';
|
||||
widget.parentNode.insertBefore(ok, widget.nextSibling);
|
||||
try { window.parent.postMessage({ type: 'turneroFirmado' }, '*'); } catch(e) {}
|
||||
} else {
|
||||
msgEl.innerHTML = '<span class="text-danger"><i class="fas fa-times me-1"></i>' + (data.error || 'Error al guardar') + '</span>';
|
||||
btnFirm.disabled = false;
|
||||
btnFirm.innerHTML = '<i class="fas fa-check-circle me-1"></i>Confirmar y firmar consentimiento';
|
||||
btnFirm.innerHTML = btnLabel;
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
msgEl.innerHTML = '<span class="text-danger"><i class="fas fa-times me-1"></i>Error de conexión.</span>';
|
||||
btnFirm.disabled = false;
|
||||
btnFirm.innerHTML = '<i class="fas fa-check-circle me-1"></i>Confirmar y firmar consentimiento';
|
||||
btnFirm.innerHTML = btnLabel;
|
||||
});
|
||||
});
|
||||
})();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user