Кастомизация
23
Сен
16

Представление и форма в одном «флаконе», эпизод II

Помните статью Представление и форма в одном «флаконе»? 🙂 Довольно бесполезное решение с точки зрения разумности применения (но довольно полезное для понимания некоторых моментов работы CRM) 🙂 Сейчас рассморим, возможно, более удачное применение этой концепции – перенесем его на «большой экран» – т.е. в главное окно CRM. Так что счастливые владельцы «широкоформатников» – ликуйте! 🙂

Итак…

  • Создайте в папка в ISV сайта CRM подпапку doubleview. В нее поместите файл account2.gif (это иконка для пункта панели навигации, который мы добавим позже);
  • В папке doubleview создайте файл MasterView.htm и поместите в него такой код:
    <html>
        <head/>
        <body onload="result.submit()">
            <FORM id=result action="/AdvancedFind/fetchData.aspx" method="post">
                <INPUT type=hidden value='<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false"><entity name="account"><attribute name="name"/><attribute name="address1_city"/><attribute name="primarycontactid"/><attribute name="telephone1"/><attribute name="accountid"/><order attribute="name" descending="false"/><filter type="and"><condition attribute="statecode" operator="eq" value="0"/></filter></entity></fetch>' name=FetchXml> 
                <INPUT type=hidden value='<grid name="resultset" object="1" jump="name" select="1" icon="1" preview="1"><row name="result" id="accountid"><cell name="name" width="300" /><cell name="primarycontactid" width="150" /><cell name="telephone1" width="100" /><cell name="address1_city" width="100" /></row></grid>' name=LayoutXml> 
                <INPUT type=hidden value="account" name="EntityName"> 
                <INPUT type=hidden value="{00000000-0000-0000-00AA-000000666000}" name="DefaultAdvFindViewId"> 
                <INPUT type=hidden value="{00000000-0000-0000-00AA-000010001002}" name="ViewId"> 
                <INPUT type=hidden value="1039" name="ViewType"> 
                <INPUT type=hidden value="name" name="SortCol"> 
                <INPUT type=hidden value="false" name="SortDescend"> 
            </FORM>
        </body>
    </html>
    

    Тут применяется довольно интересный подход для задания параметров для Расширенного поиска CRM. Основа ему — HTML-фарма, которая в скрытых полях задает параметры для расширенного поиска. Три самых важных поля:

    • FetchXml: задется Fetch-запрос отправляемый в CRM;
    • LayoutXml: разметка выводимых столбцов;
    • EntityName: имя объекта CRM в котором производится поиск.

    А на событие onload страницы повешан скрипт отправки формы по адресу /AdvancedFind/fetchData.aspx. В результате Расширенный поиск нам вернет найденные (в соответствии с Fetch-запросом) записи. Вообщем очень удобный (программный) способ использования расширенного поиска 🙂

  • Создайте в папке doubleview еще один файл – MasterDetailView.htm. Добавьте в него следующий код:
    <html>
        <head>
            <script language="javascript" type="text/javascript">
                // Функция при изменении размеров окна браузера, меняет размер IFrame'ов по высоте доступной области 
                function OnResizeComplete()  
                {
                    var fr = window.document.getElementById('iframe_masterRecordsGrid');
                    fr.style.height = document.body.clientHeight;
                    var fr2 = window.document.getElementById('DetailArea');
                    fr2.style.height = document.body.clientHeight - 2;
                }
                  
                var recordBaseURL = "/sfa/accts/edit.aspx?id="; // Базовый путь к странице редактирования бизнес-партнера
    
                // При загрузке страницы присоеденяем функцию AttachGridEvent к изменению состояния загрузки iFrame'а 
                function initIframes() {
                    document.getElementById("iframe_masterRecordsGrid").onreadystatechange = AttachGridEvent;
                    OnResizeComplete() // Подгоняем размер iFrame'а под высоту страницы
                }
    
                // Присоединяем к событию выделения строки функцию GridClick
                AttachGridEvent = function () {
                    if (document.getElementById("iframe_masterRecordsGrid").readyState == "complete") {
    
                        var frameDoc = document.getElementById("iframe_masterRecordsGrid").contentWindow.document;
                        frameDoc.all['crmGrid'].InnerGrid.attachEvent("onselectionchange", GridClick);
                        GridClick();
    
                        // Убираем лишние поля в представлении
                        frameDoc.childNodes[0].childNodes[1].style.padding = 0;
                    }
                }
    
                // Функция при щелчке на строке представления обновляет содержимое второго iFrame'а
                GridClick = function () {
                    // Вытаскиваем GUID из выделенной строки представления и подставляем в URL второго iFrame'а
                    var frameDoc = document.getElementById("iframe_masterRecordsGrid").contentWindow.document;
                    var selectedRecord = frameDoc.all['crmGrid'].InnerGrid.SelectedRecords[0][0];
                    document.getElementById("DetailArea").src = recordBaseURL + selectedRecord;
                }
            </script>
            <style type="text/css">
                HTML, BODY 
                {
            	    margin: 0;
            	    padding: 0;
            	    background-color: #b4d4ff;
                }
                #d1
                {
                	float: left;
                	width: 40%;
                	padding: 2px;
                	padding-top: 0;
                	padding-bottom: 0;
                	width: 100%;
                }
                #d2
                {
                	float: left;
                	width: 60%;
                    padding: 0;
                    padding-right: 2px;
                    width: 100%;
                }
                #DetailArea 
                {
                	border: 1px solid #6699cc;
                }
            </style>
        </head>
        <body onload="initIframes()" onresize="OnResizeComplete();">
            <div id="d1">
                <iframe id="iframe_masterRecordsGrid" src="MasterView.htm" scrolling="no"></iframe>
            </div>
            <div id="d2">
                <iframe id="DetailArea"></iframe>
            </div>
        </body>
    </html>
    

    Тут код немного посложнее:

    • Страница разбита на два вертикальных iFrame’а. В первый загружена страница MasterView.htm. А во второй будет динамически подтягиваться страница редактирования записи бизнес-партнера, которого пользователь выделил в представлении в первом iFrame’е (это представление вернул Расширенный поиск);
    • В самом начале JS-кода определена функция которая растягивает высоту iFrame’ов в соответствии с высотой окноа браузера (т.е. заполняет доступное пространство);
    • Задаем базовый путь для ASPX-сраницы (стандартной), в которой происходит редактирование нужной нам карточки (в данном случае это Бизнес-партнеры);
    • При загрузке первого iFrame’а присоединяем к событию выделения записей в его представлении функцию, котора «смотрит» выделенную запись, вытаскивает из нее GUID и на сонове него формирует URL для второго iFrame’а. Т.е. фактически передает в него страницу редактирования Бизнес-партнеров и GUID записи, которую нужно редактировать 🙂
  • Экспортируйте SiteMap из CRM и добавьте в него (в группу Customers, например, или куда Вам нужно) следующую строчку:
    <SubArea Id="doubleview" Url="/../ISV/doubleview/MasterDetailView.htm" Icon="/../ISV/doubleview/account2.gif" Title="Бизнес-партнеры II" />
    

    Тут просто добавляется ссылка на страницу MasterDetailView.htm;

  • Экспортируйте SiteMap обратно в CRM и смотрите на новую страничку 🙂




