Кастомизация
01
Сен
0

Добавление скриптов из внешних файлов

Как Вы знаете, пользовательские скрипты добавляются/редактирование в CRM через редактирование форм. Но способ этот не очень удобный, особенно в процессе разработки. Но есть подход позволяющий вынести JavaScript-код во внешние файлы. Рассмотрим парочку способов…

Локально

Т.е. видимость этих скриптов ограничивается пределами формы, на которую Вы их добавили. Рассмотрим несколько способов…
Предположим у нас есть в папке ISV файл customscript.js с таким содержимом:

function Hello() {
    alert('Hello World');
}


Добавление в DOM структуру тег script

// Создаем тег script
var scriptElement = document.createElement("script");
scriptElement.language = "javascript";
scriptElement.src = "/ISV/customscript.js?nocach=" + Math.random(); // Путь к внешнему JS-файлу и "фишка" чтобы обойти кэширование
scriptElement.attachEvent("onreadystatechange", loadScript); // Ожидаем пока скрипты загрузится и вызываем функцию loadScript

// Добавляем script к тэгу HEAD
document.getElementsByTagName("HEAD")[0].appendChild(scriptElement);

// Функция проверяет, что внешний скрипт загружен и вызывает функцию из него
function loadScript() {
    if (event.srcElement.readyState == "loaded" || event.srcElement.readState == "complete") {
        Hello();
    }
}


Использование объект запроса XmlHttp

В данной технике используете объект XMLHttpRequest для AJAX-запрос загрузки внешнего JS-файла, а затем используется функция Eval() (или execScript()) для «разбора» кода и добавлению его к пространству имен JavaScript.
В отличие от способа с тегом script, эта техника является поддерживаемым способом, т.к. не меняет DOM-структуру. Один недостаток – функция Eval() довольно медленная…

Способ #1

Заключается загрузки внешнего файла и построчная отправка в функцию Eval(). Т.к. у функции есть одно ограничение – в нее нельзя передавать имена функций, в которых присутствуют числа. Поэтому предварительно происходит проверка с помощью регулярного выражения.

function loadScript(url) {
    // Создаем объект XMLHTTP и загружаем файл переданный в параметр url
    var x = new ActiveXObject("Msxml2.XMLHTTP");
    x.open('GET', url, false);
    x.send('');

    // Вытаскиваем текст из XMLHTTP-запроса и разбиваем на строки
    eval(x.responseText);
    var s = x.responseText.split(/\n/);
    
    // Шаблон регулярного вырожения, проверяющий, что в функции или переменной нет чисел
    var r = /^(?:function|var)\s*([a-zA-Z_]+)/i;

    // Построчно загружаем код, проверяем по шаблону регулярного выражения и отправляем в функцию eval
    for (var i = 0; i < s.length; i++) {
        var m = r.exec(s[i]);
        if (m != null) {
            window[m[1]] = eval(m[1]);
        }
    }
}

loadScript("/ISV/customscript.js"); // Загружаем внешний JS-файл
Hello(); // Вызываем функцию из внешнего файла


Способ #2

Упрощенный способ первого варианта: нет необходимости проверять наличие чисел в именах функций:

function loadScript(url) {
    // Создаем объект XMLHTTP и загружаем файл переданный в параметр url
    var xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
    xmlHttp.open("GET", url, false); // Используеи "фишку" чтобы обойти кэширование
    xmlHttp.send();
    // Передаем в функцию execScript() ответ запроса в виде текста
    execScript(xmlHttp.responseText);
}

loadScript("/ISV/customscript.js"); // Загружаем внешний JS-файл
Hello(); // Вызываем функцию из внешнего файла


Глобально

Доступ к скриптам добавленных с помощью нижеописанных способов можно осуществлять из любого места CRM. Без каких либо предварительных манипуляций по подключению внешнего файла на формах.

Global.js

Самый простой способ это повестить какаой-либо код в файл <сайт CRM>\_static\_common\scriptsGlobal.js. Код из него подгржается «в любую точку CRM» 🙂



З.Ы. Для того чтобы Global.js не разростался, Вы можете взять один из скриптов из первой части, чтобы подключить к нему другой js-файл, в котором содержаться ваши кастомные скрипты.

Web.config и HttpModule

XrmLinq.CrmTweaks – этот HttpModule, который цепляется к жизненному циклу asp.net и мониторит все asp.net запросы. Для каждого запроса он проверяет, что подключен как модуль в web.config’е, затем проверяет, что HTTP-запрос обращается к нужной странице и вставляет в нее код из указанного js-файла.

Установка HttpModule’я:

  • Поместите XrmLinq.CrmTweaks.dll в папку <сайт CRM>\bin;
  • Откройте web.config сайта CRM и в секции HttpModules добавьте такую строку:
    <add name="XrmLinqScriptInjector" type="XrmLinq.CrmTweaks.ScriptInjectionFilterModule" />
    
  • А в секции appSettings такие строки:
    <add key="xrmlinq.injectscripts" value="true" />
    <add key="xrmlinq.injectscriptsto" value="edit.aspx" />
    <add key="xrmlinq.scriptstoinject" value="/ISV/customscript.js" />
    
    • injectscripts – включает/отключает модуль;
    • injectscriptsto – список разделенных через запятые страниц CRM, которые Вы хотите, чтобы модуль обрабатывал;
    • scriptstoinject – список разделенных через запятые js-файлов, которые Вы хотите, чтобы модуль включил в страницы определенные в параметре injectscriptsto.
  • Это все 🙂 можете добавлять на формы (именно им соответствует файл edit.aspx) код для вызова функций из внешних файлов.



Как результат:

  • Легко подключать Ваш пользовательский глобальный js-код;
  • Легко обновить: просто измените в пути любую переменную «/path/lib.js? version=<любое_значение>» и пользователь сразу получат обновленный код;
  • Легко поддерживать.
Комментарии (0)

*

code