mirror of
https://github.com/wavelog/wavelog.git
synced 2026-03-22 10:24:14 +00:00
Notes: basic support added to QSO page
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
|
||||
// Notes controller: handles all note actions, with security and input validation
|
||||
class Notes extends CI_Controller {
|
||||
// API endpoint: check for duplicate note title in category for user
|
||||
// Ensure only authorized users can access Notes controller
|
||||
function __construct() {
|
||||
parent::__construct();
|
||||
@@ -41,19 +40,34 @@ class Notes extends CI_Controller {
|
||||
function add() {
|
||||
$this->load->model('note');
|
||||
$this->load->library('form_validation');
|
||||
$this->load->library('callbook'); // Used for callsign parsing
|
||||
$this->load->library('callbook'); // Used for callsign parsing
|
||||
|
||||
// Support prefilled title/category from query string
|
||||
$prefill_title = $this->input->get('title', TRUE);
|
||||
$prefill_category = $this->input->get('category', TRUE);
|
||||
|
||||
$suggested_title = null;
|
||||
// Validate form fields
|
||||
$this->form_validation->set_rules('title', 'Note Title', 'required|callback_contacts_title_unique'); // Custom callback for Contacts category
|
||||
$this->form_validation->set_rules('content', 'Content', 'required');
|
||||
if ($this->form_validation->run() == FALSE) {
|
||||
// Use POST if available, otherwise use prefill from query string
|
||||
$category = $this->input->post('category', TRUE);
|
||||
if ($category === 'Contacts') {
|
||||
|
||||
$suggested_title = strtoupper($this->callbook->get_plaincall($this->input->post('title', TRUE)));
|
||||
if (empty($category) && !empty($prefill_category)) {
|
||||
$category = $prefill_category;
|
||||
}
|
||||
if ($category === 'Contacts') {
|
||||
$title_input = $this->input->post('title', TRUE);
|
||||
if (empty($title_input) && !empty($prefill_title)) {
|
||||
$title_input = $prefill_title;
|
||||
}
|
||||
$suggested_title = strtoupper($this->callbook->get_plaincall($title_input));
|
||||
}
|
||||
// Pass prefill values to view
|
||||
$data['suggested_title'] = $suggested_title;
|
||||
$data['prefill_title'] = $prefill_title;
|
||||
$data['prefill_category'] = $prefill_category;
|
||||
$data['category'] = $category;
|
||||
$data['page_title'] = __("Add Notes");
|
||||
$this->load->view('interface_assets/header', $data);
|
||||
$this->load->view('notes/add');
|
||||
@@ -241,26 +255,36 @@ class Notes extends CI_Controller {
|
||||
$id = $this->input->get('id', TRUE); // Optional, for edit
|
||||
$check_title = $title;
|
||||
if ($category === 'Contacts') {
|
||||
$check_title = strtoupper($title);
|
||||
$this->load->library('callbook');
|
||||
$check_title = strtoupper($this->callbook->get_plaincall($title));
|
||||
}
|
||||
$where = [
|
||||
'category' => $category,
|
||||
'cat' => $category,
|
||||
'user_id' => $user_id,
|
||||
'title' => $check_title
|
||||
];
|
||||
$query = $this->db->get_where('notes', $where);
|
||||
$duplicate = false;
|
||||
$exists = false;
|
||||
$note_id = null;
|
||||
if ($id) {
|
||||
foreach ($query->result() as $note) {
|
||||
if ($note->id != $id) {
|
||||
$duplicate = true;
|
||||
$exists = true;
|
||||
$note_id = $note->id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$duplicate = $query->num_rows() > 0;
|
||||
if ($query->num_rows() > 0) {
|
||||
$exists = true;
|
||||
$note_id = $query->row()->id;
|
||||
}
|
||||
}
|
||||
$this->output->set_content_type('application/json')->set_output(json_encode(['duplicate' => $duplicate]));
|
||||
$response = ['exists' => $exists];
|
||||
if ($exists && $note_id) {
|
||||
$response['id'] = $note_id;
|
||||
}
|
||||
$this->output->set_content_type('application/json')->set_output(json_encode($response));
|
||||
}
|
||||
|
||||
// Form validation callback for add: unique Contacts note title for user, only core callsign
|
||||
|
||||
@@ -29,7 +29,18 @@
|
||||
<form method="post" action="<?php echo site_url('notes/add'); ?>" name="notes_add" id="notes_add">
|
||||
<div class="mb-3">
|
||||
<label for="inputTitle"><?= __("Title"); ?></label>
|
||||
<input type="text" name="title" class="form-control" id="inputTitle" value="<?php echo isset($suggested_title) && $suggested_title ? $suggested_title : set_value('title'); ?>">
|
||||
<input type="text" name="title" class="form-control" id="inputTitle" value="<?php
|
||||
// Priority: suggested_title > POST value > prefill_title > ''
|
||||
if (isset($suggested_title) && $suggested_title) {
|
||||
echo $suggested_title;
|
||||
} elseif (set_value('title')) {
|
||||
echo set_value('title');
|
||||
} elseif (isset($prefill_title) && $prefill_title) {
|
||||
echo htmlspecialchars($prefill_title);
|
||||
} else {
|
||||
echo '';
|
||||
}
|
||||
?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="catSelect">
|
||||
@@ -39,8 +50,10 @@
|
||||
</span>
|
||||
</label>
|
||||
<select name="category" class="form-select" id="catSelect">
|
||||
<?php foreach (Note::get_possible_categories() as $category_key => $category_label): ?>
|
||||
<option value="<?= htmlspecialchars($category_key) ?>"<?= (set_value('category', 'General') == $category_key ? ' selected="selected"' : '') ?>><?= $category_label ?></option>
|
||||
<?php
|
||||
$selected_category = set_value('category', isset($category) ? $category : (isset($prefill_category) ? $prefill_category : 'General'));
|
||||
foreach (Note::get_possible_categories() as $category_key => $category_label): ?>
|
||||
<option value="<?= htmlspecialchars($category_key) ?>"<?= ($selected_category == $category_key ? ' selected="selected"' : '') ?>><?= $category_label ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
@@ -154,7 +154,7 @@ switch ($date_format) {
|
||||
<!-- Callsign Input -->
|
||||
<div class="row">
|
||||
<div class="mb-3 col-md-12">
|
||||
<label for="callsign"><?= __("Callsign"); ?></label> <i id="check_cluster" data-bs-toggle="tooltip" title="<?= __("Search DXCluster for latest Spot"); ?>" class="fas fa-search"></i>
|
||||
<label for="callsign"><?= __("Callsign"); ?></label> <i id="check_cluster" data-bs-toggle="tooltip" title="<?= __("Search DXCluster for latest Spot"); ?>" class="fas fa-search"></i></label> <i id="note_create_edit" data-bs-toggle="tooltip" title="<?= __("Create or edit note for this callsign"); ?>" class="fas fa-sticky-note text-secondary"></i>
|
||||
<div class="input-group">
|
||||
<input tabindex="7" type="text" class="form-control uppercase" id="callsign" name="callsign" autocomplete="off" required>
|
||||
<span id="qrz_info" class="input-group-text btn-included-on-field d-none py-0"></span>
|
||||
|
||||
@@ -73,6 +73,15 @@ function getUTCDateStamp(el) {
|
||||
$(el).attr('value', formatted_date);
|
||||
}
|
||||
|
||||
// Note icon state logic
|
||||
function setNoteIconState(enabled) {
|
||||
var $icon = $('#note_create_edit');
|
||||
if (enabled) {
|
||||
$icon.removeClass('text-secondary');
|
||||
} else {
|
||||
$icon.addClass('text-secondary');
|
||||
}
|
||||
}
|
||||
|
||||
$('#stationProfile').on('change', function () {
|
||||
var stationProfile = $('#stationProfile').val();
|
||||
@@ -399,7 +408,7 @@ function parseUserDate(user_provided_date) { // creates JS-Date out of user-prov
|
||||
month = parseInt(parts[1], 10) - 1;
|
||||
year = parseInt(parts[2], 10);
|
||||
}
|
||||
if (isNaN(day) || day < 1 || day > 31 || isNaN(month) || month < 0 || month > 11 || isNaN(year)) return null;
|
||||
if (isNaN(day) || day < 1 || day > 31 || isNaN(month) || month < 0 || month > 11 || isNaN(year)) return null;
|
||||
return new Date(year, month, day);
|
||||
}
|
||||
|
||||
@@ -891,6 +900,7 @@ function reset_fields() {
|
||||
clearTimeout();
|
||||
set_timers();
|
||||
resetTimers(qso_manual);
|
||||
setNoteIconState(false); // Always gray out note icon on reset
|
||||
}
|
||||
|
||||
$("#callsign").on("focusout", function () {
|
||||
@@ -921,6 +931,25 @@ $("#callsign").on("focusout", function () {
|
||||
find_callsign = find_callsign.replaceAll('Ø', '0');
|
||||
const url = `${base_url}index.php/logbook/json/${find_callsign}/${json_band}/${json_mode}/${stationProfile}/${startDate}/${last_qsos_count}`;
|
||||
|
||||
// Check note existence for this callsign
|
||||
$.get(
|
||||
window.base_url + 'index.php/notes/check_duplicate',
|
||||
{
|
||||
category: 'Contacts',
|
||||
title: callsign
|
||||
},
|
||||
function(data) {
|
||||
if (typeof data === 'string') {
|
||||
try { data = JSON.parse(data); } catch (e) { data = {}; }
|
||||
}
|
||||
if (data && data.exists === true) {
|
||||
setNoteIconState(true);
|
||||
} else {
|
||||
setNoteIconState(false);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Replace / in a callsign with - to stop urls breaking
|
||||
lookupCall = $.getJSON(url, async function (result) {
|
||||
|
||||
@@ -2173,6 +2202,8 @@ $(document).ready(function () {
|
||||
set_timers();
|
||||
updateStateDropdown('#dxcc_id', '#stateInputLabel', '#location_us_county', '#stationCntyInputQso');
|
||||
|
||||
setNoteIconState(false); /// Grey-out note icon
|
||||
|
||||
// Clear the localStorage for the qrg units, except the quicklogCallsign and a possible backlog
|
||||
clearQrgUnits();
|
||||
set_qrg();
|
||||
@@ -2400,6 +2431,39 @@ $(document).ready(function () {
|
||||
});
|
||||
}
|
||||
|
||||
// Note create/edit icon click handler
|
||||
$('#note_create_edit').on('click', function() {
|
||||
var callsign = $('#callsign').val().trim();
|
||||
if (!callsign) {
|
||||
alert('Please enter a callsign first.');
|
||||
return;
|
||||
}
|
||||
// AJAX to check if note exists for this callsign in Contacts category
|
||||
$.get(
|
||||
window.base_url + 'index.php/notes/check_duplicate',
|
||||
{
|
||||
category: 'Contacts',
|
||||
title: callsign
|
||||
},
|
||||
function(data) {
|
||||
// Defensive: try to parse if string
|
||||
if (typeof data === 'string') {
|
||||
try { data = JSON.parse(data); } catch (e) { data = {}; }
|
||||
}
|
||||
if (data && data.exists === true && data.id) {
|
||||
window.open(window.base_url + 'index.php/notes/edit/' + data.id, '_blank');
|
||||
} else if (data && data.exists === false) {
|
||||
// Open add with prefilled title and Contacts category
|
||||
var url = window.base_url + 'index.php/notes/add?title=' + encodeURIComponent(callsign) + '&category=Contacts';
|
||||
window.open(url, '_blank');
|
||||
} else {
|
||||
// Unexpected response, show error
|
||||
alert('Could not check note existence. Please try again.');
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
// everything loaded and ready 2 go
|
||||
bc.postMessage('ready');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user