feat: add medicine entry to Create Rx-Group modal on consult page
- expanded rxGroupCreateModal to modal-xl with two-column layout - left column: group info (name, complaints, diagnosis, investigation, finding) - right column: medicine form (name autocomplete, type, dose/when/freq/where, days/qty/remark) - medicine name search uses medicine_search endpoint with datalist - type auto-fills on datalist selection (same Chrome input-event fix as main form) - dose/when/freq/where selects populated from medicineDoseMasterCache (already loaded) - + Add Medicine adds to local crgcMedicineList array with live table display - Remove button (x) on each row in the pending medicine table - Save Rx-Group: creates group then batch-saves all medicines sequentially - Save & Apply: same as above then applies group to current session
This commit is contained in:
parent
2ae23c0284
commit
7dc147a397
|
|
@ -956,34 +956,75 @@
|
|||
|
||||
<!-- Create Rx-Group Modal -->
|
||||
<div class="modal fade" id="rxGroupCreateModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-md">
|
||||
<div class="modal-dialog modal-xl modal-dialog-scrollable">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Create Rx-Group</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="mb-2">
|
||||
<label class="form-label fw-semibold">Rx-Group Name <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control form-control-sm" id="crgc_name" maxlength="150" placeholder="e.g. Fever Basic">
|
||||
<div class="row g-3">
|
||||
<!-- Left: Group info -->
|
||||
<div class="col-md-5">
|
||||
<div class="fw-semibold mb-2">Group Info</div>
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Rx-Group Name <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control form-control-sm" id="crgc_name" maxlength="150" placeholder="e.g. Fever Basic">
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Complaints</label>
|
||||
<input type="text" class="form-control form-control-sm" id="crgc_complaints" maxlength="1000">
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Diagnosis</label>
|
||||
<input type="text" class="form-control form-control-sm" id="crgc_diagnosis" maxlength="1000">
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Investigation</label>
|
||||
<input type="text" class="form-control form-control-sm" id="crgc_investigation" maxlength="1000">
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Finding Examinations</label>
|
||||
<input type="text" class="form-control form-control-sm" id="crgc_finding" maxlength="1000">
|
||||
</div>
|
||||
</div>
|
||||
<!-- Right: Add medicine -->
|
||||
<div class="col-md-7">
|
||||
<div class="fw-semibold mb-2">Add Medicines</div>
|
||||
<div class="mb-2">
|
||||
<input type="text" class="form-control form-control-sm" id="crgc_med_name" list="crgc_med_suggest" placeholder="Medicine name">
|
||||
<datalist id="crgc_med_suggest"></datalist>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<input type="text" class="form-control form-control-sm" id="crgc_med_type" placeholder="Type (TAB/CAP/SYR...)">
|
||||
</div>
|
||||
<div class="row g-1 mb-2">
|
||||
<div class="col-4"><select class="form-select form-select-sm" id="crgc_med_dose"><option value="">Dose</option></select></div>
|
||||
<div class="col-4"><select class="form-select form-select-sm" id="crgc_med_when"><option value="">When</option></select></div>
|
||||
<div class="col-4"><select class="form-select form-select-sm" id="crgc_med_freq"><option value="">Freq</option></select></div>
|
||||
</div>
|
||||
<div class="row g-1 mb-2">
|
||||
<div class="col-3"><input type="text" class="form-control form-control-sm" id="crgc_med_days" placeholder="Days"></div>
|
||||
<div class="col-3"><input type="text" class="form-control form-control-sm" id="crgc_med_qty" placeholder="Qty"></div>
|
||||
<div class="col-6"><select class="form-select form-select-sm" id="crgc_med_where"><option value="">Where</option></select></div>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<input type="text" class="form-control form-control-sm" id="crgc_med_remark" placeholder="Remark">
|
||||
</div>
|
||||
<button type="button" class="btn btn-primary btn-sm" id="btn_crgc_add_med">+ Add Medicine</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Complaints</label>
|
||||
<input type="text" class="form-control form-control-sm" id="crgc_complaints" maxlength="1000">
|
||||
<!-- Medicine list -->
|
||||
<div class="mt-3" id="crgc_med_list_wrap" style="display:none;">
|
||||
<div class="fw-semibold mb-1">Medicines to Add <span class="badge bg-secondary" id="crgc_med_count">0</span></div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm table-bordered mb-0" id="crgc_med_table">
|
||||
<thead><tr><th>Medicine</th><th>Type</th><th>Dose</th><th>When</th><th>Freq</th><th>Days</th><th>Where</th><th width="60"></th></tr></thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Diagnosis</label>
|
||||
<input type="text" class="form-control form-control-sm" id="crgc_diagnosis" maxlength="1000">
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Investigation</label>
|
||||
<input type="text" class="form-control form-control-sm" id="crgc_investigation" maxlength="1000">
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Finding Examinations</label>
|
||||
<input type="text" class="form-control form-control-sm" id="crgc_finding" maxlength="1000">
|
||||
</div>
|
||||
<div class="small text-danger" id="crgc_msg" style="display:none;"></div>
|
||||
<div class="small text-danger mt-2" id="crgc_msg" style="display:none;"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary btn-sm" data-bs-dismiss="modal">Cancel</button>
|
||||
|
|
@ -4238,8 +4279,61 @@
|
|||
});
|
||||
|
||||
// ---- Create Rx-Group from consult page ----
|
||||
var crgcMedicineList = [];
|
||||
var crgcMedSuggestRows = [];
|
||||
|
||||
function populateCrgcDoseMasters() {
|
||||
var cache = medicineDoseMasterCache || { dose: [], when: [], freq: [], where: [] };
|
||||
function fill(selectId, rows, placeholder) {
|
||||
var $sel = $('#' + selectId);
|
||||
$sel.html('<option value="">' + placeholder + '</option>');
|
||||
(rows || []).forEach(function(r) {
|
||||
var val = (r.dose_sign || r.dose_sign_desc || r.name || '').toString().trim();
|
||||
var label = (r.dose_sign_desc || r.dose_sign || r.name || '').toString().trim();
|
||||
if (val) {
|
||||
$sel.append('<option value="' + $('<div>').text(val).html() + '">' + $('<div>').text(label).html() + '</option>');
|
||||
}
|
||||
});
|
||||
}
|
||||
fill('crgc_med_dose', cache.dose, 'Dose');
|
||||
fill('crgc_med_when', cache.when, 'When');
|
||||
fill('crgc_med_freq', cache.freq, 'Freq');
|
||||
fill('crgc_med_where', cache.where, 'Where');
|
||||
}
|
||||
|
||||
function renderCrgcMedicineTable() {
|
||||
var $tbody = $('#crgc_med_table tbody');
|
||||
$tbody.empty();
|
||||
if (!crgcMedicineList.length) {
|
||||
$('#crgc_med_list_wrap').hide();
|
||||
$('#crgc_med_count').text('0');
|
||||
return;
|
||||
}
|
||||
$('#crgc_med_list_wrap').show();
|
||||
$('#crgc_med_count').text(crgcMedicineList.length);
|
||||
crgcMedicineList.forEach(function(m, idx) {
|
||||
$tbody.append('<tr>'
|
||||
+ '<td>' + $('<div>').text(m.med_name).html() + '</td>'
|
||||
+ '<td>' + $('<div>').text(m.med_type).html() + '</td>'
|
||||
+ '<td>' + $('<div>').text(m.dosage).html() + '</td>'
|
||||
+ '<td>' + $('<div>').text(m.dosage_when).html() + '</td>'
|
||||
+ '<td>' + $('<div>').text(m.dosage_freq).html() + '</td>'
|
||||
+ '<td>' + $('<div>').text(m.no_of_days).html() + '</td>'
|
||||
+ '<td>' + $('<div>').text(m.dosage_where).html() + '</td>'
|
||||
+ '<td><button type="button" class="btn btn-danger btn-sm py-0 px-1 crgc-med-remove" data-idx="' + idx + '">✕</button></td>'
|
||||
+ '</tr>');
|
||||
});
|
||||
}
|
||||
|
||||
function clearCrgcMedForm() {
|
||||
$('#crgc_med_name').val('').removeData('med-id').removeData('med-type');
|
||||
$('#crgc_med_type,#crgc_med_days,#crgc_med_qty,#crgc_med_remark').val('');
|
||||
$('#crgc_med_dose,#crgc_med_when,#crgc_med_freq,#crgc_med_where').val('');
|
||||
$('#crgc_med_suggest').html('');
|
||||
crgcMedSuggestRows = [];
|
||||
}
|
||||
|
||||
function openCreateRxGroupModal() {
|
||||
// Pre-fill from current consult fields if available
|
||||
var complaints = ($('#complaints').val() || '').trim();
|
||||
var diagnosis = ($('#diagnosis').val() || '').trim();
|
||||
$('#crgc_name').val('');
|
||||
|
|
@ -4248,11 +4342,111 @@
|
|||
$('#crgc_investigation').val('');
|
||||
$('#crgc_finding').val('');
|
||||
$('#crgc_msg').hide().text('');
|
||||
crgcMedicineList = [];
|
||||
clearCrgcMedForm();
|
||||
renderCrgcMedicineTable();
|
||||
populateCrgcDoseMasters();
|
||||
try {
|
||||
bootstrap.Modal.getOrCreateInstance(document.getElementById('rxGroupCreateModal')).show();
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
// Medicine name autocomplete inside create modal
|
||||
$('#crgc_med_name').on('input', function() {
|
||||
var q = ($(this).val() || '').trim();
|
||||
if (q.length < 2) {
|
||||
crgcMedSuggestRows = [];
|
||||
$('#crgc_med_suggest').html('');
|
||||
return;
|
||||
}
|
||||
apiGet('<?= base_url('Opd_prescription/medicine_search') ?>?q=' + encodeURIComponent(q) + '&scope=active', function(data) {
|
||||
crgcMedSuggestRows = data.rows || [];
|
||||
var html = '';
|
||||
crgcMedSuggestRows.forEach(function(row) {
|
||||
html += '<option value="' + $('<div>').text(row.med_name || '').html() + '"'
|
||||
+ ' data-type="' + $('<div>').text(row.med_type || '').html() + '"></option>';
|
||||
});
|
||||
$('#crgc_med_suggest').html(html);
|
||||
|
||||
// Auto-fill type if exact name match (Chrome fires input on datalist pick)
|
||||
var currentVal = ($('#crgc_med_name').val() || '').trim().toUpperCase();
|
||||
for (var i = 0; i < crgcMedSuggestRows.length; i++) {
|
||||
if ((crgcMedSuggestRows[i].med_name || '').trim().toUpperCase() === currentVal) {
|
||||
$('#crgc_med_type').val(crgcMedSuggestRows[i].med_type || '');
|
||||
$('#crgc_med_name').data('med-id', parseInt(crgcMedSuggestRows[i].id || 0, 10));
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#crgc_med_name').on('change', function() {
|
||||
var val = ($(this).val() || '').trim().toUpperCase();
|
||||
for (var i = 0; i < crgcMedSuggestRows.length; i++) {
|
||||
if ((crgcMedSuggestRows[i].med_name || '').trim().toUpperCase() === val) {
|
||||
$('#crgc_med_type').val(crgcMedSuggestRows[i].med_type || '');
|
||||
$('#crgc_med_name').data('med-id', parseInt(crgcMedSuggestRows[i].id || 0, 10));
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('#btn_crgc_add_med').on('click', function() {
|
||||
var medName = ($('#crgc_med_name').val() || '').trim();
|
||||
if (!medName) {
|
||||
$('#crgc_med_name').focus();
|
||||
return;
|
||||
}
|
||||
crgcMedicineList.push({
|
||||
med_id: parseInt($('#crgc_med_name').data('med-id') || 0, 10),
|
||||
med_name: medName,
|
||||
med_type: ($('#crgc_med_type').val() || '').trim(),
|
||||
genericname: '',
|
||||
dosage: ($('#crgc_med_dose').val() || '').trim(),
|
||||
dosage_when: ($('#crgc_med_when').val() || '').trim(),
|
||||
dosage_freq: ($('#crgc_med_freq').val() || '').trim(),
|
||||
dosage_where: ($('#crgc_med_where').val() || '').trim(),
|
||||
no_of_days: ($('#crgc_med_days').val() || '').trim(),
|
||||
qty: ($('#crgc_med_qty').val() || '').trim(),
|
||||
remark: ($('#crgc_med_remark').val() || '').trim()
|
||||
});
|
||||
renderCrgcMedicineTable();
|
||||
clearCrgcMedForm();
|
||||
$('#crgc_med_name').focus();
|
||||
});
|
||||
|
||||
$(document).on('click', '.crgc-med-remove', function() {
|
||||
var idx = parseInt($(this).data('idx') || '0', 10);
|
||||
crgcMedicineList.splice(idx, 1);
|
||||
renderCrgcMedicineTable();
|
||||
});
|
||||
|
||||
function saveCrgcMedicines(rxId, medicines, done) {
|
||||
if (!medicines.length) {
|
||||
done();
|
||||
return;
|
||||
}
|
||||
var med = medicines[0];
|
||||
var rest = medicines.slice(1);
|
||||
var payload = {
|
||||
item_id: 0,
|
||||
med_id: med.med_id || 0,
|
||||
med_name: med.med_name,
|
||||
med_type: med.med_type,
|
||||
genericname: med.genericname || '',
|
||||
dosage: med.dosage,
|
||||
dosage_when: med.dosage_when,
|
||||
dosage_freq: med.dosage_freq,
|
||||
no_of_days: med.no_of_days,
|
||||
qty: med.qty,
|
||||
dosage_where: med.dosage_where,
|
||||
remark: med.remark
|
||||
};
|
||||
apiPost('<?= base_url('Opd_prescription/rx_group_medicine_save') ?>/' + rxId, payload, function() {
|
||||
saveCrgcMedicines(rxId, rest, done);
|
||||
});
|
||||
}
|
||||
|
||||
function saveCreateRxGroup(andApply) {
|
||||
var name = ($('#crgc_name').val() || '').trim();
|
||||
if (!name) {
|
||||
|
|
@ -4272,27 +4466,27 @@
|
|||
};
|
||||
|
||||
apiPost('<?= base_url('Opd_prescription/rx_group_save') ?>', payload, function(data) {
|
||||
$('#btn_crgc_save,#btn_crgc_save_apply').prop('disabled', false);
|
||||
if (parseInt(data.update || '0', 10) !== 1) {
|
||||
$('#btn_crgc_save,#btn_crgc_save_apply').prop('disabled', false);
|
||||
$('#crgc_msg').text(data.error_text || 'Unable to save Rx-Group.').show();
|
||||
return;
|
||||
}
|
||||
var newId = parseInt(data.insertid || '0', 10);
|
||||
var newName = name;
|
||||
var medicinesToSave = crgcMedicineList.slice();
|
||||
|
||||
// Refresh catalog cache so new group appears in selector
|
||||
loadRxGroupCatalog();
|
||||
|
||||
// Close modal
|
||||
try {
|
||||
bootstrap.Modal.getInstance(document.getElementById('rxGroupCreateModal')).hide();
|
||||
} catch (e) {}
|
||||
|
||||
$('.jsError').removeClass('text-danger text-muted').addClass('text-success').text('Rx-Group "' + newName + '" created.');
|
||||
|
||||
if (andApply && newId > 0) {
|
||||
applyRxGroupToSession(newId, newName);
|
||||
}
|
||||
saveCrgcMedicines(newId, medicinesToSave, function() {
|
||||
$('#btn_crgc_save,#btn_crgc_save_apply').prop('disabled', false);
|
||||
loadRxGroupCatalog();
|
||||
try {
|
||||
bootstrap.Modal.getInstance(document.getElementById('rxGroupCreateModal')).hide();
|
||||
} catch (e) {}
|
||||
var msgPart = medicinesToSave.length > 0 ? ' with ' + medicinesToSave.length + ' medicine(s).' : '.';
|
||||
$('.jsError').removeClass('text-danger text-muted').addClass('text-success').text('Rx-Group "' + newName + '" created' + msgPart);
|
||||
if (andApply && newId > 0) {
|
||||
applyRxGroupToSession(newId, newName);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user