Кастомизация
09
Май
3

Два зависимых вложенных Представления на форме

Предположим на форме объекта X имеется два вложенных Представления. Причем при выборе записи в первом Представлении должно отфильтровываться второе Представление. Т.е. первое представление родительское, а второе подчиненное. Рассмотрим пример, когда в первом представлении отображаются связанные с текущей формой Организации, а во втором отображаются дочерние Организации по отношению к той, которая выбрана в первом представлении.

  • Для начала, вынесите на форму нужного объекта (в данном случае это Интерес), два вложенных Представления Организаций. Для первого Представления задайте отображение только связанных записей, а для второго Представления задайте отображение всех записей;
  • Создайте JS Веб-ресурс с таким кодом:
    var GridClick = function (pgrid, sgrid, sfield, defaultid) {
        var ids = document.getElementById(pgrid).control.get_selectedIds();
        var id = defaultid;
        if (ids.length > 0) { id = ids[0]; }
    
        var updateFetchXml = function (fetchxml, field, id) {
            var offset = 19;
            var fi = fetchxml.indexOf('<condition attribute="' + field + '" operator="eq" uitype="account" uiname="Advanced Components (sample)" ');
            var nfetchxml = '';
            var closings = '';
            if (fi >= 0) {
                nfetchxml = fetchxml.substring(0, fi);
                offset = fetchxml.indexOf('/>', fi) - fi + 2;
            } else {
                fi = fetchxml.indexOf('<filter type="and">');
                if (fi < 0) {
                    offset = 0;
                    fi = fetchxml.indexOf('<entity');
                    fi = fetchxml.indexOf('/>', fi) + 2;
                    closings = '</filter>';
                }
                nfetchxml = fetchxml.substring(0, fi);
                nfetchxml += '<filter type="and">';
            }
    
            nfetchxml += '<condition attribute="' + field + '" ';
            nfetchxml += 'operator="eq" value="' + id + '" />';
            nfetchxml += closings;
            nfetchxml += fetchxml.substring(fi + offset);
            return nfetchxml;
        };
    
        var updateXml = function (grid, xmlfield, subgridfield) {
            try {
                var g = document.getElementById(grid).control;
                var a = g.getParameter(xmlfield)
                var b = updateFetchXml(a, subgridfield, id);
                g.setParameter(xmlfield, b);
            } catch (e) { }
        };
    
        // Меняем FetchXml'ки...
        updateXml(sgrid, "fetchXml", sfield);
        updateXml(sgrid, "effectiveFetchXml", sfield);
        updateXml(sgrid, "fetchXmlForFilters", sfield);
    
        // Обновляем Представление
        document.getElementById(sgrid).control.refresh();
    };
    
    var registerSubGridUpdate = function (pgrid, sgrid, sfield) {
        var p = document.getElementById(pgrid);
        var s = document.getElementById(sgrid);
        // Ожидаем пока покажется представление
        if (!p && !s) {
            setTimeout('registerSubGridUpdate("' + pgrid + '","' + sgrid + '","' + sfield + '")', 1000); return;
        }
        if (p.readyState != "complete" || s.readyState != "complete") {
            setTimeout('registerSubGridUpdate("' + pgrid + '","' + sgrid + '","' + sfield + '")', 1000); return;
        }
    
        // Формируем функцию-обработчик клика
        var el = document.getElementById(pgrid);
        var f = "var ef = function() { " +
            "GridClick('" + pgrid + "','" + sgrid + "','" + sfield +
            "','{00000000-0000-0000-0000-000000000000}');" +
        " };";
        eval(f);
    
        // Присоединяем функцию к событию клика
        el.attachEvent("onclick", ef, false);
    
        // Включаем FetchXML в Представлении
        document.getElementById(sgrid + '_filterSet').control.RefreshWithFilters();
    
        // Если выделена хотя бы одна запись, то вызываем функцию GridClick
        var r = document.getElementById(pgrid).control.get_allRecordIds();
    
        if (r.length == 0) {
            GridClick(pgrid, sgrid, sfield, "{00000000-0000-0000-0000-000000000000}");
        } else {
            var row = document.getElementById('checkBox_' + r[0]);
            do { row = row.parentNode; }
            while (row.nodeName !== "TR");
            row.fireEvent("onclick");
        } try {
            document.getElementById(sgrid + "_filterSet").control.ToggleFilters(true);
        } catch (e) { }
        document.getElementById(sgrid).control.refresh();
    };
    

    Тут у нас две функции. Первая инициализирует запуск фильтрации, подключает события клика и т.д. А вторая собственно и производит фильтрацию, динамически получая FetchXML из текущего представления;

  • Подключите JS Веб-ресурс к форме и на онлоаде вызовите функцию registerSubGridUpdate и передайте ей следующие параметры:
    • Имя родительского вложенного Представления;
    • Имя дочернего вложенного Представления;
    • Имя поля из подчиненного вложенного Представления, которое ссылается на запись из родительского вложенного Представления.




Комментарии (3)
  • Roman 09.05.2012

    спасибо за код! Я лишь убрал в начале uitype=»account» uiname=»Advanced Components (sample)» , и заработало! Вопрос — встречал в и-нете метки этого кода как «unsupported», но в списке неподдерживаемых изменений не нашёл, почему. Можете ли помочь — если этот код неподдерживаемый, то можно ли как-то его исправить? Спасибо.

  • slivka_83 09.05.2012

    Да вроде нельзя.
    К неподдерживаемым относятся манипуляции с DOM’ом
    на это указывает например применение document.getElementById. И это не исправить, т.к. стандартных поддерживаемых методов производить такие манипуляции нет.

  • Roman 09.05.2012

    Понял, спасибо за разъяснение.

*

code