sessionStorage для взаимодействия между элементами формы
Хранилище сессии — это функция HTML 5, которая позволяет централизовано и универсально обмениваться данными между различными частями веб-приложения.
Какое это имеет отношение к CRM? Это можно использовать, чтобы обмениваться данными между iFrame и основной страницей. Обычно, чтобы получить доступ с формы в iFrame’е и наоборот используются всякие window.parent и childNodes. Но есть и альтернативный путь – в sessionStorage. sessionStorage хранится пока окно браузера открыто и удаляется, как только Вы закрываете вкладку браузера/окно. Значения в sessionStorage хранятся в формате ключ/значение.
Предположим, что на форме есть скрипты и iFrame и мы хотим из iFrame’а выполнять какие-либо действия на основной форме и обратно.
Скрипт на onLoad формы:
function onLoad() { window.addEventListener( 'storage', function (e) { if (e.key === 'child' & e.newValue != "") { alert(e.newValue); sessionStorage.removeItem(e.key); } } ); Xrm.Page.getAttribute('name').addOnChange(function () { sessionStorage.setItem('parent', Xrm.Page.getAttribute('name').getValue()); }); }
Здесь у нас два основных момента:
- При загрузке страницы мы добавляем триггер на событие изменения хранилища сессии. При добавлении в него нового значения, мы смотрим его: если добавленный в него ключ равен «child», то выводим алерт с его значением, после чего удаляем его.
- Добавляем обработчик события на изменение поля name: при изменении значения, добавляем в хранилище ключ «parent», со значением поля name.
Содержимое iFrame:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Form IFrame</title> <script> window.addEventListener('storage', function(e) { if (e.key === 'parent' & e.newValue != "") { document.getElementById("crmField").value = e.newValue; sessionStorage.removeItem(e.key); } }); function onClickF() { sessionStorage.setItem('child', document.getElementById("crmField").value); } </script> </head> <body> <input type="text" id="crmField"> <button onclick="onClickF()">Send</button> </body> </html>
Здесь также у нас два основных момента:
- Также при загрузке подключаемся к событию изменения хранилища сессии и при добавлении в него нового значения смотрим его: если это parent, то записываем его в контрол crmField и удаляем ключ из хранилища.
- При клике на кнопке помещаем содержимое поля crmField в сессию под ключом «child».
Улучшения
Модель ключ/значение довольно простая и в самом примитивном виде может не отвечать всем потребностям Вашего сложного приложения. Но ничто не мешает Вам внести искусственные улучшения:
- Вы может передавать в имени ключа подзначения, например, разделив основную часть от второстепенной двоеточием: child:subname1
При «прослушке» хранилища Вам нужно разделять и проверять эти подзначения:window.addEventListener( 'storage', function (e) { if (e.key.split(':')[0] === 'child') { if (e.key.split(':')[1] === 'subname1') { } } } );
- В самом значении можно передать сложный объект в JSON-формате:
sessionStorage.setItem('child', JSON.stringify({ fieldName: 'test', disabled: false }));
на выходе расшифровав его следующем образом:
var sessionStoredValue = JSON.parse(e.newValue)[d];
Круто! Никогда не задумавался об этом. А оно поддерживается? Можно ли юзать в онлайн?
Да вроде поддерживается. Точнее это не функционал CRM как таковой, а функционал браузера, а именно его поддержка стандарта HTML5.