diff --git a/application/controllers/Notes.php b/application/controllers/Notes.php
index de681e717..6e5dcd8be 100644
--- a/application/controllers/Notes.php
+++ b/application/controllers/Notes.php
@@ -275,6 +275,30 @@ class Notes extends CI_Controller {
$this->output->set_content_type('application/json')->set_output(json_encode($response));
}
+ // API endpoint to get note details by ID
+ public function get($id = null) {
+ $this->load->model('note');
+ $clean_id = $this->security->xss_clean($id);
+ if (!is_numeric($clean_id) || !$this->note->belongs_to_user($clean_id, $this->session->userdata('user_id'))) {
+ $this->output->set_content_type('application/json')->set_output(json_encode(['error' => _("Not found or not allowed")]));
+ return;
+ }
+ $query = $this->note->view($clean_id);
+ if ($query && $query->num_rows() > 0) {
+ $row = $query->row();
+ $response = [
+ 'id' => $row->id,
+ 'category' => $row->cat,
+ 'user_id' => $row->user_id,
+ 'title' => $row->title,
+ 'content' => $row->note
+ ];
+ $this->output->set_content_type('application/json')->set_output(json_encode($response));
+ } else {
+ $this->output->set_content_type('application/json')->set_output(json_encode(['error' => _("Not found")]));
+ }
+ }
+
// Form validation callback for add: unique Contacts note title for user, only core callsign
public function contacts_title_unique($title = null) {
$category = $this->input->post('category', TRUE);
@@ -315,7 +339,8 @@ class Notes extends CI_Controller {
// Check for existing note with the same title
$this->load->model('note');
- if ($this->note->get_note_id_by_category($user_id, 'Contacts', $core) > 0) {
+ $existing_id = $this->note->get_note_id_by_category($user_id, 'Contacts', $core);
+ if ($existing_id > 0 && $existing_id != $note_id) {
$this->form_validation->set_message('contacts_title_unique_edit', __("A note with this callsign already exists in your Contacts. Please enter a unique callsign."));
return FALSE;
}
@@ -324,4 +349,6 @@ class Notes extends CI_Controller {
return TRUE;
}
+
+
}
diff --git a/application/models/Note.php b/application/models/Note.php
index b2b968060..f5f247ea0 100644
--- a/application/models/Note.php
+++ b/application/models/Note.php
@@ -80,7 +80,8 @@ class Note extends CI_Model {
$title = str_replace('0', 'Ø', $check_title);
}
// Check for existing note with same title in Contacts category
- if ($this->get_note_id_by_category($user_id, $category, $check_title) && $category === 'Contacts') {
+ $existing_id = $this->get_note_id_by_category($user_id, $category, $check_title);
+ if ($existing_id > 0 && $existing_id != $note_id && $category === 'Contacts') {
show_error(__("In Contacts category, the titles of the notes need to be unique."));
return;
}
diff --git a/application/views/qso/index.php b/application/views/qso/index.php
index 3af9573c1..9b9d3a9dc 100644
--- a/application/views/qso/index.php
+++ b/application/views/qso/index.php
@@ -720,7 +720,9 @@ switch ($date_format) {
-
+
+
+
diff --git a/assets/js/sections/qso.js b/assets/js/sections/qso.js
index 7ac238dfa..33f6bdcb4 100644
--- a/assets/js/sections/qso.js
+++ b/assets/js/sections/qso.js
@@ -73,30 +73,92 @@ function getUTCDateStamp(el) {
$(el).attr('value', formatted_date);
}
+
+ var saveBtn = document.getElementById('callsign-note-save-btn');
+ function setNoteEditorState(state, noteText, saveBtn) {
+ if (!noteEditor) return;
+ if (state === 'no_callsign') {
+
+ } else if (state === 'no_note') {
+
+ } else if (state === 'has_note') {
+
+ }
+ }
+
+
// Note icon state logic
-function setNotesVisibility(state) {
+function setNotesVisibility(state, noteText = "") {
var $icon = $('#note_create_edit');
$icon.removeClass('text-secondary text-info');
- $icon.removeAttr('data-bs-original-title');
- $icon.removeAttr('title');
- if (state == 2) {
- // Callsign with existing note
- $icon.show();
- $icon.addClass('text-info');
- $icon.attr('data-bs-original-title', lang_qso_note_edit);
- $('#callsign-notes').show();
- } else if (state == 1) {
- // Callsign, no note yet
- $icon.show();
- $icon.attr('data-bs-original-title', lang_qso_note_add);
- $('#callsign-notes').show();
- } else {
- // No callsign - hide icon
- $icon.hide();
- $icon.attr('data-bs-original-title', lang_qso_note_no_callsign);
- $('#callsign-notes').hide();
+ $icon.removeAttr('data-bs-original-title title');
+ var $noteCard = $('#callsign-notes');
+ var $saveBtn = $('#callsign-note-save-btn');
+ var $editorElem = $('#callsign_note_content');
+ var noteEditor = $editorElem.data('easymde');
+ var $editBtn = $('#callsign-note-edit-btn');
+
+ // Initialize EasyMDE if not already done
+ if (!noteEditor && typeof EasyMDE !== 'undefined') {
+ noteEditor = new EasyMDE({
+ element: $editorElem[0],
+ spellChecker: false,
+ toolbar: [
+ "bold", "italic", "heading", "|","preview", "|",
+ "quote", "unordered-list", "ordered-list", "|",
+ "link", "image", "|",
+ "guide"
+ ],
+ forceSync: true,
+ status: false,
+ maxHeight: '250px',
+ autoDownloadFontAwesome: false,
+ autoRefresh: { delay: 250 },
+ });
+ $editorElem.data('easymde', noteEditor);
}
+ if (state === 0) {
+ // No callsign
+ $icon.hide().attr('data-bs-original-title', lang_qso_note_no_callsign);
+
+ // Hide note card
+ $noteCard.hide();
+
+ } else if (state === 1) {
+ // Callsign, no note yet
+ $icon.show().attr('data-bs-original-title', lang_qso_note_add);
+
+ // Show note card
+ $noteCard.show();
+
+ // Hide editor toolbar, set value and show preview
+ document.querySelector('.EasyMDEContainer .editor-toolbar').style.display = 'none';
+ noteEditor.value('No notes found for this callsign - click Edit Note to add notes.');
+ noteEditor.togglePreview();
+ noteEditor.codemirror.setOption('readOnly', true);
+
+ } else if (state === 2) {
+ // Callsign with existing note
+ $icon.show().addClass('text-info').attr('data-bs-original-title', lang_qso_note_edit);
+
+ // Show note card
+ $noteCard.show();
+
+ // Hide editor toolbar, set value and show preview
+ document.querySelector('.EasyMDEContainer .editor-toolbar').style.display = 'none';
+ noteEditor.value(noteText);
+ noteEditor.togglePreview();
+ noteEditor.codemirror.setOption('readOnly', true);
+ }
+
+ // Show Edit button for states 1 and 2
+ if (state === 1 || state === 2) {
+ $editBtn.removeClass('d-none').show();
+ } else {
+ $editBtn.addClass('d-none').hide();
+ }
+
// If Bootstrap tooltip is initialized, update it
if ($icon.data('bs.tooltip')) {
$icon.tooltip('dispose').tooltip();
@@ -923,7 +985,7 @@ function reset_fields() {
setNotesVisibility(0); // Always gray out note icon on reset
}
-// Set note icon state: 0 = gray, 1 = empty, 2 = filled based on callsign
+// Get status of notes for this callsign
function get_note_icon(callsign){
$.get(
window.base_url + 'index.php/notes/check_duplicate',
@@ -935,8 +997,23 @@ function get_note_icon(callsign){
if (typeof data === 'string') {
try { data = JSON.parse(data); } catch (e) { data = {}; }
}
- if (data && data.exists === true) {
- setNotesVisibility(2);
+ if (data && data.exists === true && data.id) {
+ // Get the note content using the note ID
+ $.get(
+ window.base_url + 'index.php/notes/get/' + data.id,
+ function(noteData) {
+ if (typeof noteData === 'string') {
+ try { noteData = JSON.parse(noteData); } catch (e) { noteData = {}; }
+ }
+ if (noteData && noteData.content) {
+ setNotesVisibility(2, noteData.content);
+ } else {
+ setNotesVisibility(2,'Error');
+ }
+ }
+ ).fail(function() {
+ setNotesVisibility(2,'Error');
+ });
} else {
setNotesVisibility(1);
}
@@ -2490,25 +2567,6 @@ $(document).ready(function () {
);
});
- if (document.getElementById('callsign_note_content')) {
- if (typeof EasyMDE !== 'undefined') {
- new EasyMDE({
- element: document.getElementById('callsign_note_content'),
- spellChecker: false,
- toolbar: [
- "bold", "italic", "heading", "|","preview", "|",
- "quote", "unordered-list", "ordered-list", "|",
- "link", "image", "|",
- "guide"
- ],
- forceSync: true,
- status: false,
- maxHeight: '250px',
- autoDownloadFontAwesome: false,
- });
- }
- }
-
// everything loaded and ready 2 go
bc.postMessage('ready');