З.Ы. Готовая папка doubleview 🙂

Комментарии (16)
  • Азат 23.09.2010

    Не совсем в топик, но все же…

    пользуемся CRM’ом через IE 9, причем в связи с характером работы у каждого юзера в течение дня в IE открыто одновременно несколько вкладок (например Контакты, Действия, Отчеты, …).
    Каждую вкладку в IE CRM подписывает незамысловатым «Microsoft Dynamics CRM» — поэтому возникает путаница: в какой вкладке контакты, в какой действия, в какой отчеты и т.п. — не понятно 🙁
    [img]http://imagepost.ru/images/f/uo/fuomfusvctpwyclujibmispksyvvsw.gif[/img]

    Нужно сделать, чтобы CRM писал во вкладке название объекта, выбранного в navbar’e
    [img]http://imagepost.ru/images/p/zl/pzldijecrqqqvpfvggglcxeccgibdl.gif[/img]

  • slivka_83 23.09.2010
  • Азат 23.09.2010

    Пробовали.
    Вот: http://imagepost.ru/images/3/fw/3fw.gif
    В заголовке окна действительно вместо URL-адреса — имя записи 🙂
    Однако в названиях вкладок Internet Explorer’а — все тот же «Microsoft Dynamics CRM» 🙁

  • slivka_83 23.09.2010

    Посмотрел у себя… у меня тоже 9 ослик. И на вкладках пищется «Контакт: ФИО», «Организация: < название организации>» и т.д.
    http://imagepost.ru/images/2/01/2011-09-19_022645.png

  • Азат 23.09.2010

    О, Круто! Именно это нам и надо :)))
    Только у Вас CRM 2011, а у нас 4.0
    Может быть дело в версиях?
    Тогда другой вопрос: как реализовать это в CRM 4.0

    А то переходить на 2011 ради этой фичи не очень хочется 🙁

  • slivka_83 23.09.2010

    Ну, то что отображается на вкладке прописывается в теге title. И если это не раелизовано стандартными средствами, то единственный вариант, который я вижу — писать http-модуль, который перед отсправкой страницы пользователю будет изменять тег title. но это довольно трудоемко…

  • Sergey 23.09.2010

    А если в этой форме Бизнес партнера надо скрыть левую навигационную панель, как тут быть? При этом в стандартной карточке Бизнес партнера она должна остаться.
    Может на ОнЛоад Формы партнера повесить какой-то скрипт который будет отлавливать, как именно она отстраивается а отсюда передавать этот параметр? Посоветуйте что-то, заранее спасибо

  • slivka_83 23.09.2010

    Что такое «стандартная карточка бизнес-партнера» и соответственно что такое не стндартная и что такое «отстраивается»?

  • Sergey 23.09.2010

    Суть вопроса в том, как при двойном отображении скрыть левую навигационную панель в карточке бизнес партнера, которая отображается в правом фрейме?

  • slivka_83 23.09.2010

    Ну да, обработчик можно повесить и на онлоад формы и на загрузку страницы MasterDetailView.htm. С помощью DevTollBar’a найти ID левой навигационно поннели и в коде повесить ее скрытие.

  • Sergey 23.09.2010

    Попробую. Хотя, в идеале вырезать кусок ДОМ структуры, и не строить левую панель, чтобы ускорить загрузку содержимого MasterDetailView.htm. Т.е. сразу в этот фрейм строить страницу без левой панели. А вот это я не знаю как сделать. Спасибо

  • Sergey 23.09.2010

    Прошарился по форумам. Оказывается нельзя загрузить карточку Бизнес партнера или любого другого объекта сразу выкусив левую панель. А ее надо облегчить, может узлы этой панели для этого повыкусывать, а потом уже ее прятать? Кто-то пробовал?

  • slivka_83 23.09.2010

    Мне такого делать вроде не приходилось…

  • Борис 23.09.2010

    Сделал всё по инструкции…не получается. Код весь прошёл вдоль ипоперёк..разобрал каждую запятую…всё должно работать. Хелп плиз…

    Симптомы следующие:

    После загрузки схемы. Открываю ссылку.
    Форма загружает в левый фрейм список бизнес-партнеров….. при этом первый пункт сразу выделен..соответственно через секунду в нём же открывает его детальную карту…Правый фрейм который должен генерироваться динамически и отображаться во фрейме DetailArea вообще не работает…т.е ощущение что его и вовсе нет. Проверил hmtl загруженной страницы…

    присутствует…но всё-равно ноль отображения.
    Скрины тут:
    msk-mb_ru/scrin1.jpg
    msk-mb_ru/scrin2.jpg

  • Борис 23.09.2010

    Сглупил…всё дело было в css. Код:
    #d1
    {
    float: left;
    width: 30%;
    padding: 1px;
    padding-top: 0;
    padding-bottom: 0;
    overflow:hidden;
    }
    #d2
    {
    float: left;
    width: 70%;
    padding: 0;
    padding-right: 2px;

    }
    #DetailArea
    {
    border: 1px solid #6699cc;
    width: 100%;
    }

    всё исправил ) Версия IE: 9.0.8 всё работает )

    Спасибо за скрипт!! ))

*

code