mirror of
https://gh.wpcy.net/https://github.com/stingray82/MainWP-Client-Notes-For-Pro-Report.git
synced 2026-05-01 00:39:59 +08:00
- Added strict Y-m-d validation to save handler to prevent invalid manual date entries. - Improved DB query safety: • ajax_load_work_note_action() now uses a single, clean $wpdb->prepare(). • Switched delete handler to use $wpdb->delete(). - Polished migration toolbar JS injection for reliability. - General code cleanup for consistency and maintainability. Changelog: * Added: Strict date format validation when saving notes, blocking invalid manual entries. * Improved: Database query safety for loading and deleting notes. * Improved: Migration toolbar JS injection reliability. * Cleaned: General code formatting and minor logic refinements.
196 lines
No EOL
6.2 KiB
JavaScript
196 lines
No EOL
6.2 KiB
JavaScript
jQuery(document).ready(function ($) {
|
|
// ---- Cached selectors
|
|
const $noteId = $('input[name="note_id"]');
|
|
const $siteId = $('input[name="wpid"]');
|
|
const $date = $('#work_notes_date');
|
|
const $contentTA = $('textarea[name="work_notes_content"]');
|
|
const $saveBtn = $('#save-work-note');
|
|
|
|
// ---- Helpers
|
|
function getEditorContent() {
|
|
const ed = window.tinyMCE ? tinyMCE.get('work_notes_content') : null;
|
|
return ed ? ed.getContent() : $contentTA.val();
|
|
}
|
|
|
|
function setEditorContent(html) {
|
|
const ed = window.tinyMCE ? tinyMCE.get('work_notes_content') : null;
|
|
if (ed) ed.setContent(html || '');
|
|
$contentTA.val(html || '');
|
|
}
|
|
|
|
function setDateInput(value, triggerChange = true) {
|
|
// Prefer Flatpickr API when available
|
|
if (window.workNotesFlatpickrInstance) {
|
|
window.workNotesFlatpickrInstance.setDate(value || null, true); // true => triggerChange
|
|
} else {
|
|
$date.val(value || '');
|
|
if (triggerChange) $date.trigger('change');
|
|
}
|
|
}
|
|
|
|
// Replaces deprecated .focus()/.blur() event shorthands
|
|
function fixDatePicker() {
|
|
// If an altInput exists, ensure it's in sync
|
|
const val = $date.val();
|
|
setDateInput(val, true);
|
|
}
|
|
|
|
function resetForm() {
|
|
$noteId.val('-1');
|
|
$saveBtn.text('Save Work Note');
|
|
|
|
// Reset date to today where possible
|
|
const today = (window.mainwpWorkNotes && mainwpWorkNotes.today) ? mainwpWorkNotes.today : '';
|
|
setDateInput(today, true);
|
|
|
|
// Clear editor
|
|
setEditorContent('');
|
|
|
|
fixDatePicker();
|
|
}
|
|
|
|
function reloadNotesTable(wpid) {
|
|
$.post(window.mainwpWorkNotes.ajax_url, {
|
|
action: 'load_work_notes_form',
|
|
nonce: window.mainwpWorkNotes.nonce,
|
|
site_id: wpid
|
|
}).done(function (response) {
|
|
if (response && response.success && response.data && response.data.html) {
|
|
$('.ui.celled.table tbody').replaceWith(response.data.html);
|
|
// Using delegated handlers below, so no need to rebind, but call just in case
|
|
bindWorkNotesEvents();
|
|
} else {
|
|
alert((response && response.data && response.data.message) || 'Failed to reload notes.');
|
|
}
|
|
}).fail(function () {
|
|
alert('Failed to reload notes.');
|
|
});
|
|
}
|
|
|
|
function bindWorkNotesEvents() {
|
|
// EDIT note
|
|
$(document).off('click', '.edit-note').on('click', '.edit-note', function () {
|
|
const noteIdVal = $(this).data('note-id');
|
|
const wpid = $siteId.val();
|
|
|
|
$.post(window.mainwpWorkNotes.ajax_url, {
|
|
action: 'load_work_note',
|
|
nonce: window.mainwpWorkNotes.nonce,
|
|
wpid: wpid,
|
|
note_id: noteIdVal
|
|
}).done(function (response) {
|
|
if (response && response.success) {
|
|
$noteId.val(noteIdVal);
|
|
$saveBtn.text('Update Work Note');
|
|
|
|
// Date
|
|
setDateInput(response.data.date, true);
|
|
|
|
// Content
|
|
setEditorContent(response.data.content);
|
|
|
|
fixDatePicker();
|
|
} else {
|
|
alert(response && response.data ? response.data.message : 'Failed to load the note.');
|
|
}
|
|
}).fail(function () {
|
|
alert('Failed to load the note.');
|
|
});
|
|
});
|
|
|
|
// DELETE note
|
|
$(document).off('click', '.delete-note').on('click', '.delete-note', function () {
|
|
if (!window.confirm('Are you sure you want to delete this note?')) return;
|
|
|
|
const noteIdVal = $(this).data('note-id');
|
|
const wpid = $siteId.val();
|
|
|
|
$.post(window.mainwpWorkNotes.ajax_url, {
|
|
action: 'delete_work_note',
|
|
nonce: window.mainwpWorkNotes.nonce,
|
|
wpid: wpid,
|
|
note_id: noteIdVal
|
|
}).done(function (response) {
|
|
if (response && response.success) {
|
|
alert(response.data.message || 'Note deleted.');
|
|
reloadNotesTable(wpid);
|
|
resetForm();
|
|
} else {
|
|
alert(response && response.data ? response.data.message : 'Failed to delete the note.');
|
|
}
|
|
}).fail(function () {
|
|
alert('Failed to delete the note.');
|
|
});
|
|
});
|
|
}
|
|
|
|
// SAVE / UPDATE
|
|
$saveBtn.off('click').on('click', function () {
|
|
const noteIdVal = $noteId.val();
|
|
const wpid = $siteId.val();
|
|
// Gate Manual Entry
|
|
let dateVal = $date.val();
|
|
if (window.workNotesFlatpickrInstance) {
|
|
const fp = window.workNotesFlatpickrInstance;
|
|
|
|
// Prefer the selected date if present
|
|
if (fp.selectedDates && fp.selectedDates[0]) {
|
|
dateVal = fp.formatDate(fp.selectedDates[0], 'Y-m-d');
|
|
} else if (fp.altInput && fp.altInput.value) {
|
|
// If user typed into the alt input, parse it using altFormat
|
|
const parsed = fp.parseDate(fp.altInput.value, fp.config.altFormat);
|
|
if (parsed) {
|
|
dateVal = fp.formatDate(parsed, 'Y-m-d');
|
|
}
|
|
}
|
|
}
|
|
const content = getEditorContent();
|
|
|
|
$.post(window.mainwpWorkNotes.ajax_url, {
|
|
action: 'save_work_note',
|
|
nonce: window.mainwpWorkNotes.nonce,
|
|
note_id: noteIdVal,
|
|
wpid: wpid,
|
|
work_notes_date: dateVal,
|
|
work_notes_content: content
|
|
}).done(function (response) {
|
|
if (response && response.success) {
|
|
alert(response.data.message || 'Note saved.');
|
|
reloadNotesTable(wpid);
|
|
resetForm();
|
|
} else {
|
|
alert(response && response.data ? response.data.message : 'Failed to save the note.');
|
|
}
|
|
}).fail(function () {
|
|
alert('Failed to save the note.');
|
|
});
|
|
});
|
|
|
|
// ---- Init Flatpickr if present
|
|
if (typeof window.flatpickr !== 'undefined') {
|
|
window.workNotesFlatpickrInstance = flatpickr('#work_notes_date', {
|
|
dateFormat: 'Y-m-d',
|
|
altInput: true,
|
|
altFormat: (window.mainwpWorkNotes && mainwpWorkNotes.date_format) || 'd/m/Y',
|
|
defaultDate: $date.val() || (window.mainwpWorkNotes && mainwpWorkNotes.today) || null,
|
|
allowInput: true,
|
|
onChange: function (selectedDates, _str, inst) {
|
|
if (selectedDates[0]) {
|
|
$date.val(inst.formatDate(selectedDates[0], 'Y-m-d')).trigger('change');
|
|
}
|
|
},
|
|
onClose: function (_selectedDates, _str, inst) {
|
|
if (inst.altInput && inst.altInput.value) {
|
|
const parsed = inst.parseDate(inst.altInput.value, inst.config.altFormat);
|
|
if (parsed) {
|
|
$date.val(inst.formatDate(parsed, 'Y-m-d')).trigger('change');
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// ---- Kick things off
|
|
fixDatePicker();
|
|
bindWorkNotesEvents();
|
|
}); |