В версии главного модуля 11.0.1 (от 29.09.11) был реализован функционал сохранения веб-форм. Хотелось бы его использовать для своих веб-форм, однако, описания использования и API пока нет. Стало интересно разобрать механизмы.
Минимальный код для автосохранения своей формы выглядит следующим образом:
Рассмотрим его подробнее.
1. Вначале вызывается статический метод Allowed класса CAutoSave. Данный метод позволяет определить, разрешено ли вообще сохранение. Возвращает true если выполняются следующие условия:
• пользователь авторизован
• включено автосохранение форм в настройках интерфейса
/bitrix/admin/user_settings.php?lang=ru
• текущая страница не /bitrix/admin/update_system.php
2. Далее в конструкторе класса ($AUTOSAVE = new CAutoSave()) определяется autosaveId - уникальный ID записи для сохранения и восстановления нашей веб-формы.
В формировании этого id учавствуют: текущий url (без параметров), ID пользователя, следующие ключи в $_GET (регистронезависимо):
Т.е. если перед инициализацией у нас будет $_GET['NAME'] ='123', то результирующий autosaveId будет отличаться от того, если бы его не было.
Так же в $_GET учитываются ключи, символы которых оканчиваются на ID
Для определения autosaveId используется такой алгоритм:
'2'.md5($this->formId.'|'.$GLOBALS['USER']->GetID());
3. Вызываем метод Init. Данный метод для публичной части:
• Инициализирует библиотеку CJSCore::Init(array('autosave'), true)
• Добавляет hidden поле
<input type="hidden" name="autosave_id" id="autosave_marker_<?=$this->GetID()?>" value="<?=$this->GetID()?>" />
• Создает javaScript-объект window .autosave_<?=$this->GetID()?> = new top.BX .CAutoSave
Запускаем наш скрипт, вводим в поле какое-либо значение и немного ждем до автосохранения
Обновляем страницу через F5, видим то что нужно
Как это работает:
- Созданный javaScript-объект window .autosave_<?=$this->GetID()?> на событие готовности документа BX .ready собирает элементы формы и вешает на их события change, keyup, click обработчик.
- В обработчике происходит сбор данных формы и отправка их файлу /bitrix/tools/autosave.php, при этом передается autosaveId, что позволяет в точности сказать, какая форма передала данные (при передаче autosaveId перед конструктором попытка восстановления формы [при данной попытке запись удаляется из базы] не производится)
- Данные сохраняются в таблице b_undo
- Далее, при обновлении страницы данные записываются в javaScript (их мы можем восстановить через желтое окно), а из базы удаляются.
Для принудительного сохранения данных нужно вызвать метод Save объекта
window .autosave_2ce25983ea86048d216fe1e8099ec1688.Save();
Несколько веб-форм на одной странице:
Если имеется несколько веб-форм на одной странице, то по умолчанию у них будут одинаковые autosaveId. Нужно использовать переменные $_GET, оканчивающиеся на ID:
Однако, поскольку после загрузки страницы данные стираются из базы, а из окна восстановления мы можем восстановить только одну форму, то восстановление нужно не через окно восстановления, а напрямую, через метод Restore
window .autosave_20565efe71c10207c52dc03d35b6e6a6f.Restore();
window .autosave_23bbe98db68ee55636cbc5fcf25b47755.Restore();
, например, с помощью кнопки.
Минимальный код для автосохранения своей формы выглядит следующим образом:
<?require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php");?> <fo rm action="/test/bxauths.php"> <input type="text" name="saveinput1"> <? if (CAutoSave::Allowed()) { $AUTOSAVE = new CAutoSave(); $AUTOSAVE->Init(); } ?> </form> <?require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php");?> |
1. Вначале вызывается статический метод Allowed класса CAutoSave. Данный метод позволяет определить, разрешено ли вообще сохранение. Возвращает true если выполняются следующие условия:
• пользователь авторизован
• включено автосохранение форм в настройках интерфейса
/bitrix/admin/user_settings.php?lang=ru
• текущая страница не /bitrix/admin/update_system.php
2. Далее в конструкторе класса ($AUTOSAVE = new CAutoSave()) определяется autosaveId - уникальный ID записи для сохранения и восстановления нашей веб-формы.
В формировании этого id учавствуют: текущий url (без параметров), ID пользователя, следующие ключи в $_GET (регистронезависимо):
$arImportantParams = array('LANG'=>1, 'SITE'=>1, 'PATH'=>1, 'TYPE'=>1, 'EVENT_NAME'=>1, 'SHOW_ERROR'=>1, 'NAME'=>1, 'FULL_SRC'=>1, 'ACTION'=>1, 'LOGICAL'=>1, 'ADMIN'=>1, 'ADDITIONAL'=>1, 'NEW'=>1, 'MODE'=>1, 'CONDITION'=>1, 'QUESTION_TYPE'=>1); |
Так же в $_GET учитываются ключи, символы которых оканчиваются на ID
Для определения autosaveId используется такой алгоритм:
'2'.md5($this->formId.'|'.$GLOBALS['USER']->GetID());
3. Вызываем метод Init. Данный метод для публичной части:
• Инициализирует библиотеку CJSCore::Init(array('autosave'), true)
• Добавляет hidden поле
<input type="hidden" name="autosave_id" id="autosave_marker_<?=$this->GetID()?>" value="<?=$this->GetID()?>" />
• Создает javaScript-объект window .autosave_<?=$this->GetID()?> = new top.BX .CAutoSave
Запускаем наш скрипт, вводим в поле какое-либо значение и немного ждем до автосохранения
Обновляем страницу через F5, видим то что нужно
Как это работает:
- Созданный javaScript-объект window .autosave_<?=$this->GetID()?> на событие готовности документа BX .ready собирает элементы формы и вешает на их события change, keyup, click обработчик.
- В обработчике происходит сбор данных формы и отправка их файлу /bitrix/tools/autosave.php, при этом передается autosaveId, что позволяет в точности сказать, какая форма передала данные (при передаче autosaveId перед конструктором попытка восстановления формы [при данной попытке запись удаляется из базы] не производится)
- Данные сохраняются в таблице b_undo
- Далее, при обновлении страницы данные записываются в javaScript (их мы можем восстановить через желтое окно), а из базы удаляются.
Для принудительного сохранения данных нужно вызвать метод Save объекта
window .autosave_2ce25983ea86048d216fe1e8099ec1688.Save();
Несколько веб-форм на одной странице:
Если имеется несколько веб-форм на одной странице, то по умолчанию у них будут одинаковые autosaveId. Нужно использовать переменные $_GET, оканчивающиеся на ID:
Однако, поскольку после загрузки страницы данные стираются из базы, а из окна восстановления мы можем восстановить только одну форму, то восстановление нужно не через окно восстановления, а напрямую, через метод Restore
window .autosave_20565efe71c10207c52dc03d35b6e6a6f.Restore();
window .autosave_23bbe98db68ee55636cbc5fcf25b47755.Restore();
, например, с помощью кнопки.