From 2e6bff35a05dd4ec75f8e78d85e7f7963923f2d6 Mon Sep 17 00:00:00 2001 From: DevSoftTech Server Date: Sat, 6 Jun 2026 05:12:23 +0530 Subject: [PATCH] Make IPD discharge complaint names and remarks editable like OPD form FEATURE: Inline editing for discharge complaint table PROBLEM: In IPD discharge form, complaint names and remarks were read-only after adding. Unlike OPD consult form where you can edit complaint names directly in the table. SOLUTION: 1. VIEW Changes (discharge_create.php): - Changed complaint name and remark columns from static to editable - Added data attributes for complaint ID and original values - Added CSS classes: discharge-complaint-name-input, discharge-complaint-remark-input 2. JAVASCRIPT Changes: - Added saveComplaintField() function for AJAX updates - Event handlers on blur to save changes - Enter key support to blur and save - Visual feedback: green border on success, red on error - Auto-updates original value after successful save 3. CONTROLLER Changes (Ipd_discharge.php): - Added update_complaint_field() method for AJAX endpoint - Updates ipd_discharge_comp table (comp_report or comp_remark) - Returns JSON success/error response BENEFITS: - Same user experience as OPD consult form - Edit complaints/remarks without page reload - Immediate feedback on save success/failure - Type correction and updates without removing and re-adding rows --- app/Controllers/Ipd_discharge.php | 40 ++++++++ app/Views/billing/ipd/discharge_create.php | 104 ++++++++++++++++++++- 2 files changed, 141 insertions(+), 3 deletions(-) diff --git a/app/Controllers/Ipd_discharge.php b/app/Controllers/Ipd_discharge.php index 6c1985e..61932c1 100644 --- a/app/Controllers/Ipd_discharge.php +++ b/app/Controllers/Ipd_discharge.php @@ -2814,6 +2814,46 @@ class Ipd_discharge extends BaseController ]); } + public function update_complaint_field() + { + if (! $this->request->isAJAX()) { + return $this->response->setStatusCode(400)->setJSON(['success' => false, 'error' => 'Invalid request']); + } + + $complaintId = (int) $this->request->getPost('complaint_id'); + $fieldType = trim((string) $this->request->getPost('field_type')); + $fieldValue = trim((string) $this->request->getPost('field_value')); + + if ($complaintId <= 0 || !in_array($fieldType, ['name', 'remark'], true)) { + return $this->response->setJSON(['success' => false, 'error' => 'Invalid parameters']); + } + + $table = 'ipd_discharge_comp'; + if (! $this->db->tableExists($table)) { + return $this->response->setJSON(['success' => false, 'error' => 'Complaint table not found']); + } + + $columnName = $fieldType === 'name' ? 'comp_report' : 'comp_remark'; + + try { + $updated = $this->db->table($table) + ->where('id', $complaintId) + ->update([ + $columnName => $fieldValue, + 'updated_at' => date('Y-m-d H:i:s') + ]); + + if ($updated) { + return $this->response->setJSON(['success' => true]); + } else { + return $this->response->setJSON(['success' => false, 'error' => 'No rows updated']); + } + } catch (\Throwable $e) { + log_message('error', 'Failed to update discharge complaint field: {msg}', ['msg' => $e->getMessage()]); + return $this->response->setJSON(['success' => false, 'error' => 'Database error']); + } + } + private function upsertByComposite( string $table, string $ipdField, diff --git a/app/Views/billing/ipd/discharge_create.php b/app/Views/billing/ipd/discharge_create.php index 9afe6f0..277e4da 100644 --- a/app/Views/billing/ipd/discharge_create.php +++ b/app/Views/billing/ipd/discharge_create.php @@ -738,9 +738,27 @@ $allergyStatusNoKnown = in_array($allergyStatusNormalized, ['no known drug aller No complaint rows yet. - - - + + + + + + + @@ -3877,6 +3895,86 @@ $allergyStatusNoKnown = in_array($allergyStatusNormalized, ['no known drug aller }, { passive: true, capture: true }); syncNavOnScroll(); + // ═══════════════════════════════════════════════════════════════════ + // Editable Complaint Name and Remark Fields + // ═══════════════════════════════════════════════════════════════════ + 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 form = document.getElementById('discharge_main_form'); + if (!form) { + 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('', { + method: 'POST', + 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); + }); + } + + // Complaint Name input handlers + document.querySelectorAll('.discharge-complaint-name-input').forEach(function(input) { + input.addEventListener('blur', function() { + saveComplaintField(this, 'name'); + }); + + input.addEventListener('keydown', function(e) { + if (e.key === 'Enter') { + e.preventDefault(); + this.blur(); + } + }); + }); + + // Complaint Remark input handlers + document.querySelectorAll('.discharge-complaint-remark-input').forEach(function(input) { + input.addEventListener('blur', function() { + saveComplaintField(this, 'remark'); + }); + + input.addEventListener('keydown', function(e) { + if (e.key === 'Enter') { + e.preventDefault(); + this.blur(); + } + }); + }); + })();