Почему важно сохранять черновики форм в WPForms
При работе с большими или многошаговыми формами пользователи часто сталкиваются с проблемой потери введённых данных из-за случайного закрытия страницы, сбоев интернета или других технических причин. Автоматическое сохранение черновиков позволяет сохранять текущие ответы и загруженные файлы, чтобы пользователь мог вернуться и продолжить заполнение без потери данных.
В WPForms нет штатного функционала для автосохранения черновиков, но с помощью кастомного кода и хуков можно реализовать эту возможность.
Диагностика проблемы: как проверить, что данные формы не сохраняются
- Пользователь жалуется на потерю данных при обновлении страницы;
- Отсутствие функции возврата к незавершённой форме;
- Файлы не сохраняются, если форма не отправлена;
- Проверка в консоли разработчика на ошибки JavaScript;
- Отсутствие AJAX-запросов на сохранение данных при вводе.
Пошаговое решение: реализация автосохранения черновиков в WPForms
1. Хранение данных формы в локальном хранилище браузера
Для начала реализуем сохранение введённых данных формы в localStorage с помощью JavaScript. Это позволит сохранять данные на стороне клиента и восстанавливать их при перезагрузке.
document.addEventListener('DOMContentLoaded', function () {
const form = document.querySelector('.wpforms-form');
if (!form) return;
// Загрузка данных из localStorage
const savedData = localStorage.getItem('wpforms_draft');
if (savedData) {
const data = JSON.parse(savedData);
for (const [name, value] of Object.entries(data)) {
const field = form.querySelector(`[name="${name}"]`);
if (field) {
field.value = value;
}
}
}
// Сохранение данных при изменении полей
form.addEventListener('input', function () {
const inputs = form.querySelectorAll('input, textarea, select');
const formData = {};
inputs.forEach(input => {
if (input.name) {
formData[input.name] = input.value;
}
});
localStorage.setItem('wpforms_draft', JSON.stringify(formData));
});
});2. Поддержка загрузки файлов через AJAX для сохранения в черновике
Файлы нельзя сохранить в localStorage из-за ограничений браузера, поэтому реализуем их загрузку на сервер в отдельном AJAX-запросе сразу после выбора файла. Для этого добавим обработчик на input type="file".
document.querySelectorAll('.wpforms-form input[type="file"]').forEach(input => {
input.addEventListener('change', function () {
const file = this.files[0];
if (!file) return;
const formData = new FormData();
formData.append('file', file);
formData.append('action', 'wpforms_save_draft_file');
formData.append('field_name', this.name);
fetch(wpforms_vars.ajax_url, {
method: 'POST',
credentials: 'same-origin',
body: formData
})
.then(response => response.json())
.then(data => {
if (data.success) {
// Сохраняем в localStorage путь к файлу для восстановления
let draftFiles = JSON.parse(localStorage.getItem('wpforms_draft_files') || '{}');
draftFiles[this.name] = data.file_url;
localStorage.setItem('wpforms_draft_files', JSON.stringify(draftFiles));
} else {
alert('Ошибка загрузки файла: ' + data.data);
}
});
});
});3. Обработка AJAX-запроса на сервере для сохранения файлов
Добавим PHP-функцию, которая сохраняет загруженный файл во временную папку и возвращает URL для восстановления.
add_action('wp_ajax_wpforms_save_draft_file', 'wpforms_save_draft_file_callback');
add_action('wp_ajax_nopriv_wpforms_save_draft_file', 'wpforms_save_draft_file_callback');
function wpforms_save_draft_file_callback() {
if (empty($_FILES['file'])) {
wp_send_json_error('Файл не загружен');
}
$uploaded = $_FILES['file'];
$upload_overrides = array('test_form' => false);
$movefile = wp_handle_upload($uploaded, $upload_overrides);
if ($movefile && !isset($movefile['error'])) {
wp_send_json_success(array('file_url' => $movefile['url']));
} else {
wp_send_json_error($movefile['error']);
}
}4. Восстановление загруженных файлов при загрузке страницы
Добавим JS код, который вставляет ссылки на загруженные файлы обратно в форму (например, в виде превью или ссылки для скачивания).
document.addEventListener('DOMContentLoaded', function () {
const draftFiles = JSON.parse(localStorage.getItem('wpforms_draft_files') || '{}');
for (const [fieldName, fileUrl] of Object.entries(draftFiles)) {
const container = document.querySelector(`.wpforms-form [name="${fieldName}"]`).parentNode;
if (container) {
const link = document.createElement('a');
link.href = fileUrl;
link.textContent = 'Ранее загруженный файл';
link.target = '_blank';
container.appendChild(link);
}
}
});Проверка результата после внедрения
- Откройте форму WPForms и введите данные в поля;
- Загрузите файл в поле с типом file;
- Обновите страницу браузера без отправки формы;
- Проверьте, что данные полей и ссылка на загруженный файл восстановились;
- Отправьте форму и убедитесь, что данные передаются корректно.
Частые ошибки и их исправление
- Данные не сохраняются в localStorage. Проверьте, правильно ли подключён JS-код и нет ли ошибок в консоли браузера.
- Файлы не загружаются или сервер возвращает ошибку. Проверьте настройки PHP (upload_max_filesize, post_max_size), права папки uploads и корректность AJAX-обработчика.
- При восстановлении файла ссылка не отображается. Убедитесь, что ключи в localStorage совпадают с именами полей формы и что код вставки ссылки корректно находит контейнер.
- Конфликты с другими скриптами или плагинами. Проверьте совместимость, отключите другие плагины для теста.
Практические советы по безопасности и производительности
- Используйте nonce-проверку в AJAX-запросах для защиты от CSRF.
- Ограничьте размер и типы загружаемых файлов в PHP и JavaScript.
- Очищайте локальное хранилище после успешной отправки формы, чтобы не накапливать устаревшие данные.
- Для больших форм с большим количеством полей применяйте дебаунсинг на событие input, чтобы не перегружать localStorage.
- Реализуйте автоматическую очистку временных файлов на сервере через cron, чтобы не засорять upload-папку.
Сравнение методов сохранения черновиков в WPForms
| Метод | Преимущества | Недостатки | Пример применения |
|---|---|---|---|
| localStorage + AJAX для файлов | Быстрое локальное сохранение, не нагружает сервер, можно восстановить данные при перезагрузке | Не подходит для очень больших данных, файлы требуют отдельной загрузки, зависит от браузера | Реализация в статье |
| Сохранение черновиков в базе данных (через AJAX) | Данные централизованы, можно использовать на разных устройствах | Требует настройки серверной части и дополнительных таблиц, увеличивает нагрузку | Плагины для кастомных черновиков, сложная интеграция |
| Использование сторонних плагинов автосохранения | Готовое решение, поддержка и обновления | Дополнительные затраты, возможные конфликты | Плагины автосохранения форм |