logo

1 февр. 2013 г.

BIEE11g: задать значения переменных презентации javascript-функцией

Привет всем!
На днях узнал, что кодом из самого первого сообщения этого блога все-таки кто-то пользуется.
А именно, javascript-функцией инициализации переменных презентации.
С переходом на Oracle BI 11g эта функция, разумеется, перестала работать.

После некоторых изысканий хочу опубликовать адаптацию под версию 11g.


Сразу оговорюсь, что функция тестировалась на версии Oracle BI 11.1.1.6.2.

Сам код функции:
<script type="text/javascript">
    function setPresVariable(aArgs) {
        if ( !aArgs || aArgs.length == 0) return;

        var tUnionExpr = XUICreateElement(saw.xml.kSawxNamespace, "expr");
        tUnionExpr.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
        tUnionExpr.setAttribute("xsi:type", "sawx:logical");
        tUnionExpr.setAttribute("op", "and");

        var sPresVar;
        var sValue;
        for (var i = 0; i < aArgs.length; i++) {
            sPresVar = aArgs[i][0];
            sValue = aArgs[i][1];

            var tExpr = XUICreateElement(saw.xml.kSawxNamespace, 'expr');
            XUISetAttributeString(tExpr, "setVariable", "dashboard.variables['" + sPresVar + "']");
            tExpr.setAttribute("xsi:type", "sawx:setVariable");
            tExpr.setAttribute("op", "in");
            tExpr.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");

            var tSQLExpr = XUICreateElement(saw.xml.kSawxNamespace, 'expr');
            tSQLExpr.setAttribute("xsi:type", "sawx:sqlExpression");
            tExpr.appendChild(tSQLExpr);

            var tValExpr = XUICreateElement(saw.xml.kSawxNamespace, 'expr');
            tValExpr.setAttribute("xsi:type", "sawx:untypedLiteral");
            XUISetElementText(tValExpr, sValue);
            tExpr.appendChild(tValExpr);

            tUnionExpr.appendChild(tExpr);
        }

        if (aArgs.length == 1) {
            tUnionExpr = tUnionExpr.firstChild
        }

        var bInlineReload = true;
        var sAction = "PromptFinish";

        var tDashViewController = obidash.getViewController();
        var tClientStateManager = tDashViewController.getClientStateManager();

        var sStatePath = tClientStateManager.getCurrentStatePath();
        var tStateXML = tClientStateManager.clientStateXml;

        tStateXMLExpr = saw.parseXML(tStateXML.xml);
        var aSectionsStatePath = tStateXMLExpr.selectNodes("//sawst:container[@xsi:type = 'sawst:section' ]");
        var aPromptsStatePath = tStateXMLExpr.selectNodes("//sawst:container[@xsi:type = 'sawst:dashprompt' ]");

        sStatePath = sStatePath + '~' + aSectionsStatePath[0].getAttribute("cid") + '~' + aPromptsStatePath[0].getAttribute("cid");

        return PromptManager.submitPrompt(sStatePath, bInlineReload, sAction, tUnionExpr);
}
</script>

Тестировал я ее следующим образом:
1. Поместил на информационную панель 2 текстовых элемента и одну произвольную подсказку инфопанели (наличие хоть какой-нибудь подсказки обязательно для функции).


Первый текстовый элемент содержит код функции (соответственно, выставлена галка "Contains HTML Markup") и кнопку, вызывающую эту функцию.
<script type="text/javascript">
    function setPresVariable(aArgs) {
        if ( !aArgs || aArgs.length == 0) return;

        var tUnionExpr = XUICreateElement(saw.xml.kSawxNamespace, "expr");
        tUnionExpr.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
        tUnionExpr.setAttribute("xsi:type", "sawx:logical");
        tUnionExpr.setAttribute("op", "and");

        var sPresVar;
        var sValue;
        for (var i = 0; i < aArgs.length; i++) {
            sPresVar = aArgs[i][0];
            sValue = aArgs[i][1];

            var tExpr = XUICreateElement(saw.xml.kSawxNamespace, 'expr');
            XUISetAttributeString(tExpr, "setVariable", "dashboard.variables['" + sPresVar + "']");
            tExpr.setAttribute("xsi:type", "sawx:setVariable");
            tExpr.setAttribute("op", "in");
            tExpr.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");

            var tSQLExpr = XUICreateElement(saw.xml.kSawxNamespace, 'expr');
            tSQLExpr.setAttribute("xsi:type", "sawx:sqlExpression");
            tExpr.appendChild(tSQLExpr);

            var tValExpr = XUICreateElement(saw.xml.kSawxNamespace, 'expr');
            tValExpr.setAttribute("xsi:type", "sawx:untypedLiteral");
            XUISetElementText(tValExpr, sValue);
            tExpr.appendChild(tValExpr);

            tUnionExpr.appendChild(tExpr);
        }

        if (aArgs.length == 1) {
            tUnionExpr = tUnionExpr.firstChild
        }

        var bInlineReload = true;
        var sAction = "PromptFinish";

        var tDashViewController = obidash.getViewController();
        var tClientStateManager = tDashViewController.getClientStateManager();

        var sStatePath = tClientStateManager.getCurrentStatePath();
        var tStateXML = tClientStateManager.clientStateXml;

        tStateXMLExpr = saw.parseXML(tStateXML.xml);
        var aSectionsStatePath = tStateXMLExpr.selectNodes("//sawst:container[@xsi:type = 'sawst:section' ]");
        var aPromptsStatePath = tStateXMLExpr.selectNodes("//sawst:container[@xsi:type = 'sawst:dashprompt' ]");

        sStatePath = sStatePath + '~' + aSectionsStatePath[0].getAttribute("cid") + '~' + aPromptsStatePath[0].getAttribute("cid");

        return PromptManager.submitPrompt(sStatePath, bInlineReload, sAction, tUnionExpr);
}
</script>
<button onclick="setPresVariable([ ['P_TEST_VAR', 'YOU CAN DO IT!!!'] ])">Press to set Presentation Var 'P_TEST_VAR'</button>

