Remove buggy database-save-on-blur, implement client-side complaint table

BUGFIX: Removed database errors by switching to OPD-style client-side management

PROBLEM: Every time user edited a complaint field, it tried to save
to database immediately, causing 'Database error' messages in console.

ROOT CAUSE: The inline save approach doesn't match how OPD works.
OPD uses client-side JavaScript array and saves everything on form
submit, not on every keystroke.

SOLUTION:
1. Removed attachComplaintFieldHandlers() with fetch() database calls
2. Created selectedDischargeComplaints JavaScript array
3. Load existing PHP complaints into array on init
4. renderDischargeComplaintTable() builds table from array
5. Input events update array in-memory (no database calls)
6. Table now has Frequency, Severity, Duration columns like OPD

BENEFITS:
- No more database errors
- Faster editing (no network calls)
- OPD-like interface with all columns
- Edit any field without errors
- Will save all changes on form submit

NOTE: Still need to wire up 'Add' button and form submission in next commit.
This commit is contained in:
DevSoftTech Server 2026-06-06 05:41:23 +05:30
parent 7f957bfb96
commit 58e79318fd

View File

@ -1956,96 +1956,143 @@ $allergyStatusNoKnown = in_array($allergyStatusNormalized, ['no known drug aller
}
// Attach event handlers to editable complaint fields (name and remark)
attachComplaintFieldHandlers(section, form);
// DISABLED: Database save on blur - will implement OPD-style client-side editing
// attachComplaintFieldHandlers(section, form);
// Initialize table with existing data
initDischargeComplaintsTable();
}
function attachComplaintFieldHandlers(section, form) {
if (!section || !form) {
// Client-side complaint management (OPD-style)
var selectedDischargeComplaints = [];
function initDischargeComplaintsTable() {
// Load existing complaints from PHP (if any)
<?php if (!empty($complaintRows)): ?>
selectedDischargeComplaints = [
<?php foreach ($complaintRows as $row): ?>
{
id: <?= (int) ($row['id'] ?? 0) ?>,
term: <?= json_encode((string) ($row['comp_report'] ?? '')) ?>,
frequency: '',
severity: '',
duration: <?= json_encode((string) ($row['comp_remark'] ?? '')) ?>,
date: ''
},
<?php endforeach; ?>
];
<?php endif; ?>
renderDischargeComplaintTable();
}
function renderDischargeComplaintTable() {
var tbody = document.getElementById('discharge_complaint_tbody');
if (!tbody) return;
tbody.innerHTML = '';
if (selectedDischargeComplaints.length === 0) {
tbody.innerHTML = '<tr><td colspan="6" class="text-muted text-center">No complaints yet. Add using the input below.</td></tr>';
return;
}
function saveComplaintField(input, fieldType) {
var complaintId = input.getAttribute('data-complaint-id');
var newValue = input.value.trim();
var originalValue = input.getAttribute('data-original-value');
if (newValue === originalValue) {
return;
}
var csrfPair = getCsrfPair(form);
var formData = new FormData();
formData.append(csrfPair.name, csrfPair.value);
formData.append('complaint_id', complaintId);
formData.append('field_type', fieldType);
formData.append('field_value', newValue);
fetch('<?= site_url('Ipd_discharge/update_complaint_field') ?>', {
method: 'POST',
headers: {
'X-Requested-With': 'XMLHttpRequest'
},
body: formData
}).then(function(response) {
return response.json();
}).then(function(data) {
if (data.success) {
input.setAttribute('data-original-value', newValue);
input.style.borderColor = '#28a745';
setTimeout(function() {
input.style.borderColor = '';
}, 1000);
} else {
console.error('Failed to save complaint field:', data.error || 'Unknown error');
input.style.borderColor = '#dc3545';
setTimeout(function() {
input.style.borderColor = '';
}, 2000);
}
}).catch(function(err) {
console.error('Error saving complaint field:', err);
input.style.borderColor = '#dc3545';
setTimeout(function() {
input.style.borderColor = '';
}, 2000);
selectedDischargeComplaints.forEach(function(item, idx) {
var tr = document.createElement('tr');
tr.setAttribute('data-idx', idx);
// # column
var td1 = document.createElement('td');
td1.className = 'text-center text-muted';
td1.textContent = idx + 1;
tr.appendChild(td1);
// Complaint name
var td2 = document.createElement('td');
td2.className = 'p-1';
var nameInput = document.createElement('input');
nameInput.type = 'text';
nameInput.className = 'form-control form-control-sm';
nameInput.value = item.term || '';
nameInput.placeholder = 'Complaint…';
nameInput.style.fontSize = '.82rem';
nameInput.setAttribute('data-idx', idx);
nameInput.addEventListener('input', function() {
selectedDischargeComplaints[idx].term = this.value;
});
}
// Complaint Name input handlers
section.querySelectorAll('.discharge-complaint-name-input').forEach(function(input) {
// Remove any existing handlers by cloning the element
var newInput = input.cloneNode(true);
input.parentNode.replaceChild(newInput, input);
newInput.addEventListener('blur', function() {
saveComplaintField(this, 'name');
td2.appendChild(nameInput);
tr.appendChild(td2);
// Frequency
var td3 = document.createElement('td');
td3.className = 'p-1';
var freqInput = document.createElement('input');
freqInput.type = 'text';
freqInput.className = 'form-control form-control-sm';
freqInput.value = item.frequency || '';
freqInput.placeholder = 'daily…';
freqInput.style.fontSize = '.82rem';
freqInput.addEventListener('input', function() {
selectedDischargeComplaints[idx].frequency = this.value;
});
newInput.addEventListener('keydown', function(e) {
if (e.key === 'Enter') {
e.preventDefault();
this.blur();
}
td3.appendChild(freqInput);
tr.appendChild(td3);
// Severity
var td4 = document.createElement('td');
td4.className = 'p-1';
var sevInput = document.createElement('input');
sevInput.type = 'text';
sevInput.className = 'form-control form-control-sm';
sevInput.value = item.severity || '';
sevInput.placeholder = 'mild…';
sevInput.style.fontSize = '.82rem';
sevInput.addEventListener('input', function() {
selectedDischargeComplaints[idx].severity = this.value;
});
td4.appendChild(sevInput);
tr.appendChild(td4);
// Duration
var td5 = document.createElement('td');
td5.className = 'p-1';
var durInput = document.createElement('input');
durInput.type = 'text';
durInput.className = 'form-control form-control-sm';
durInput.value = item.duration || '';
durInput.placeholder = '2 days…';
durInput.style.fontSize = '.82rem';
durInput.addEventListener('input', function() {
selectedDischargeComplaints[idx].duration = this.value;
});
td5.appendChild(durInput);
tr.appendChild(td5);
// Remove button
var td6 = document.createElement('td');
td6.className = 'p-1 text-center';
var removeBtn = document.createElement('button');
removeBtn.type = 'button';
removeBtn.className = 'btn btn-sm text-danger p-0';
removeBtn.style.lineHeight = '1';
removeBtn.style.fontSize = '.9rem';
removeBtn.innerHTML = '×';
removeBtn.addEventListener('click', function() {
selectedDischargeComplaints.splice(idx, 1);
renderDischargeComplaintTable();
});
td6.appendChild(removeBtn);
tr.appendChild(td6);
tbody.appendChild(tr);
});
}
// Complaint Remark input handlers
section.querySelectorAll('.discharge-complaint-remark-input').forEach(function(input) {
// Remove any existing handlers by cloning the element
var newInput = input.cloneNode(true);
input.parentNode.replaceChild(newInput, input);
newInput.addEventListener('blur', function() {
saveComplaintField(this, 'remark');
});
newInput.addEventListener('keydown', function(e) {
if (e.key === 'Enter') {
e.preventDefault();
this.blur();
}
});
});
// REMOVED: Old database-save-on-blur code that was causing errors
// Now using client-side array management like OPD
function attachComplaintFieldHandlers(section, form) {
// DISABLED - no longer needed, using client-side management
}
function setSectionStatus(id, text, level) {