129 lines
5.0 KiB
JavaScript
129 lines
5.0 KiB
JavaScript
document.addEventListener('DOMContentLoaded', function() {
|
|
// Unique key for the current page URL
|
|
const pageKey = window.location.pathname + window.location.search;
|
|
const STORAGE_KEY = 'autosave_' + pageKey;
|
|
// Expiration time: 12 hours
|
|
const EXPIRATION_MS = 12 * 60 * 60 * 1000;
|
|
|
|
function saveFormData() {
|
|
const forms = document.querySelectorAll('form');
|
|
let formData = {};
|
|
let hasData = false;
|
|
|
|
forms.forEach((form, formIndex) => {
|
|
const inputs = form.querySelectorAll('input:not([type="password"]):not([type="hidden"]):not([type="submit"]):not([type="file"]), textarea, select');
|
|
let formState = {};
|
|
inputs.forEach(input => {
|
|
// Ignore inputs without a name
|
|
if (!input.name) return;
|
|
|
|
if (input.type === 'checkbox' || input.type === 'radio') {
|
|
formState[input.name] = input.checked;
|
|
} else {
|
|
formState[input.name] = input.value;
|
|
}
|
|
});
|
|
if (Object.keys(formState).length > 0) {
|
|
formData[formIndex] = formState;
|
|
hasData = true;
|
|
}
|
|
});
|
|
|
|
if (hasData) {
|
|
const dataToSave = {
|
|
timestamp: new Date().getTime(),
|
|
data: formData
|
|
};
|
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(dataToSave));
|
|
}
|
|
}
|
|
|
|
function loadFormData() {
|
|
const saved = localStorage.getItem(STORAGE_KEY);
|
|
if (saved) {
|
|
try {
|
|
const parsed = JSON.parse(saved);
|
|
const now = new Date().getTime();
|
|
|
|
// Discard data if it's older than expiration time
|
|
if (now - parsed.timestamp > EXPIRATION_MS) {
|
|
localStorage.removeItem(STORAGE_KEY);
|
|
return;
|
|
}
|
|
|
|
const formData = parsed.data;
|
|
const forms = document.querySelectorAll('form');
|
|
|
|
forms.forEach((form, formIndex) => {
|
|
if (formData[formIndex]) {
|
|
const formState = formData[formIndex];
|
|
const inputs = form.querySelectorAll('input:not([type="password"]):not([type="hidden"]):not([type="submit"]):not([type="file"]), textarea, select');
|
|
|
|
inputs.forEach(input => {
|
|
if (input.name && formState[input.name] !== undefined) {
|
|
if (input.type === 'checkbox' || input.type === 'radio') {
|
|
// Set checked state
|
|
if (input.checked !== formState[input.name]) {
|
|
input.checked = formState[input.name];
|
|
}
|
|
} else {
|
|
// Set value
|
|
if (input.value !== formState[input.name]) {
|
|
input.value = formState[input.name];
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
// Show a small non-intrusive toast notification
|
|
showToast("Восстановлены несохраненные данные");
|
|
} catch (e) {
|
|
console.error("Error parsing autosave data", e);
|
|
}
|
|
}
|
|
}
|
|
|
|
function showToast(message) {
|
|
const toast = document.createElement('div');
|
|
toast.textContent = message;
|
|
toast.style.position = 'fixed';
|
|
toast.style.bottom = '20px';
|
|
toast.style.right = '20px';
|
|
toast.style.backgroundColor = '#494bd6';
|
|
toast.style.color = 'white';
|
|
toast.style.padding = '10px 20px';
|
|
toast.style.borderRadius = '5px';
|
|
toast.style.zIndex = '9999';
|
|
toast.style.fontFamily = '"Plus Jakarta Sans", sans-serif';
|
|
toast.style.fontSize = '12px';
|
|
toast.style.boxShadow = '0 4px 6px rgba(0,0,0,0.3)';
|
|
toast.style.transition = 'opacity 0.5s ease';
|
|
|
|
document.body.appendChild(toast);
|
|
|
|
setTimeout(() => {
|
|
toast.style.opacity = '0';
|
|
setTimeout(() => toast.remove(), 500);
|
|
}, 3000);
|
|
}
|
|
|
|
// Load data on page load
|
|
loadFormData();
|
|
|
|
// Debounce function for saving data so it doesn't trigger on every single keystroke excessively
|
|
let timeout;
|
|
document.addEventListener('input', function(e) {
|
|
if (['INPUT', 'TEXTAREA', 'SELECT'].includes(e.target.tagName)) {
|
|
clearTimeout(timeout);
|
|
timeout = setTimeout(saveFormData, 500);
|
|
}
|
|
});
|
|
|
|
// Clear saved data on successful form submission
|
|
document.addEventListener('submit', function(e) {
|
|
localStorage.removeItem(STORAGE_KEY);
|
|
});
|
|
});
|