diff --git a/app/Config/Routes.php b/app/Config/Routes.php
index 6d76a59..78c0457 100644
--- a/app/Config/Routes.php
+++ b/app/Config/Routes.php
@@ -535,6 +535,9 @@ $routes->get('Opd_prescription/get_complaints', 'Opd_prescription::get_complaint
$routes->get('Opd_prescription/get_disease', 'Opd_prescription::get_disease');
$routes->get('Opd_prescription/get_finding_exam', 'Opd_prescription::get_finding_exam');
$routes->post('Opd_prescription/autotype_keyword_save', 'Opd_prescription::autotype_keyword_save');
+$routes->get('Opd_prescription/autotype_keyword_list', 'Opd_prescription::autotype_keyword_list');
+$routes->post('Opd_prescription/autotype_keyword_update', 'Opd_prescription::autotype_keyword_update');
+$routes->post('Opd_prescription/autotype_keyword_remove', 'Opd_prescription::autotype_keyword_remove');
$routes->post('Opd_prescription/complaints_parse', 'Opd_prescription::complaints_parse');
$routes->post('Opd_prescription/complaints_ai_draft', 'Opd_prescription::complaints_ai_draft');
$routes->post('Opd_prescription/clinical_autotype', 'Opd_prescription::clinical_autotype');
diff --git a/app/Controllers/Opd_prescription.php b/app/Controllers/Opd_prescription.php
index d3019a9..257f543 100644
--- a/app/Controllers/Opd_prescription.php
+++ b/app/Controllers/Opd_prescription.php
@@ -4111,6 +4111,195 @@ class Opd_prescription extends BaseController
]);
}
+ public function autotype_keyword_list()
+ {
+ if (! $this->canAccessPrescription()) {
+ return $this->response->setStatusCode(403)->setJSON(['rows' => []]);
+ }
+
+ $section = trim((string) $this->request->getGet('section'));
+ $scope = strtolower(trim((string) $this->request->getGet('scope')));
+ $q = trim((string) $this->request->getGet('q'));
+ $docId = max(0, (int) ($this->getCurrentUserId() ?? 0));
+ $canMaster = $this->canManageMasterKeyword();
+
+ if ($scope === '') {
+ $scope = 'all';
+ }
+
+ if (! $this->ensureAutotypeKeywordTable()) {
+ return $this->response->setJSON(['rows' => []]);
+ }
+
+ $builder = $this->db->table('opd_autotype_keyword_master')
+ ->select('id,doc_id,section_key,keyword,updated_at')
+ ->where('is_active', 1);
+
+ if ($this->isAutotypeKeywordSectionAllowed($section)) {
+ $builder->where('section_key', $section);
+ }
+
+ if ($scope === 'master') {
+ $builder->where('doc_id', 0);
+ } elseif ($scope === 'doctor') {
+ $builder->where('doc_id', $docId);
+ } else {
+ $builder->groupStart()
+ ->where('doc_id', 0)
+ ->orWhere('doc_id', $docId)
+ ->groupEnd();
+ }
+
+ if ($q !== '') {
+ $builder->like('keyword', $q);
+ }
+
+ $rows = $builder
+ ->orderBy('doc_id', 'DESC')
+ ->orderBy('updated_at', 'DESC')
+ ->orderBy('keyword', 'ASC')
+ ->limit(200)
+ ->get()
+ ->getResultArray();
+
+ $out = [];
+ foreach ($rows as $row) {
+ $id = (int) ($row['id'] ?? 0);
+ $rowDocId = (int) ($row['doc_id'] ?? 0);
+ $isMaster = $rowDocId === 0;
+ $canEdit = $isMaster ? $canMaster : ($rowDocId === $docId);
+
+ $out[] = [
+ 'id' => $id,
+ 'doc_id' => $rowDocId,
+ 'section_key' => (string) ($row['section_key'] ?? ''),
+ 'keyword' => (string) ($row['keyword'] ?? ''),
+ 'scope' => $isMaster ? 'master' : 'doctor',
+ 'scope_label' => $isMaster ? 'Master' : 'My',
+ 'updated_at' => (string) ($row['updated_at'] ?? ''),
+ 'can_edit' => $canEdit ? 1 : 0,
+ 'can_delete' => $canEdit ? 1 : 0,
+ ];
+ }
+
+ return $this->response->setJSON(['rows' => $out]);
+ }
+
+ public function autotype_keyword_update()
+ {
+ if (! $this->request->isAJAX()) {
+ return $this->response->setStatusCode(400)->setJSON(['update' => 0, 'error_text' => 'Invalid request']);
+ }
+
+ if (! $this->canAccessPrescription()) {
+ return $this->response->setStatusCode(403)->setJSON(['update' => 0, 'error_text' => 'Access denied']);
+ }
+
+ $id = (int) $this->request->getPost('id');
+ $keyword = trim((string) $this->request->getPost('keyword'));
+ $keyword = preg_replace('/\s+/', ' ', $keyword) ?? $keyword;
+ if ($id <= 0 || mb_strlen($keyword) < 2) {
+ return $this->response->setJSON(['update' => 0, 'error_text' => 'Valid keyword is required']);
+ }
+
+ if (! $this->ensureAutotypeKeywordTable()) {
+ return $this->response->setJSON(['update' => 0, 'error_text' => 'Keyword storage unavailable']);
+ }
+
+ $table = $this->db->table('opd_autotype_keyword_master');
+ $current = $table->where('id', $id)->where('is_active', 1)->get(1)->getRowArray();
+ if (empty($current)) {
+ return $this->response->setJSON(['update' => 0, 'error_text' => 'Keyword not found']);
+ }
+
+ $docId = max(0, (int) ($this->getCurrentUserId() ?? 0));
+ $rowDocId = (int) ($current['doc_id'] ?? 0);
+ if ($rowDocId === 0) {
+ if (! $this->canManageMasterKeyword()) {
+ return $this->response->setJSON(['update' => 0, 'error_text' => 'No permission to edit master keyword']);
+ }
+ } elseif ($rowDocId !== $docId) {
+ return $this->response->setJSON(['update' => 0, 'error_text' => 'You can edit only your own keyword']);
+ }
+
+ $section = (string) ($current['section_key'] ?? '');
+ if (! $this->isAutotypeKeywordSectionAllowed($section)) {
+ return $this->response->setJSON(['update' => 0, 'error_text' => 'Unsupported section']);
+ }
+
+ $dup = $table
+ ->where('doc_id', $rowDocId)
+ ->where('section_key', $section)
+ ->where('keyword', $keyword)
+ ->where('id <>', $id)
+ ->where('is_active', 1)
+ ->get(1)
+ ->getRowArray();
+ if (! empty($dup)) {
+ return $this->response->setJSON(['update' => 0, 'error_text' => 'Keyword already exists in this scope']);
+ }
+
+ $table->where('id', $id)->update([
+ 'keyword' => $keyword,
+ 'updated_at' => date('Y-m-d H:i:s'),
+ ]);
+
+ return $this->response->setJSON([
+ 'update' => 1,
+ 'error_text' => 'Keyword updated',
+ 'csrfName' => csrf_token(),
+ 'csrfHash' => csrf_hash(),
+ ]);
+ }
+
+ public function autotype_keyword_remove()
+ {
+ if (! $this->request->isAJAX()) {
+ return $this->response->setStatusCode(400)->setJSON(['update' => 0, 'error_text' => 'Invalid request']);
+ }
+
+ if (! $this->canAccessPrescription()) {
+ return $this->response->setStatusCode(403)->setJSON(['update' => 0, 'error_text' => 'Access denied']);
+ }
+
+ $id = (int) $this->request->getPost('id');
+ if ($id <= 0) {
+ return $this->response->setJSON(['update' => 0, 'error_text' => 'Keyword id is required']);
+ }
+
+ if (! $this->ensureAutotypeKeywordTable()) {
+ return $this->response->setJSON(['update' => 0, 'error_text' => 'Keyword storage unavailable']);
+ }
+
+ $table = $this->db->table('opd_autotype_keyword_master');
+ $current = $table->where('id', $id)->where('is_active', 1)->get(1)->getRowArray();
+ if (empty($current)) {
+ return $this->response->setJSON(['update' => 0, 'error_text' => 'Keyword not found']);
+ }
+
+ $docId = max(0, (int) ($this->getCurrentUserId() ?? 0));
+ $rowDocId = (int) ($current['doc_id'] ?? 0);
+ if ($rowDocId === 0) {
+ if (! $this->canManageMasterKeyword()) {
+ return $this->response->setJSON(['update' => 0, 'error_text' => 'No permission to remove master keyword']);
+ }
+ } elseif ($rowDocId !== $docId) {
+ return $this->response->setJSON(['update' => 0, 'error_text' => 'You can remove only your own keyword']);
+ }
+
+ $table->where('id', $id)->update([
+ 'is_active' => 0,
+ 'updated_at' => date('Y-m-d H:i:s'),
+ ]);
+
+ return $this->response->setJSON([
+ 'update' => 1,
+ 'error_text' => 'Keyword removed',
+ 'csrfName' => csrf_token(),
+ 'csrfHash' => csrf_hash(),
+ ]);
+ }
+
// Legacy-compatible wrappers used by older autocomplete clients.
public function get_complaints()
{
@@ -6322,13 +6511,30 @@ class Opd_prescription extends BaseController
is_active TINYINT NOT NULL DEFAULT 1,
created_at DATETIME NULL,
updated_at DATETIME NULL,
- UNIQUE KEY uniq_doc_section_keyword (doc_id, section_key, keyword),
- INDEX idx_section_keyword (section_key, keyword),
+ UNIQUE KEY uniq_doc_section_keyword (doc_id, section_key, keyword(120)),
+ INDEX idx_section_keyword (section_key, keyword(120)),
INDEX idx_doc_active (doc_id, is_active)
)";
$this->db->query($sql);
} catch (\Throwable $e) {
- return false;
+ // Fallback for stricter MySQL/InnoDB index length limits.
+ try {
+ $fallbackSql = "CREATE TABLE IF NOT EXISTS opd_autotype_keyword_master (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ doc_id INT NOT NULL DEFAULT 0,
+ section_key VARCHAR(60) NOT NULL,
+ keyword VARCHAR(180) NOT NULL,
+ is_active TINYINT NOT NULL DEFAULT 1,
+ created_at DATETIME NULL,
+ updated_at DATETIME NULL,
+ UNIQUE KEY uniq_doc_section_keyword (doc_id, section_key, keyword),
+ INDEX idx_section_keyword (section_key, keyword),
+ INDEX idx_doc_active (doc_id, is_active)
+ )";
+ $this->db->query($fallbackSql);
+ } catch (\Throwable $e2) {
+ return false;
+ }
}
return $this->db->tableExists('opd_autotype_keyword_master');
@@ -6389,6 +6595,16 @@ class Opd_prescription extends BaseController
return $out;
}
+ private function canManageMasterKeyword(): bool
+ {
+ $user = auth()->user();
+ if (! $user || ! method_exists($user, 'can')) {
+ return false;
+ }
+
+ return $user->can('doctor_work.template_workspace.access') || $user->can('doctor_work.access');
+ }
+
private function isTemplateSectionAllowed(string $section): bool
{
return in_array($section, ['finding_examinations', 'diagnosis', 'provisional_diagnosis', 'prescriber_remarks', 'advice'], true);
diff --git a/app/Views/billing/opd_prescription_basic.php b/app/Views/billing/opd_prescription_basic.php
index 08a072c..c0d1f2b 100644
--- a/app/Views/billing/opd_prescription_basic.php
+++ b/app/Views/billing/opd_prescription_basic.php
@@ -467,6 +467,7 @@
Doctor View
+
@@ -949,6 +950,91 @@
+
+
@@ -1200,6 +1286,12 @@
var autotypeSuggestCacheMaxEntries = 240;
var autotypeSuggestCacheLocalKey = 'opd_autotype_suggest_cache_v1';
var autotypeSuggestCacheLocalReady = false;
+ var autotypeKeywordModalLoading = false;
+ var autotypeKeywordSectionLabels = {
+ complaints: 'Complaints',
+ finding_examinations: 'Finding/Examinations',
+ provisional_diagnosis: 'Provisional Diagnosis'
+ };
var medInputTimer = null;
var crgcMedInputTimer = null;
var medicineDoseMasterCache = { dose: [], when: [], freq: [], where: [] };
@@ -1586,6 +1678,72 @@
return (val || '').toString().split(/,\s*/);
}
+ function getTextareaCaretCoordinates(el, caretPos) {
+ var doc = document;
+ var div = doc.createElement('div');
+ var style = window.getComputedStyle(el);
+ var propList = [
+ 'boxSizing', 'width', 'height', 'overflowX', 'overflowY',
+ 'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth',
+ 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft',
+ 'fontStyle', 'fontVariant', 'fontWeight', 'fontStretch', 'fontSize',
+ 'fontSizeAdjust', 'lineHeight', 'fontFamily', 'textAlign', 'textTransform',
+ 'textIndent', 'textDecoration', 'letterSpacing', 'wordSpacing'
+ ];
+
+ div.style.position = 'absolute';
+ div.style.visibility = 'hidden';
+ div.style.whiteSpace = 'pre-wrap';
+ div.style.wordWrap = 'break-word';
+ div.style.left = '-9999px';
+ propList.forEach(function(prop) {
+ div.style[prop] = style[prop];
+ });
+
+ div.textContent = el.value.substring(0, caretPos);
+ var span = doc.createElement('span');
+ span.textContent = el.value.substring(caretPos) || '.';
+ div.appendChild(span);
+ doc.body.appendChild(div);
+
+ var top = span.offsetTop - el.scrollTop;
+ var left = span.offsetLeft - el.scrollLeft;
+ doc.body.removeChild(div);
+
+ return { top: top, left: left };
+ }
+
+ function positionAutocompleteNearCaret($field) {
+ var ac = $field.autocomplete('instance');
+ if (!ac || !ac.menu || !ac.menu.element || !$field.length) {
+ return;
+ }
+
+ var el = $field.get(0);
+ if (!el || el.tagName !== 'TEXTAREA') {
+ return;
+ }
+
+ var offset = $field.offset();
+ if (!offset) {
+ return;
+ }
+
+ var caretPos = Number(el.selectionStart || 0);
+ var caret = getTextareaCaretCoordinates(el, caretPos);
+ var lineHeight = parseFloat(window.getComputedStyle(el).lineHeight || '20');
+ var menuLeft = Math.max(8, offset.left + caret.left);
+ var menuTop = Math.max(8, offset.top + caret.top + lineHeight + 6);
+
+ ac.menu.element.css({
+ position: 'absolute',
+ left: menuLeft + 'px',
+ top: menuTop + 'px',
+ minWidth: Math.max(260, Math.round($field.innerWidth() * 0.65)) + 'px',
+ zIndex: 2000
+ });
+ }
+
function extractLastCommaTerm(term) {
return splitCommaTerms(term).pop() || '';
}
@@ -1668,11 +1826,14 @@
return token;
}
- function saveAutotypeKeyword(section, keyword, done) {
- var scope = 'doctor';
- var useMaster = window.confirm('Save keyword to Master list for all doctors?\nChoose Cancel to save only for current doctor.');
- if (useMaster) {
- scope = 'master';
+ function saveAutotypeKeyword(section, keyword, done, scopeOverride) {
+ var scope = (scopeOverride || '').toString().trim().toLowerCase();
+ if (scope !== 'doctor' && scope !== 'master') {
+ scope = 'doctor';
+ var useMaster = window.confirm('Save keyword to Master list for all doctors?\nChoose Cancel to save only for current doctor.');
+ if (useMaster) {
+ scope = 'master';
+ }
}
apiPost('= base_url('Opd_prescription/autotype_keyword_save') ?>', {
@@ -1690,6 +1851,137 @@
});
}
+ function autotypeKeywordApiList(params, done) {
+ $.getJSON('= base_url('Opd_prescription/autotype_keyword_list') ?>', params || {}, function(data) {
+ if (typeof done === 'function') {
+ done(data || {});
+ }
+ }).fail(function() {
+ if (typeof done === 'function') {
+ done({ rows: [], error_text: 'Unable to fetch keyword list.' });
+ }
+ });
+ }
+
+ function autotypeKeywordApiUpdate(id, keyword, done) {
+ apiPost('= base_url('Opd_prescription/autotype_keyword_update') ?>', {
+ id: id,
+ keyword: keyword
+ }, function(data) {
+ if (typeof done === 'function') {
+ done(data || {});
+ }
+ });
+ }
+
+ function autotypeKeywordApiRemove(id, done) {
+ apiPost('= base_url('Opd_prescription/autotype_keyword_remove') ?>', {
+ id: id
+ }, function(data) {
+ if (typeof done === 'function') {
+ done(data || {});
+ }
+ });
+ }
+
+ function renderAutotypeKeywordManagerRows(rows) {
+ var $tbody = $('#autotype_keyword_manager_rows');
+ $tbody.empty();
+
+ var list = Array.isArray(rows) ? rows : [];
+ if (!list.length) {
+ $tbody.append('
| No keyword found. |
');
+ return;
+ }
+
+ list.forEach(function(row) {
+ var id = Number(row.id || 0);
+ var keyword = (row.keyword || '').toString();
+ var section = (row.section_key || '').toString();
+ var scopeLabel = (row.scope_label || row.scope || '').toString();
+ var canEdit = Number(row.can_edit || 0) === 1;
+ var canDelete = Number(row.can_delete || 0) === 1;
+
+ var $tr = $('
');
+ $(' | ').text(autotypeKeywordSectionLabels[section] || section || '-').appendTo($tr);
+ $(' | ').text(keyword).appendTo($tr);
+ $(' | ').text(scopeLabel).appendTo($tr);
+
+ var $action = $(' | ');
+ var $editBtn = $('');
+ var $delBtn = $('');
+ $editBtn.attr('data-id', id).attr('data-keyword', keyword).addClass('btn-autotype-keyword-edit');
+ $delBtn.attr('data-id', id).attr('data-keyword', keyword).addClass('btn-autotype-keyword-delete');
+
+ if (!canEdit) {
+ $editBtn.prop('disabled', true);
+ }
+ if (!canDelete) {
+ $delBtn.prop('disabled', true);
+ }
+
+ $action.append($editBtn).append($delBtn).appendTo($tr);
+ $tbody.append($tr);
+ });
+ }
+
+ function getAutotypeKeywordFilters() {
+ return {
+ section: ($('#autotype_keyword_filter_section').val() || '').toString(),
+ scope: ($('#autotype_keyword_filter_scope').val() || 'all').toString(),
+ q: ($('#autotype_keyword_filter_search').val() || '').toString().trim()
+ };
+ }
+
+ function submitModalAutotypeKeyword() {
+ var section = ($('#autotype_keyword_add_section').val() || '').toString();
+ var scope = ($('#autotype_keyword_add_scope').val() || 'doctor').toString().toLowerCase();
+ var keyword = ($('#autotype_keyword_add_text').val() || '').toString().trim();
+
+ if (!section) {
+ $('.jsError').removeClass('text-success text-muted').addClass('text-danger').text('Please select section for keyword.');
+ return;
+ }
+ if (!keyword || keyword.length < 2) {
+ $('.jsError').removeClass('text-success text-muted').addClass('text-danger').text('Please type at least 2 characters in keyword text.');
+ return;
+ }
+
+ saveAutotypeKeyword(section, keyword, function(data) {
+ if (Number(data.update || 0) === 1) {
+ clearAutotypeSuggestionCaches();
+ $('#autotype_keyword_add_text').val('');
+ $('.jsError').removeClass('text-danger text-muted').addClass('text-success').text((data.error_text || 'Keyword saved') + ': ' + keyword);
+ loadAutotypeKeywordManagerRows();
+ } else {
+ $('.jsError').removeClass('text-success text-muted').addClass('text-danger').text(data.error_text || 'Unable to save keyword.');
+ }
+ }, scope);
+ }
+
+ function loadAutotypeKeywordManagerRows() {
+ if (autotypeKeywordModalLoading) {
+ return;
+ }
+
+ autotypeKeywordModalLoading = true;
+ $('#autotype_keyword_manager_note').text('Loading keywords...');
+ autotypeKeywordApiList(getAutotypeKeywordFilters(), function(data) {
+ autotypeKeywordModalLoading = false;
+ var rows = (data && data.rows) ? data.rows : [];
+ renderAutotypeKeywordManagerRows(rows);
+ $('#autotype_keyword_manager_note').text('Showing ' + rows.length + ' keyword(s).');
+ if (data && data.error_text) {
+ $('.jsError').removeClass('text-success text-muted').addClass('text-danger').text(data.error_text);
+ }
+ });
+ }
+
+ function clearAutotypeSuggestionCaches() {
+ autotypeSuggestCache = {};
+ persistAutotypeSuggestCache();
+ }
+
function bindLegacyCommaAutocomplete(selector, endpointUrl, extractValue) {
var $field = $(selector);
if (!$field.length || !($.ui && $.ui.autocomplete)) {
@@ -1744,6 +2036,9 @@
focus: function() {
return false;
},
+ open: function() {
+ positionAutocompleteNearCaret($(this));
+ },
select: function(event, ui) {
var terms = splitCommaTerms(this.value);
terms.pop();
@@ -1756,6 +2051,14 @@
return false;
}
});
+
+ $field.on('keyup click focus', function() {
+ var $self = $(this);
+ var ac = $self.autocomplete('instance');
+ if (ac && ac.menu && ac.menu.element && ac.menu.element.is(':visible')) {
+ positionAutocompleteNearCaret($self);
+ }
+ });
}
function getCsrfPair() {
@@ -5963,12 +6266,103 @@
saveAutotypeKeyword(section, keyword, function(data) {
if (Number(data.update || 0) === 1) {
$('.jsError').removeClass('text-danger text-muted').addClass('text-success').text((data.error_text || 'Keyword saved') + ': ' + keyword);
+ loadAutotypeKeywordManagerRows();
} else {
$('.jsError').removeClass('text-success text-muted').addClass('text-danger').text(data.error_text || 'Unable to save keyword.');
}
});
});
+ $('#btn_manage_autotype_keywords').on('click', function() {
+ var firstSection = ($('#autotype_keyword_filter_section').val() || 'complaints').toString();
+ if (!firstSection) {
+ firstSection = 'complaints';
+ }
+ $('#autotype_keyword_add_section').val(firstSection);
+ loadAutotypeKeywordManagerRows();
+ if (window.bootstrap && window.bootstrap.Modal) {
+ window.bootstrap.Modal.getOrCreateInstance(document.getElementById('autotypeKeywordModal')).show();
+ } else {
+ $('#autotypeKeywordModal').show();
+ }
+ });
+
+ $('#btn_autotype_keyword_add').on('click', function() {
+ submitModalAutotypeKeyword();
+ });
+
+ $('#autotype_keyword_add_text').on('keydown', function(e) {
+ if ((e.key || '').toLowerCase() === 'enter') {
+ e.preventDefault();
+ submitModalAutotypeKeyword();
+ }
+ });
+
+ $('#btn_autotype_keyword_filter_reload').on('click', function() {
+ loadAutotypeKeywordManagerRows();
+ });
+
+ $('#autotype_keyword_filter_section, #autotype_keyword_filter_scope').on('change', function() {
+ loadAutotypeKeywordManagerRows();
+ });
+
+ $('#autotype_keyword_filter_search').on('keydown', function(e) {
+ if ((e.key || '').toLowerCase() === 'enter') {
+ e.preventDefault();
+ loadAutotypeKeywordManagerRows();
+ }
+ });
+
+ $(document).on('click', '.btn-autotype-keyword-edit', function() {
+ var id = Number($(this).data('id') || 0);
+ var oldKeyword = ($(this).data('keyword') || '').toString();
+ if (id <= 0) {
+ return;
+ }
+
+ var next = window.prompt('Edit keyword', oldKeyword);
+ if (next === null) {
+ return;
+ }
+ next = next.toString().trim();
+ if (next.length < 2) {
+ $('.jsError').removeClass('text-success text-muted').addClass('text-danger').text('Keyword must be at least 2 characters.');
+ return;
+ }
+
+ autotypeKeywordApiUpdate(id, next, function(data) {
+ if (Number(data.update || 0) === 1) {
+ clearAutotypeSuggestionCaches();
+ $('.jsError').removeClass('text-danger text-muted').addClass('text-success').text(data.error_text || 'Keyword updated.');
+ loadAutotypeKeywordManagerRows();
+ } else {
+ $('.jsError').removeClass('text-success text-muted').addClass('text-danger').text(data.error_text || 'Unable to update keyword.');
+ }
+ });
+ });
+
+ $(document).on('click', '.btn-autotype-keyword-delete', function() {
+ var id = Number($(this).data('id') || 0);
+ var keyword = ($(this).data('keyword') || '').toString();
+ if (id <= 0) {
+ return;
+ }
+
+ if (!window.confirm('Delete keyword: ' + keyword + ' ?')) {
+ return;
+ }
+
+ autotypeKeywordApiRemove(id, function(data) {
+ if (Number(data.update || 0) === 1) {
+ clearAutotypeSuggestionCaches();
+ $('.jsError').removeClass('text-danger text-muted').addClass('text-success').text(data.error_text || 'Keyword removed.');
+ loadAutotypeKeywordManagerRows();
+ } else {
+ $('.jsError').removeClass('text-success text-muted').addClass('text-danger').text(data.error_text || 'Unable to remove keyword.');
+ }
+ });
+ });
+
initConsultSectionDesigner();
bindLegacyCommaAutocomplete('#complaints', '= base_url('Opd_prescription/complaints_search') ?>', function(row) {