Второй элемент служит для проверки инициализации переменной и содержит просто текст
P_TEST_VAR = '@{P_TEST_VAR}{nothing}'

Подсказка инфопанели функционально не используется, поэтому она расположена в Секции, у которой выставлено CSS-свойство display:none


2. В режиме просмотра информационной панели просто нажал на созданную кнопку.


Результат "налицо"!


НЮАНСЫ:
- функция работает только в рамках информационной панели (использовать ее только внутри Анализа, без публикации Анализа на инфопанели, не получится);
- на информационной панели обязательно должна быть хоть одна подсказка инфопанелей (пусть даже совершенно "левая" - ее можно скрыть).

13 комментариев:

  1. Скажите как изменить текст функции, если надо одновременно установить 2 переменные

    ОтветитьУдалить
  2. Извините, пропустил ваш вопрос...
    Вечером внесу изменения в код функции данного сообщения для поддержки нескольких переменных.

    ОтветитьУдалить
  3. Внес изменения в тело javascript-функции.
    Теперь для того, чтобы одним вызовом функции проинициализировать значения, например, 2-х презентационных переменных, следует использовать:
    setPresVariable([ ['P_TEST_VAR', 'YOU CAN DO IT!!!'], ['P_TEST_VAR2', 'Yes, just do it!'] ])

    ОтветитьУдалить
  4. Спасибо здорово.
    Есть ещё такой вопрос:

    Предположим я использую комбо-бокс
    В теге table размещаю сам комбо бокс и кнопку применить c onclick=doSubmit()
    doSubmit() вызывает setPresVariable с зачением из комбо-бокса
    далее после тега table размещаю тег script type="text/javascript":
    Внутри тега:
    var
    vCombo = document.getElementById("MY_ID");
    vCombo.value = '@{MY_P}{0}';

    Так вот, после нажатия на кнопку "применить", код, который инициализирует комбо-бокс значением переменной не отрабатывает, хотя сама переменная принимает нужное значение
    Аналогичный код на BI10 работал.
    Подскажите, пожалуйста, что не так?

    ОтветитьУдалить
  5. Здорово!
    А есть ли возможность таким макаром заполнить переменную содержимым ячейки в таблице по Action'у? Или, может быть, это можно сделать другим макаром? =)

    ОтветитьУдалить
  6. Есть тип Action - "Сценарий в браузере" - чистый javascript.
    Его и используйте: пропишите в USERSCRIPTS.js функцию, которая будет инициализировать переменную презентации, и вызывайте ее в Action.

    ОтветитьУдалить
  7. Возможно, сюда это не очень в тему, но ваш пост наиболее близок к моей проблеме из всего, что я пока нашла) В общем, задача такая - при использовании выпадающего списка в переменную нужно записать не само значение из списка, а его айдишник в таблице. Нет ли идей, как это можно сделать?

    Заранее спасибо)

    ОтветитьУдалить
  8. Здравствуйте, Евгения!
    Отвечу на этих выходных...

    ОтветитьУдалить
  9. Jack Carver, добрый день!

    Есть ли возможность используя javascript изменять при редактировании анализа стандартные параметры (к примеру изменить параметры, которые меняются при редактировании формулы столбца - заголовки, правила агрегирования)?


    Спасибо)

    ОтветитьУдалить
    Ответы
    1. Можно многое сделать. Вопрос в целесообразности. Так как зачастую подобное трудно реализовать.
      Приведите конкретный пример того, что вы хотите делать в JS для манипуляции элементами BI.

      Удалить
    2. Пример кода, который пока не работает:

      var f = XUICreateElement(saw.xml.kSawNamespace, "report");
      f.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
      f.setAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
      f.setAttribute("xmlns:sawx", "com.siebel.analytics.web/expression/v1.1");

      var j = new Object();
      j.onApply = true;

      var g = new saw.ajax.Request("GetColumnInfoXML", this.loadColumnInfo, this, j);
      g.setFatalErrorHandler(this.handleServerError);

      g.addArg("ReportXML", saw.getXmlText(f));
      g.addArg("ColumnID", "c5648bab168d17c65"); //входной параметр
      g.addArg("_scid", obips_scid);
      g.addArg("aggRule", "default");
      g.addArg("ajaxType", "xhr");
      g.addArg("columnHdg", "Revenue2"); //входной параметр
      g.addArg("customHdg", "x"); //входной параметр
      g.addArg("formula", "\"Base Facts\".\"Revenue\"");
      g.addArg("icharset", "utf-8");
      g.addArg("tableHdg", "Base Facts");

      var d = saw.ajax.createConnection(g);
      d.post();

      Функционал отлаживаю в: \war\res\b_mozilla\answers\columnformulaeditor.js

      Удалить
    3. Что именно вы хотите реализовать подобным образом?

      Удалить
  10. Попробовали использовать Вашу функцию и заметили такую вещь: если функцию вызывать по событию, связанному с промптом на страницу(клик/наведение на кнопку применить), то значение промпта сбрасывается на предыдущее значение. Как это можно вылечить?

    ОтветитьУдалить