IPD Discharge: add Form/Type-aware Dose/Strength autocomplete and fix Duration keyboard arrow key navigation in IPD & OPD
This commit is contained in:
parent
7f4b49a1c6
commit
c0842d1502
|
|
@ -1380,9 +1380,10 @@ $historyFields = [
|
|||
</optgroup>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="col-md-3 position-relative">
|
||||
<label class="form-label fw-semibold mb-1 text-dark">Dose / Strength</label>
|
||||
<input type="text" class="form-control shadow-sm" id="discharge_dosage" autocomplete="off" placeholder="e.g. 1 Tab / 5ml / 500mg">
|
||||
<div id="discharge_dosage_dd" style="display:none;position:absolute;left:0;right:0;top:100%;z-index:1080;background:#fff;border:1px solid #dee2e6;border-radius:.375rem;box-shadow:0 4px 12px rgba(0,0,0,.12);max-height:220px;overflow-y:auto;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -6149,6 +6150,305 @@ $historyFields = [
|
|||
});
|
||||
}
|
||||
|
||||
// ── Smart Dose / Strength Autocomplete for #discharge_dosage ─────────────────
|
||||
(function() {
|
||||
var dosageInput = document.getElementById('discharge_dosage');
|
||||
var dosageDropdown = document.getElementById('discharge_dosage_dd');
|
||||
if (!dosageInput || !dosageDropdown) return;
|
||||
|
||||
var highlightIdx = -1;
|
||||
|
||||
function getCat() {
|
||||
var ft = ($('#discharge_med_type').val() || '').toString().trim().toUpperCase();
|
||||
var mn = ($('#discharge_med_name').val() || '').toString().trim().toUpperCase();
|
||||
if (!ft) {
|
||||
if (/\b(TAB|TABLET|TABLETS)\b/i.test(mn)) ft = 'TAB';
|
||||
else if (/\b(CAP|CAPSULE|CAPSULES)\b/i.test(mn)) ft = 'CAP';
|
||||
else if (/\b(SYP|SYRUP|SUSP|SUSPENSION|SOLN|LIQUID)\b/i.test(mn)) ft = 'SYR';
|
||||
else if (/\b(INJ|INJECTION|INFUSION)\b/i.test(mn)) ft = 'INJ';
|
||||
else if (/\b(DROP|DROPS|EYE DROP|EAR DROP|NASAL DROP)\b/i.test(mn)) ft = 'DROPS';
|
||||
else if (/\b(OINT|OINTMENT|GEL|CREAM|LOTION)\b/i.test(mn)) ft = 'CREAM';
|
||||
else if (/\b(INHALER|PUFF|MDI|ROTACAP)\b/i.test(mn)) ft = 'INHALER';
|
||||
else if (/\b(RESPULE|RESPULES)\b/i.test(mn)) ft = 'RESPULES';
|
||||
else if (/\b(SACHET|GRANULES|POWDER)\b/i.test(mn)) ft = 'SACHET';
|
||||
}
|
||||
if (ft === 'TAB' || ft === 'TABLET' || ft === 'LOZENGE') return 'tablet';
|
||||
if (ft === 'CAP' || ft === 'CAPSULE') return 'capsule';
|
||||
if (ft === 'SYR' || ft === 'SUSP' || ft === 'SOLN' || ft === 'SYRUP' || ft === 'SUSPENSION') return 'syrup';
|
||||
if (ft.indexOf('DROP') !== -1 || ft === 'DROPS') return 'drops';
|
||||
if (ft === 'INHALER') return 'inhaler';
|
||||
if (ft === 'RESPULES') return 'respules';
|
||||
if (ft.indexOf('SPRAY') !== -1) return 'spray';
|
||||
if (ft === 'SACHET' || ft === 'POWDER') return 'sachet';
|
||||
if (ft === 'INJ' || ft === 'INFUSION' || ft === 'INJECTION') return 'injection';
|
||||
if (['CREAM', 'OINT', 'GEL', 'LOTION', 'SHAMPOO', 'SOAP', 'OIL', 'DUSTING POWDER', 'PAINT', 'PATCH'].indexOf(ft) !== -1) return 'topical';
|
||||
if (ft === 'SUPPOSITORY' || ft === 'ENEMA' || ft === 'PESSARY') return 'suppository';
|
||||
if (ft === 'GARGLE') return 'gargle';
|
||||
return 'general';
|
||||
}
|
||||
|
||||
var PRESETS = {
|
||||
tablet: ['1 Tab', '1/2 Tab', '2 Tab', '1/4 Tab', '1.5 Tab', '500 mg', '650 mg', '250 mg', '100 mg', '50 mg', '10 mg', '5 mg', '20 mg', '40 mg'],
|
||||
capsule: ['1 Cap', '2 Cap', '500 mg', '250 mg', '100 mg', '20 mg', '40 mg', '150 mg', '300 mg'],
|
||||
syrup: ['5 ml (1 tsp)', '10 ml (2 tsp)', '2.5 ml (1/2 tsp)', '15 ml (1 tbsp)', '2 ml', '1 ml', '3 ml', '7.5 ml', '1 tsp', '2 tsp', '1 tbsp', '20 ml'],
|
||||
drops: ['1 Drop', '2 Drops', '3 Drops', '4 Drops', '1-2 Drops', '2-3 Drops', '0.5 ml', '1 ml'],
|
||||
inhaler: ['1 Puff', '2 Puffs', '1-2 Puffs', '3 Puffs'],
|
||||
respules: ['1 Respule', '1/2 Respule', '2 Respules', '1 Respule in 2.5 ml Saline'],
|
||||
spray: ['1 Spray each nostril', '2 Sprays each nostril', '1 Spray', '2 Sprays'],
|
||||
sachet: ['1 Sachet in half glass water', '1 Sachet', '1/2 Sachet', '1 Scoop', '5 g', '10 g', '1 tsp'],
|
||||
injection: ['1 Amp', '1 Vial', '1 ml', '2 ml', '5 ml', '10 ml', '100 ml', '500 ml', '100 mg', '250 mg', '500 mg', '1 g', '1000 IU', '5000 IU'],
|
||||
topical: ['Apply Thinly', '1 Application', '1 Fingertip Unit (FTU)', 'Apply Generously', '1 Patch', 'Few Drops'],
|
||||
suppository: ['1 Suppository', '1 Pessary', '1 Enema'],
|
||||
gargle: ['10 ml with warm water', '15 ml with equal parts water', '5 ml', '10 ml'],
|
||||
general: ['1 Tab', '1/2 Tab', '2 Tab', '1 Cap', '5 ml (1 tsp)', '10 ml (2 tsp)', '2.5 ml (1/2 tsp)', '500 mg', '650 mg', '250 mg', '1 Puff', '1 Sachet', '1 Drop', '1 Amp']
|
||||
};
|
||||
|
||||
function getSuggestions(val) {
|
||||
var q = String(val || '').trim().toLowerCase();
|
||||
var cat = getCat();
|
||||
var res = [], seen = {};
|
||||
|
||||
function add(s) {
|
||||
if (!s) return;
|
||||
var k = String(s).trim();
|
||||
if (k && !seen[k.toLowerCase()]) {
|
||||
seen[k.toLowerCase()] = true;
|
||||
res.push(k);
|
||||
}
|
||||
}
|
||||
|
||||
var isHalf = (q === '1/2' || q === '0.5' || q === 'half' || q === '.5');
|
||||
var isQuarter = (q === '1/4' || q === '0.25' || q === '.25');
|
||||
var isOneAndHalf = (q === '1.5' || q === '1 1/2');
|
||||
var isTwoAndHalf = (q === '2.5' || q === '2 1/2');
|
||||
|
||||
if (isHalf) {
|
||||
if (cat === 'tablet') { add('1/2 Tab'); add('1/4 Tab'); add('1 Tab'); }
|
||||
else if (cat === 'capsule') { add('1/2 Cap'); add('1 Cap'); }
|
||||
else if (cat === 'syrup') { add('2.5 ml (1/2 tsp)'); add('1/2 tsp (2.5 ml)'); add('2.5 ml'); add('5 ml (1 tsp)'); }
|
||||
else if (cat === 'sachet') { add('1/2 Sachet'); add('1 Sachet'); }
|
||||
else if (cat === 'respules') { add('1/2 Respule'); add('1 Respule'); }
|
||||
else if (cat === 'drops') { add('0.5 ml'); add('1 Drop'); }
|
||||
else { add('1/2 Tab'); add('2.5 ml (1/2 tsp)'); add('1/2 Sachet'); add('1/2 Cap'); }
|
||||
} else if (isQuarter) {
|
||||
if (cat === 'tablet') { add('1/4 Tab'); add('1/2 Tab'); }
|
||||
else if (cat === 'syrup') { add('1.25 ml (1/4 tsp)'); }
|
||||
else { add('1/4 Tab'); }
|
||||
} else if (isOneAndHalf) {
|
||||
if (cat === 'tablet') { add('1.5 Tab'); }
|
||||
else if (cat === 'syrup') { add('7.5 ml (1.5 tsp)'); }
|
||||
else { add('1.5 Tab'); add('7.5 ml'); }
|
||||
} else if (isTwoAndHalf) {
|
||||
if (cat === 'tablet') { add('2.5 Tab'); }
|
||||
else if (cat === 'syrup') { add('2.5 ml (1/2 tsp)'); add('12.5 ml'); }
|
||||
else { add('2.5 ml'); add('2.5 Tab'); }
|
||||
}
|
||||
|
||||
var numMatch = q.match(/^(\d+(?:\.\d+)?)/);
|
||||
if (numMatch) {
|
||||
var n = parseFloat(numMatch[1]);
|
||||
var nStr = numMatch[1];
|
||||
|
||||
if (cat === 'tablet') {
|
||||
if (n === 1) { add('1 Tab'); add('1/2 Tab'); add('1/4 Tab'); add('1.5 Tab'); add('10 mg'); add('100 mg'); add('1000 mg (1 g)'); }
|
||||
else if (n === 2) { add('2 Tab'); add('2.5 Tab'); add('20 mg'); add('200 mg'); add('250 mg'); }
|
||||
else if (n === 3) { add('3 Tab'); add('30 mg'); add('300 mg'); }
|
||||
else if (n === 4) { add('4 Tab'); add('1/4 Tab'); add('40 mg'); add('400 mg'); }
|
||||
else if (n === 5) { add('500 mg'); add('50 mg'); add('5 mg'); add('1/2 Tab'); add('5 Tab'); }
|
||||
else if (n === 6) { add('650 mg'); add('60 mg'); add('6 Tab'); }
|
||||
else { if (n < 10) add(nStr + ' Tab'); add(nStr + ' mg'); add(nStr + ' mcg'); add(nStr + ' g'); }
|
||||
} else if (cat === 'capsule') {
|
||||
if (n === 1) { add('1 Cap'); add('2 Cap'); add('100 mg'); add('150 mg'); add('10 mg'); }
|
||||
else if (n === 2) { add('2 Cap'); add('20 mg'); add('200 mg'); add('250 mg'); }
|
||||
else if (n === 5) { add('500 mg'); add('50 mg'); add('5 Cap'); }
|
||||
else { if (n < 10) add(nStr + ' Cap'); add(nStr + ' mg'); add(nStr + ' mcg'); }
|
||||
} else if (cat === 'syrup') {
|
||||
if (n === 1) { add('1 tsp (5 ml)'); add('1 tbsp (15 ml)'); add('1/2 tsp (2.5 ml)'); add('1 ml'); add('10 ml (2 tsp)'); add('15 ml (1 tbsp)'); }
|
||||
else if (n === 2) { add('2 ml'); add('2.5 ml (1/2 tsp)'); add('2 tsp (10 ml)'); add('20 ml'); }
|
||||
else if (n === 3) { add('3 ml'); add('3.5 ml'); add('30 ml'); }
|
||||
else if (n === 4) { add('4 ml'); add('4.5 ml'); }
|
||||
else if (n === 5) { add('5 ml (1 tsp)'); add('5 ml'); add('2.5 ml (1/2 tsp)'); add('15 ml (1 tbsp)'); add('50 ml'); }
|
||||
else if (n === 7 || n === 7.5) { add('7.5 ml (1.5 tsp)'); add('7 ml'); }
|
||||
else if (n === 10) { add('10 ml (2 tsp)'); add('10 ml'); }
|
||||
else if (n === 15) { add('15 ml (1 tbsp)'); add('15 ml'); }
|
||||
else if (n === 20) { add('20 ml'); }
|
||||
else { add(nStr + ' ml'); if (n <= 4) add(nStr + ' tsp (' + (n * 5) + ' ml)'); if (n <= 2) add(nStr + ' tbsp (' + (n * 15) + ' ml)'); }
|
||||
} else if (cat === 'drops') {
|
||||
if (n === 1) { add('1 Drop'); add('1-2 Drops'); add('0.5 ml'); add('1 ml'); }
|
||||
else if (n === 2) { add('2 Drops'); add('2-3 Drops'); add('2 ml'); }
|
||||
else if (n === 3) { add('3 Drops'); add('3-4 Drops'); }
|
||||
else if (n === 4) { add('4 Drops'); add('4-5 Drops'); }
|
||||
else if (n === 5) { add('5 Drops'); }
|
||||
else { add(n === 1 ? '1 Drop' : (nStr + ' Drops')); add(nStr + ' ml'); }
|
||||
} else if (cat === 'inhaler') {
|
||||
if (n === 1) { add('1 Puff'); add('2 Puffs'); add('1-2 Puffs'); }
|
||||
else if (n === 2) { add('2 Puffs'); add('1-2 Puffs'); }
|
||||
else { add(n === 1 ? '1 Puff' : (nStr + ' Puffs')); }
|
||||
} else if (cat === 'respules') {
|
||||
if (n === 1) { add('1 Respule'); add('1/2 Respule'); add('2 Respules'); add('1 Respule in 2.5 ml Saline'); }
|
||||
else { add(n === 1 ? '1 Respule' : (nStr + ' Respules')); }
|
||||
} else if (cat === 'spray') {
|
||||
if (n === 1) { add('1 Spray each nostril'); add('2 Sprays each nostril'); add('1 Spray'); add('2 Sprays'); }
|
||||
else { add(nStr + ' Sprays each nostril'); add(nStr + ' Sprays'); }
|
||||
} else if (cat === 'sachet') {
|
||||
if (n === 1) { add('1 Sachet in half glass water'); add('1 Sachet'); add('1/2 Sachet'); add('1 Scoop'); add('5 g'); add('10 g'); }
|
||||
else { add(nStr + ' Sachets'); add(nStr + ' g'); }
|
||||
} else if (cat === 'injection') {
|
||||
if (n === 1) { add('1 Amp'); add('1 Vial'); add('1 ml'); add('10 ml'); add('100 ml'); add('500 ml'); add('100 mg'); add('1 g'); add('1000 IU'); }
|
||||
else if (n === 2) { add('2 ml'); add('2 Amp'); add('2 Vial'); add('250 mg'); add('2 g'); }
|
||||
else if (n === 5) { add('5 ml'); add('500 mg'); add('500 ml (IV)'); add('5000 IU'); }
|
||||
else { add(nStr + ' ml'); add(nStr + ' Amp'); add(nStr + ' Vial'); add(nStr + ' mg'); }
|
||||
} else if (cat === 'topical') {
|
||||
if (n === 1) { add('1 Application'); add('1 Fingertip Unit (FTU)'); add('1 Patch'); add('Apply Thinly'); }
|
||||
else { add(nStr + ' Applications'); add(nStr + ' Patches'); }
|
||||
} else if (cat === 'suppository') {
|
||||
add(nStr + ' Suppository'); add(nStr + ' Pessary'); add(nStr + ' Enema');
|
||||
} else if (cat === 'gargle') {
|
||||
add(nStr + '0 ml in half cup warm water'); add(nStr + ' ml');
|
||||
} else {
|
||||
if (n === 1) { add('1 Tab'); add('1/2 Tab'); add('1 Cap'); add('1 tsp (5 ml)'); add('1 ml'); add('1 Puff'); add('1 Sachet'); add('1 Drop'); add('1 Amp'); add('100 mg'); add('500 mg'); }
|
||||
else if (n === 2) { add('2 Tab'); add('2 Cap'); add('2 tsp (10 ml)'); add('2 ml'); add('2.5 ml (1/2 tsp)'); add('2 Puffs'); add('2 Drops'); add('250 mg'); }
|
||||
else if (n === 5) { add('5 ml (1 tsp)'); add('500 mg'); add('50 mg'); add('5 mg'); add('5 Drops'); add('5 g'); }
|
||||
else { add(nStr + ' Tab'); add(nStr + ' ml'); add(nStr + ' mg'); add(nStr + ' Cap'); }
|
||||
}
|
||||
}
|
||||
|
||||
var presets = PRESETS[cat] || PRESETS.general;
|
||||
presets.forEach(function(p) {
|
||||
if (!q || p.toLowerCase().indexOf(q) !== -1) {
|
||||
add(p);
|
||||
}
|
||||
});
|
||||
|
||||
if (doseMasterCache && Array.isArray(doseMasterCache.dose)) {
|
||||
doseMasterCache.dose.forEach(function(item) {
|
||||
var label = (item.label || item.name || '').toString().trim();
|
||||
if (label && (!q || label.toLowerCase().indexOf(q) !== -1)) {
|
||||
add(label);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return res.slice(0, 12);
|
||||
}
|
||||
|
||||
function updateHighlight(items, updateInput) {
|
||||
items.forEach(function(el, i) {
|
||||
if (i === highlightIdx) {
|
||||
el.style.backgroundColor = '#0d6efd';
|
||||
el.style.color = '#ffffff';
|
||||
el.style.fontWeight = '600';
|
||||
if (updateInput) {
|
||||
dosageInput.value = el.getAttribute('data-val') || el.innerText.trim();
|
||||
}
|
||||
var cTop = dosageDropdown.scrollTop;
|
||||
var cBottom = cTop + dosageDropdown.clientHeight;
|
||||
var eTop = el.offsetTop;
|
||||
var eBottom = eTop + el.offsetHeight;
|
||||
if (eTop < cTop) {
|
||||
dosageDropdown.scrollTop = eTop;
|
||||
} else if (eBottom > cBottom) {
|
||||
dosageDropdown.scrollTop = eBottom - dosageDropdown.clientHeight;
|
||||
}
|
||||
} else {
|
||||
el.style.backgroundColor = '';
|
||||
el.style.color = '';
|
||||
el.style.fontWeight = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function renderDropdown(items) {
|
||||
if (!items.length) {
|
||||
dosageDropdown.style.display = 'none';
|
||||
dosageDropdown.innerHTML = '';
|
||||
highlightIdx = -1;
|
||||
return;
|
||||
}
|
||||
var html = '';
|
||||
items.forEach(function(item, i) {
|
||||
html += '<div class="px-3 py-2 border-bottom discharge-dosage-opt" data-val="' + $('<div>').text(item).html() + '" style="cursor:pointer;font-size:13px;">' + $('<div>').text(item).html() + '</div>';
|
||||
});
|
||||
dosageDropdown.innerHTML = html;
|
||||
dosageDropdown.style.display = 'block';
|
||||
var els = dosageDropdown.querySelectorAll('.discharge-dosage-opt');
|
||||
els.forEach(function(el, idx) {
|
||||
el.addEventListener('mouseenter', function() {
|
||||
highlightIdx = idx;
|
||||
updateHighlight(els, false);
|
||||
});
|
||||
el.addEventListener('mousedown', function(e) { e.preventDefault(); });
|
||||
el.addEventListener('click', function() {
|
||||
dosageInput.value = this.getAttribute('data-val');
|
||||
dosageDropdown.style.display = 'none';
|
||||
highlightIdx = -1;
|
||||
var freq = document.getElementById('discharge_dosage_freq');
|
||||
if (freq) freq.focus();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
dosageInput.addEventListener('focus', function() {
|
||||
var sugs = getSuggestions(dosageInput.value);
|
||||
highlightIdx = -1;
|
||||
renderDropdown(sugs);
|
||||
});
|
||||
|
||||
dosageInput.addEventListener('input', function() {
|
||||
var sugs = getSuggestions(dosageInput.value);
|
||||
highlightIdx = -1;
|
||||
renderDropdown(sugs);
|
||||
});
|
||||
|
||||
dosageInput.addEventListener('blur', function() {
|
||||
setTimeout(function() { dosageDropdown.style.display = 'none'; highlightIdx = -1; }, 200);
|
||||
});
|
||||
|
||||
dosageInput.addEventListener('keydown', function(e) {
|
||||
var items = dosageDropdown.querySelectorAll('.discharge-dosage-opt');
|
||||
var isVisible = dosageDropdown.style.display === 'block' && items.length > 0;
|
||||
|
||||
if (e.key === 'ArrowDown') {
|
||||
e.preventDefault();
|
||||
if (!isVisible) {
|
||||
var sugs = getSuggestions(dosageInput.value);
|
||||
renderDropdown(sugs);
|
||||
items = dosageDropdown.querySelectorAll('.discharge-dosage-opt');
|
||||
highlightIdx = 0;
|
||||
updateHighlight(items, true);
|
||||
return;
|
||||
}
|
||||
highlightIdx = (highlightIdx + 1) % items.length;
|
||||
updateHighlight(items, true);
|
||||
} else if (e.key === 'ArrowUp') {
|
||||
if (!isVisible) return;
|
||||
e.preventDefault();
|
||||
highlightIdx = (highlightIdx - 1 + items.length) % items.length;
|
||||
updateHighlight(items, true);
|
||||
} else if (e.key === 'Enter' || e.key === 'Tab') {
|
||||
if (isVisible) {
|
||||
if (e.key === 'Enter') e.preventDefault();
|
||||
if (highlightIdx >= 0 && items[highlightIdx]) {
|
||||
dosageInput.value = items[highlightIdx].getAttribute('data-val');
|
||||
}
|
||||
dosageDropdown.style.display = 'none';
|
||||
highlightIdx = -1;
|
||||
var freq = document.getElementById('discharge_dosage_freq');
|
||||
if (freq) freq.focus();
|
||||
}
|
||||
} else if (e.key === 'Escape') {
|
||||
dosageDropdown.style.display = 'none';
|
||||
highlightIdx = -1;
|
||||
}
|
||||
});
|
||||
|
||||
window.refreshDischargeDosageDropdown = function() {
|
||||
if (dosageDropdown.style.display === 'block' || document.activeElement === dosageInput) {
|
||||
renderDropdown(getSuggestions(dosageInput.value));
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
// ── Smart Frequency Autocomplete for #discharge_dosage_freq ─────────────────
|
||||
(function() {
|
||||
var freqInput = document.getElementById('discharge_dosage_freq');
|
||||
|
|
@ -6258,32 +6558,39 @@ $historyFields = [
|
|||
|
||||
if (e.key === 'ArrowDown') {
|
||||
e.preventDefault();
|
||||
highlightIdx = (highlightIdx + 1) % sugs.length;
|
||||
if (freqDropdown.style.display === 'none') {
|
||||
renderDropdown(sugs);
|
||||
highlightIdx = 0;
|
||||
} else {
|
||||
highlightIdx = (highlightIdx + 1) % sugs.length;
|
||||
}
|
||||
renderDropdown(sugs);
|
||||
} else if (e.key === 'ArrowUp') {
|
||||
e.preventDefault();
|
||||
highlightIdx = (highlightIdx - 1 + sugs.length) % sugs.length;
|
||||
renderDropdown(sugs);
|
||||
} else if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
if (highlightIdx >= 0 && sugs[highlightIdx]) {
|
||||
freqInput.value = sugs[highlightIdx].code;
|
||||
}
|
||||
freqDropdown.style.display = 'none';
|
||||
var whenSelect = document.getElementById('discharge_dosage_when');
|
||||
if (whenSelect) whenSelect.focus();
|
||||
} else if (e.key === 'ArrowUp') {
|
||||
if (freqDropdown.style.display === 'none') return;
|
||||
e.preventDefault();
|
||||
highlightIdx = (highlightIdx - 1 + sugs.length) % sugs.length;
|
||||
renderDropdown(sugs);
|
||||
if (highlightIdx >= 0 && sugs[highlightIdx]) {
|
||||
freqInput.value = sugs[highlightIdx].code;
|
||||
}
|
||||
} else if (e.key === 'Enter' || e.key === 'Tab') {
|
||||
if (freqDropdown.style.display === 'block') {
|
||||
if (e.key === 'Enter') e.preventDefault();
|
||||
if (highlightIdx >= 0 && sugs[highlightIdx]) {
|
||||
freqInput.value = sugs[highlightIdx].code;
|
||||
}
|
||||
freqDropdown.style.display = 'none';
|
||||
var whenSelect = document.getElementById('discharge_dosage_when');
|
||||
if (whenSelect) whenSelect.focus();
|
||||
}
|
||||
} else if (e.key === 'Escape') {
|
||||
freqDropdown.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('click', '.discharge-freq-opt', function() {
|
||||
freqInput.value = $(this).data('code');
|
||||
freqDropdown.style.display = 'none';
|
||||
var whenSelect = document.getElementById('discharge_dosage_when');
|
||||
if (whenSelect) whenSelect.focus();
|
||||
});
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
if (!freqInput.contains(e.target) && !freqDropdown.contains(e.target)) {
|
||||
freqDropdown.style.display = 'none';
|
||||
|
|
@ -6297,20 +6604,61 @@ $historyFields = [
|
|||
var daysDropdown = document.getElementById('discharge_no_of_days_dd');
|
||||
if (!daysInput || !daysDropdown) return;
|
||||
|
||||
var _DURATION_PRESETS = [
|
||||
'1 Day', '2 Days', '3 Days', '4 Days', '5 Days', '6 Days', '7 Days',
|
||||
'10 Days', '14 Days', '15 Days', '21 Days', '1 Month', '2 Months', '3 Months'
|
||||
];
|
||||
var selectedIdx = -1;
|
||||
|
||||
function buildOptions(val) {
|
||||
val = String(val || '').trim();
|
||||
var num = parseInt(val, 10);
|
||||
if (isNaN(num) || num <= 0) return [];
|
||||
var unitDays = num === 1 ? 'Day' : 'Days';
|
||||
var unitWeeks = num === 1 ? 'Week' : 'Weeks';
|
||||
var unitMonths = num === 1 ? 'Month' : 'Months';
|
||||
return [
|
||||
num + ' ' + unitDays,
|
||||
num + ' ' + unitWeeks,
|
||||
num + ' ' + unitMonths
|
||||
];
|
||||
var q = String(val || '').trim().toLowerCase();
|
||||
var suggestions = [], seen = {};
|
||||
|
||||
var numMatch = q.match(/^(\d+)/);
|
||||
if (numMatch) {
|
||||
var n = parseInt(numMatch[1], 10);
|
||||
var unitDays = n === 1 ? '1 Day' : (n + ' Days');
|
||||
var unitWeeks = n === 1 ? '1 Week' : (n + ' Weeks');
|
||||
var unitMonths = n === 1 ? '1 Month' : (n + ' Months');
|
||||
|
||||
[unitDays, unitWeeks, unitMonths].forEach(function(s) {
|
||||
if (!seen[s.toLowerCase()]) { seen[s.toLowerCase()] = true; suggestions.push(s); }
|
||||
});
|
||||
}
|
||||
|
||||
_DURATION_PRESETS.forEach(function(p) {
|
||||
if (!q || p.toLowerCase().indexOf(q) !== -1) {
|
||||
if (!seen[p.toLowerCase()]) { seen[p.toLowerCase()] = true; suggestions.push(p); }
|
||||
}
|
||||
});
|
||||
|
||||
return suggestions.slice(0, 10);
|
||||
}
|
||||
|
||||
function updateHighlight(items, updateInput) {
|
||||
items.forEach(function(el, i) {
|
||||
if (i === selectedIdx) {
|
||||
el.style.backgroundColor = '#0d6efd';
|
||||
el.style.color = '#ffffff';
|
||||
el.style.fontWeight = '600';
|
||||
if (updateInput) {
|
||||
daysInput.value = el.getAttribute('data-val') || el.innerText.trim();
|
||||
}
|
||||
var cTop = daysDropdown.scrollTop;
|
||||
var cBottom = cTop + daysDropdown.clientHeight;
|
||||
var eTop = el.offsetTop;
|
||||
var eBottom = eTop + el.offsetHeight;
|
||||
if (eTop < cTop) {
|
||||
daysDropdown.scrollTop = eTop;
|
||||
} else if (eBottom > cBottom) {
|
||||
daysDropdown.scrollTop = eBottom - daysDropdown.clientHeight;
|
||||
}
|
||||
} else {
|
||||
el.style.backgroundColor = '';
|
||||
el.style.color = '';
|
||||
el.style.fontWeight = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function renderDropdown(items) {
|
||||
|
|
@ -6321,60 +6669,94 @@ $historyFields = [
|
|||
return;
|
||||
}
|
||||
var html = '';
|
||||
items.forEach(function(item, i) {
|
||||
html += '<a href="javascript:void(0)" class="dropdown-item discharge-days-opt ' + (i === selectedIdx ? 'active' : '') + '" data-val="' + $('<div>').text(item).html() + '" style="font-size:12px; padding:4px 12px;">' + $('<div>').text(item).html() + '</a>';
|
||||
items.forEach(function(item) {
|
||||
html += '<div class="px-3 py-2 border-bottom discharge-days-opt" data-val="' + $('<div>').text(item).html() + '" style="cursor:pointer;font-size:13px;">' + $('<div>').text(item).html() + '</div>';
|
||||
});
|
||||
daysDropdown.innerHTML = html;
|
||||
daysDropdown.style.display = 'block';
|
||||
|
||||
var els = daysDropdown.querySelectorAll('.discharge-days-opt');
|
||||
els.forEach(function(el, idx) {
|
||||
el.addEventListener('mouseenter', function() {
|
||||
selectedIdx = idx;
|
||||
updateHighlight(els, false);
|
||||
});
|
||||
el.addEventListener('mousedown', function(e) { e.preventDefault(); });
|
||||
el.addEventListener('click', function() {
|
||||
daysInput.value = this.getAttribute('data-val') || this.innerText.trim();
|
||||
daysDropdown.style.display = 'none';
|
||||
selectedIdx = -1;
|
||||
var remark = document.getElementById('discharge_remark');
|
||||
if (remark) remark.focus();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
daysInput.addEventListener('focus', function() {
|
||||
var items = buildOptions(daysInput.value);
|
||||
selectedIdx = -1;
|
||||
renderDropdown(items);
|
||||
});
|
||||
|
||||
daysInput.addEventListener('input', function() {
|
||||
var items = buildOptions(daysInput.value);
|
||||
selectedIdx = items.length ? 0 : -1;
|
||||
selectedIdx = -1;
|
||||
renderDropdown(items);
|
||||
});
|
||||
|
||||
daysInput.addEventListener('blur', function() {
|
||||
setTimeout(function() { daysDropdown.style.display = 'none'; selectedIdx = -1; }, 200);
|
||||
});
|
||||
|
||||
daysInput.addEventListener('keydown', function(e) {
|
||||
var items = daysDropdown.querySelectorAll('.discharge-days-opt');
|
||||
if (!items.length || daysDropdown.style.display === 'none') {
|
||||
if (e.key === 'Enter') {
|
||||
var isVisible = daysDropdown.style.display === 'block' && items.length > 0;
|
||||
|
||||
if (e.key === 'ArrowDown') {
|
||||
e.preventDefault();
|
||||
if (!isVisible) {
|
||||
var opts = buildOptions(daysInput.value);
|
||||
renderDropdown(opts);
|
||||
items = daysDropdown.querySelectorAll('.discharge-days-opt');
|
||||
if (!items.length) return;
|
||||
selectedIdx = 0;
|
||||
updateHighlight(items, true);
|
||||
return;
|
||||
}
|
||||
if (selectedIdx < 0) {
|
||||
selectedIdx = 0;
|
||||
} else {
|
||||
selectedIdx = (selectedIdx + 1) % items.length;
|
||||
}
|
||||
updateHighlight(items, true);
|
||||
} else if (e.key === 'ArrowUp') {
|
||||
if (!isVisible) return;
|
||||
e.preventDefault();
|
||||
if (selectedIdx < 0) {
|
||||
selectedIdx = items.length - 1;
|
||||
} else {
|
||||
selectedIdx = (selectedIdx - 1 + items.length) % items.length;
|
||||
}
|
||||
updateHighlight(items, true);
|
||||
} else if (e.key === 'Enter' || e.key === 'Tab') {
|
||||
if (isVisible) {
|
||||
if (e.key === 'Enter') e.preventDefault();
|
||||
var targetIdx = selectedIdx >= 0 ? selectedIdx : 0;
|
||||
if (items[targetIdx]) {
|
||||
daysInput.value = items[targetIdx].getAttribute('data-val') || items[targetIdx].innerText.trim();
|
||||
}
|
||||
daysDropdown.style.display = 'none';
|
||||
selectedIdx = -1;
|
||||
var remark = document.getElementById('discharge_remark');
|
||||
if (remark) remark.focus();
|
||||
} else if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
var remark = document.getElementById('discharge_remark');
|
||||
if (remark) remark.focus();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (e.key === 'ArrowDown') {
|
||||
e.preventDefault();
|
||||
selectedIdx = (selectedIdx + 1) % items.length;
|
||||
renderDropdown(buildOptions(daysInput.value));
|
||||
} else if (e.key === 'ArrowUp') {
|
||||
e.preventDefault();
|
||||
selectedIdx = (selectedIdx - 1 + items.length) % items.length;
|
||||
renderDropdown(buildOptions(daysInput.value));
|
||||
} else if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
if (selectedIdx >= 0 && items[selectedIdx]) {
|
||||
daysInput.value = items[selectedIdx].getAttribute('data-val');
|
||||
}
|
||||
daysDropdown.style.display = 'none';
|
||||
var remark = document.getElementById('discharge_remark');
|
||||
if (remark) remark.focus();
|
||||
} else if (e.key === 'Escape') {
|
||||
daysDropdown.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('click', '.discharge-days-opt', function() {
|
||||
daysInput.value = $(this).data('val');
|
||||
daysDropdown.style.display = 'none';
|
||||
var remark = document.getElementById('discharge_remark');
|
||||
if (remark) remark.focus();
|
||||
});
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
if (!daysInput.contains(e.target) && !daysDropdown.contains(e.target)) {
|
||||
daysDropdown.style.display = 'none';
|
||||
selectedIdx = -1;
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
|
@ -6593,6 +6975,9 @@ $historyFields = [
|
|||
|
||||
$('#discharge_med_type').on('change input', function() {
|
||||
autoSelectDischargeRoute($(this).val());
|
||||
if (window.refreshDischargeDosageDropdown) {
|
||||
window.refreshDischargeDosageDropdown();
|
||||
}
|
||||
});
|
||||
|
||||
function applyDischargeMedicineMatch(matched) {
|
||||
|
|
|
|||
|
|
@ -6433,16 +6433,23 @@
|
|||
general: ['1 Tab', '1/2 Tab', '2 Tab', '1 Cap', '5 ml (1 tsp)', '10 ml (2 tsp)', '2.5 ml (1/2 tsp)', '500 mg', '650 mg', '250 mg', '1 Puff', '1 Sachet', '1 Drop', '1 Amp']
|
||||
};
|
||||
|
||||
function highlightMedDosageItem(idx) {
|
||||
function highlightMedDosageItem(idx, updateInput) {
|
||||
var $items = $('#med_dosage_dd .med-dosage-dd-item');
|
||||
if (!$items.length) return;
|
||||
if (idx < 0) idx = 0;
|
||||
if (idx >= $items.length) idx = $items.length - 1;
|
||||
medDosageHighlightIdx = idx;
|
||||
|
||||
$items.css('background', '').removeClass('active-dd-item');
|
||||
$items.css({ 'background': '', 'color': '', 'font-weight': '' }).removeClass('active-dd-item');
|
||||
var $target = $items.eq(medDosageHighlightIdx);
|
||||
$target.css('background', '#e2ebff').addClass('active-dd-item');
|
||||
$target.css({ 'background': '#0d6efd', 'color': '#ffffff', 'font-weight': '600' }).addClass('active-dd-item');
|
||||
|
||||
if (updateInput) {
|
||||
var val = $target.text().trim();
|
||||
if (val) {
|
||||
$('#med_dosage').val(val);
|
||||
}
|
||||
}
|
||||
|
||||
var container = document.getElementById('med_dosage_dd');
|
||||
var elem = $target[0];
|
||||
|
|
@ -6819,27 +6826,33 @@
|
|||
if (!isVisible) {
|
||||
var sugs = getMedDosageSuggestions(($(this).val() || '').trim());
|
||||
renderMedDosageDropdown(sugs);
|
||||
highlightMedDosageItem(0);
|
||||
highlightMedDosageItem(0, true);
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
var nextIdx = medDosageHighlightIdx + 1;
|
||||
if (nextIdx >= $items.length) nextIdx = 0;
|
||||
highlightMedDosageItem(nextIdx);
|
||||
highlightMedDosageItem(nextIdx, true);
|
||||
} else if (e.key === 'ArrowUp') {
|
||||
if (!isVisible) return;
|
||||
e.preventDefault();
|
||||
var prevIdx = medDosageHighlightIdx - 1;
|
||||
if (prevIdx < 0) prevIdx = $items.length - 1;
|
||||
highlightMedDosageItem(prevIdx);
|
||||
} else if (e.key === 'Enter') {
|
||||
highlightMedDosageItem(prevIdx, true);
|
||||
} else if (e.key === 'Enter' || e.key === 'Tab') {
|
||||
if (isVisible) {
|
||||
e.preventDefault();
|
||||
var targetIdx = medDosageHighlightIdx >= 0 ? medDosageHighlightIdx : 0;
|
||||
var $target = $items.eq(targetIdx);
|
||||
if ($target.length) {
|
||||
$target.trigger('click');
|
||||
if (e.key === 'Enter') e.preventDefault();
|
||||
$('#med_dosage').val($target.text().trim()).trigger('change');
|
||||
$dd.hide().empty();
|
||||
medDosageHighlightIdx = -1;
|
||||
setTimeout(function() { $('#med_freq').focus(); }, 30);
|
||||
}
|
||||
} else if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
setTimeout(function() { $('#med_freq').focus(); }, 30);
|
||||
}
|
||||
} else if (e.key === 'Escape') {
|
||||
$dd.hide().empty();
|
||||
|
|
@ -7013,16 +7026,23 @@
|
|||
];
|
||||
var medDaysHighlightIdx = -1;
|
||||
|
||||
function highlightMedDaysItem(idx) {
|
||||
function highlightMedDaysItem(idx, updateInput) {
|
||||
var $items = $('#med_days_dd .med-days-dd-item');
|
||||
if (!$items.length) return;
|
||||
if (idx < 0) idx = 0;
|
||||
if (idx >= $items.length) idx = $items.length - 1;
|
||||
medDaysHighlightIdx = idx;
|
||||
|
||||
$items.css('background', '').removeClass('active-dd-item');
|
||||
$items.css({ 'background': '', 'color': '', 'font-weight': '' }).removeClass('active-dd-item');
|
||||
var $target = $items.eq(medDaysHighlightIdx);
|
||||
$target.css('background', '#e2ebff').addClass('active-dd-item');
|
||||
$target.css({ 'background': '#0d6efd', 'color': '#ffffff', 'font-weight': '600' }).addClass('active-dd-item');
|
||||
|
||||
if (updateInput) {
|
||||
var val = $target.text().trim();
|
||||
if (val) {
|
||||
$('#med_days').val(val);
|
||||
}
|
||||
}
|
||||
|
||||
var container = document.getElementById('med_days_dd');
|
||||
var elem = $target[0];
|
||||
|
|
@ -7103,28 +7123,33 @@
|
|||
if (!isVisible) {
|
||||
var sugs = getMedDaysSuggestions(($(this).val() || '').trim());
|
||||
renderMedDaysDropdown(sugs);
|
||||
highlightMedDaysItem(0);
|
||||
highlightMedDaysItem(0, true);
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
var nextIdx = medDaysHighlightIdx + 1;
|
||||
if (nextIdx >= $items.length) nextIdx = 0;
|
||||
highlightMedDaysItem(nextIdx);
|
||||
highlightMedDaysItem(nextIdx, true);
|
||||
} else if (e.key === 'ArrowUp') {
|
||||
if (!isVisible) return;
|
||||
e.preventDefault();
|
||||
var prevIdx = medDaysHighlightIdx - 1;
|
||||
if (prevIdx < 0) prevIdx = $items.length - 1;
|
||||
highlightMedDaysItem(prevIdx);
|
||||
} else if (e.key === 'Enter') {
|
||||
highlightMedDaysItem(prevIdx, true);
|
||||
} else if (e.key === 'Enter' || e.key === 'Tab') {
|
||||
if (isVisible) {
|
||||
e.preventDefault();
|
||||
var targetIdx = medDaysHighlightIdx >= 0 ? medDaysHighlightIdx : 0;
|
||||
var $target = $items.eq(targetIdx);
|
||||
if ($target.length) {
|
||||
$target.trigger('click');
|
||||
if (e.key === 'Enter') e.preventDefault();
|
||||
$('#med_days').val($target.text().trim()).trigger('change');
|
||||
$dd.hide().empty();
|
||||
medDaysHighlightIdx = -1;
|
||||
setTimeout(function() { $('#med_remark').focus(); }, 30);
|
||||
}
|
||||
} else if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
setTimeout(function() { $('#med_remark').focus(); }, 30);
|
||||
}
|
||||
} else if (e.key === 'Escape') {
|
||||
$dd.hide().empty();
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user