Добро пожаловать в мой блог! Изначально он не задумывался как блог CRM разработчика, но жизнь сама внесла нужные коррективы. Тут я публикою все свои наблюдения относительно обозначенных в заголовке систем. Если Вы найдете в нем что-то интересное для Вас, как для заказчика, то буду рад сотрудничать с Вами! В моей компетенции 100% задач по MS CRM 3.0/4.0/2011:
MVP 2010, 2011
- Консалтинг
- Проектирование
- Разработка
- Обучение
MVP 2010, 2011
Пользовательские контролы с Присутствием в SharePoint
Запись от Артем Enot Грунин размещена 08.10.2009 в 14:29
Теги .net, java script, precence, webpart
Однажды я уже касался индикаторов присутствия на страницах своего блога. Если в CRM они редкость и роскошь, то SharePoint ими буквально напичкан - они по умолчанию есть в списках, на сылках и подписях, словом на всем что указывает на профиль пользователя. На всем, кроме пользовательских типов контролов... В этом есть нечто общее с CRM - нет открытого для разработчика интерфейса для реализации подобной ф-ции. В SDK на слово Precence отзывается одна единственная полезная страница NameCtrl Control, которая поможет скорее с выбором направления поисков, нежели в реализации данного функционала. Решение, тем нее менее удалось найти. Как и в CRM присутствие реализует JS код, хранимый не в файле OWS.js, как это говорит в SDK, а в init.js, который лежит в том же каталоге (может помочь при отладке). Нас в первую очередь интересуют две функции:
EnsureIMNControl, инициирующая цепь событий, которые вдохнут жизнь в наш дохлый контрол, и IMNGetOOUILocation которая определит позицию индикатора. Реализация последней особенно интересна:
Вот так она будет осуществлять поиск положения индикатора. Иными словами, контрол должен быть завернут в HTML элемент SPAN или TABLE и быть либо анкером, либо картинкой. После недолгих мучений мне удалось реализовать данное требование. Ваш код на C# мог бы выглядеть следующим образом:
В данной реализации индикатор будет "натравлен" на пустую картинку перед ссылкой на профиль пользователя. Обратите внимание на тег <UserEmail>: каждый идикатор должен знать SIP адрес пользователя на которого ссылается, или на худой конец его E-Mail, которые чаще всего совпадают. Оба эти атрибута доступны через профиль пользователя, например так:
EnsureIMNControl, инициирующая цепь событий, которые вдохнут жизнь в наш дохлый контрол, и IMNGetOOUILocation которая определит позицию индикатора. Реализация последней особенно интересна:
Код:
var objRet=new Object; var objSpan=obj; var objOOUI=obj; var oouiX=0, oouiY=0, objDX=0; var fRtl=document.dir=="rtl"; while (objSpan && objSpan.tagName !="SPAN" && objSpan.tagName !="TABLE") { objSpan=objSpan.parentNode; } if (objSpan) { var collNodes=objSpan.tagName=="TABLE" ? objSpan.rows(0).cells(0).childNodes : objSpan.childNodes; var i; for (i=0; i < collNodes.length;++i) { if (collNodes.item(i).tagName=="IMG" && collNodes.item(i).id) { objOOUI=collNodes.item(i); break; } if (collNodes.item(i).tagName=="A" && collNodes.item(i).childNodes.length > 0 && collNodes.item(i).childNodes.item(0).tagName=="IMG" && collNodes.item(i).childNodes.item(0).id) { objOOUI=collNodes.item(i).childNodes.item(0); break; } } } * * *
Код:
HtmlGenericControl lineString; HtmlImage indicator = new HtmlImage(); indicator.ID = "imid_" + i; indicator.Src = "/_layouts/images/imnhdr.gif"; indicator.Attributes.Add("onload", "IMNRC('" + <UserEmail> + "')"); indicator.Attributes.Add("ShowOfflinePawn", "1"); indicator.Attributes.CssStyle.Add(HtmlTextWriterStyle.MarginRight, "2px"); // Оборачиваем индикатор в SPAN (нужно чтобы корректно привязались обработчики событий) HtmlGenericControl indSpan = new HtmlGenericControl("SPAN"); indSpan.Controls.Add(indicator); // Ссылка на пользователя HtmlAnchor link = new HtmlAnchor(); link.InnerHtml = <UserName>; link.HRef = <MySiteUri>; link.Attributes.CssStyle.Add(HtmlTextWriterStyle.MarginRight, "15px"); lineString.Controls.Add(indSpan); lineString.Controls.Add(link);
Код:
UserProfileManager profileManager = new UserProfileManager(ServerContext.Current); UserProfile profile = profileManager.GetUserProfile(@"domen\user"); String email = (String)profile[PropertyConstants.WorkEmail].Value; String sip = (String)profile[PropertyConstants.SipAddress].Value;
Всего комментариев 0