Разработка
24
Апр
2

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());
    });
}

Здесь у нас два основных момента:

  1. При загрузке страницы мы добавляем триггер на событие изменения хранилища сессии. При добавлении в него нового значения, мы смотрим его: если добавленный в него ключ равен «child», то выводим алерт с его значением, после чего удаляем его.
  2. Добавляем обработчик события на изменение поля 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>

Здесь также у нас два основных момента:

  1. Также при загрузке подключаемся к событию изменения хранилища сессии и при добавлении в него нового значения смотрим его: если это parent, то записываем его в контрол crmField и удаляем ключ из хранилища.
  2. При клике на кнопке помещаем содержимое поля crmField в сессию под ключом «child».


Улучшения

Модель ключ/значение довольно простая и в самом примитивном виде может не отвечать всем потребностям Вашего сложного приложения. Но ничто не мешает Вам внести искусственные улучшения:

  1. Вы может передавать в имени ключа подзначения, например, разделив основную часть от второстепенной двоеточием: child:subname1
    При «прослушке» хранилища Вам нужно разделять и проверять эти подзначения:

    window.addEventListener(
        'storage',
        function (e) {
            if (e.key.split(':')[0] === 'child') {
                if (e.key.split(':')[1] === 'subname1') {
    
                }
            }
        }
    );
    
  2. В самом значении можно передать сложный объект в JSON-формате:
    sessionStorage.setItem('child', JSON.stringify({ fieldName: 'test', disabled: false }));
    

    на выходе расшифровав его следующем образом:

    var sessionStoredValue = JSON.parse(e.newValue)[d];
    
Комментарии (2)
  • Michael Goriachev 24.04.2017

    Круто! Никогда не задумавался об этом. А оно поддерживается? Можно ли юзать в онлайн?

  • slivka_83 24.04.2017

    Да вроде поддерживается. Точнее это не функционал CRM как таковой, а функционал браузера, а именно его поддержка стандарта HTML5.

*

code