feat: autocomplete CIE-10 en diagnóstico y fix tab en exámenes
- buscar_cie10.php: busca por código o descripción, límite 12 resultados - inp-diag: dropdown estilo empresa, Enter selecciona primero - selectOnTab:false en TomSelect de exámenes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
4fdc8e2c13
commit
c717d474f7
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
require_once __DIR__ . '/_helpers.php';
|
||||||
|
requireMethod('GET');
|
||||||
|
requireTurnero();
|
||||||
|
|
||||||
|
$q = trim($_GET['q'] ?? '');
|
||||||
|
if (strlen($q) < 2) { jsonOk(['items' => []]); }
|
||||||
|
|
||||||
|
$pdo = db();
|
||||||
|
$like = '%' . $q . '%';
|
||||||
|
|
||||||
|
// Código exacto primero, luego coincidencias por descripción
|
||||||
|
$stmt = $pdo->prepare(
|
||||||
|
"SELECT cod_diag, concepto
|
||||||
|
FROM cie10_diagnosticos
|
||||||
|
WHERE cod_diag LIKE ? OR concepto LIKE ?
|
||||||
|
ORDER BY CASE WHEN cod_diag LIKE ? THEN 0 ELSE 1 END, cod_diag
|
||||||
|
LIMIT 12"
|
||||||
|
);
|
||||||
|
$stmt->execute([$like, $like, $like]);
|
||||||
|
|
||||||
|
jsonOk(['items' => $stmt->fetchAll(PDO::FETCH_ASSOC)]);
|
||||||
@@ -796,7 +796,15 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
<div id="wrap-diag" class="d-none mt-2">
|
<div id="wrap-diag" class="d-none mt-2">
|
||||||
<label class="form-label mb-1 small fw-semibold">Diagnóstico (CIE-10)</label>
|
<label class="form-label mb-1 small fw-semibold">Diagnóstico (CIE-10)</label>
|
||||||
<input type="text" id="inp-diag" class="form-control form-control-sm"
|
<input type="text" id="inp-diag" class="form-control form-control-sm"
|
||||||
placeholder="Código CIE-10 diagnóstico principal" maxlength="20">
|
placeholder="Código o descripción CIE-10…"
|
||||||
|
autocomplete="off"
|
||||||
|
oninput="buscarDiag()"
|
||||||
|
onblur="setTimeout(()=>document.getElementById('diag-resultados').classList.add('d-none'),150)"
|
||||||
|
onkeydown="if(event.key==='Enter'&&_diagResultados.length){event.preventDefault();seleccionarDiag(_diagResultados[0].cod_diag,_diagResultados[0].concepto);}">
|
||||||
|
<div class="position-relative">
|
||||||
|
<ul id="diag-resultados" class="list-unstyled mb-0 border rounded bg-white shadow-sm position-absolute w-100 d-none"
|
||||||
|
style="z-index:200;max-height:200px;overflow-y:auto;top:2px"></ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Tabla de precios calculados -->
|
<!-- Tabla de precios calculados -->
|
||||||
@@ -1133,7 +1141,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
examTS = new TomSelect('#sel-examenes', {
|
examTS = new TomSelect('#sel-examenes', {
|
||||||
plugins: ['remove_button'],
|
plugins: ['remove_button'],
|
||||||
maxOptions: null,
|
maxOptions: null,
|
||||||
selectOnTab: true,
|
selectOnTab: false,
|
||||||
|
|
||||||
onItemAdd() { recalcularPrecios(); examTS.setTextboxValue(''); examTS.refreshOptions(false); },
|
onItemAdd() { recalcularPrecios(); examTS.setTextboxValue(''); examTS.refreshOptions(false); },
|
||||||
onItemRemove: () => recalcularPrecios(),
|
onItemRemove: () => recalcularPrecios(),
|
||||||
@@ -2355,6 +2363,37 @@ function quitarEmpresa() {
|
|||||||
document.getElementById('inp-diag').value = '';
|
document.getElementById('inp-diag').value = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── CIE-10 autocomplete ───────────────────────────────────────
|
||||||
|
let _diagTimer = null, _diagResultados = [];
|
||||||
|
function buscarDiag() {
|
||||||
|
clearTimeout(_diagTimer);
|
||||||
|
_diagTimer = setTimeout(_doDiagSearch, 250);
|
||||||
|
}
|
||||||
|
async function _doDiagSearch() {
|
||||||
|
const q = document.getElementById('inp-diag').value.trim();
|
||||||
|
const ul = document.getElementById('diag-resultados');
|
||||||
|
if (q.length < 2) { ul.classList.add('d-none'); return; }
|
||||||
|
const res = await fetch(`${API}buscar_cie10.php?q=${encodeURIComponent(q)}`);
|
||||||
|
const j = await res.json();
|
||||||
|
_diagResultados = j.items || [];
|
||||||
|
if (!_diagResultados.length) {
|
||||||
|
ul.innerHTML = '<li class="px-3 py-2 text-muted small">Sin resultados</li>';
|
||||||
|
ul.classList.remove('d-none'); return;
|
||||||
|
}
|
||||||
|
ul.innerHTML = _diagResultados.map((d, i) => `
|
||||||
|
<li class="px-3 py-2" style="cursor:pointer;border-bottom:1px solid #f1f5f9"
|
||||||
|
onmousedown="seleccionarDiag(${JSON.stringify(d.cod_diag)},${JSON.stringify(d.concepto)})">
|
||||||
|
<span class="fw-semibold small">${escHtml(d.cod_diag)}</span>
|
||||||
|
<span class="text-muted small ms-2">${escHtml(d.concepto)}</span>
|
||||||
|
</li>`).join('');
|
||||||
|
ul.classList.remove('d-none');
|
||||||
|
}
|
||||||
|
function seleccionarDiag(cod, concepto) {
|
||||||
|
document.getElementById('inp-diag').value = cod;
|
||||||
|
document.getElementById('diag-resultados').classList.add('d-none');
|
||||||
|
_diagResultados = [];
|
||||||
|
}
|
||||||
|
|
||||||
// ── Motor de precios ──────────────────────────────────────────
|
// ── Motor de precios ──────────────────────────────────────────
|
||||||
let _recalcTimer;
|
let _recalcTimer;
|
||||||
let _preciosActivos = [];
|
let _preciosActivos = [];
|
||||||
|
|||||||
Reference in New Issue
Block a user