Страницы с тегами : js, javascript

7 способов улучшить поля в формах SharePoint 2013

Кастомизация форм – очень больная тема в SharePoint. InfoPath фактически умер, новые способы кастомизации появятся не раньше следующего релиза (назначенного на конец 2015 года), а для использования SPServices нужен jQuery старой версии, что само по себе несет проблемы, так еще и требует знания отображаемых имен полей, что делает решение ненадежным. Подробнее в моем курсе по клиентской разработке SharePoint.

Создавая TypeScript-определения для клиентской библиотеки SharePoint  сделал несколько примеров полей. Недавно я провел большой рефакторинг и выделил кастомные поля в отдельные, повторно используемые функции.

Все функции содержатся в файле typescripttemplaes.ts. Тем, кто не пользуется TypeScript (зря!), можно скачать .js файл в том же каталоге.

Как пользоваться typescripttemplates:

  1. Скачать файл и добавить .js в проект
  2. Сделать свой файл скрипта для полей, такого вида:
    module _ {
        function init() {
            CSR.override()
                .lookupAddNew("Master", "Add New Master item", true)
                .register();        
        }
    
    
                    
                


Загрузка скриптов в SharePoint

В прошедшем недавно семинаре про клиентской разработке в SharePoint (записи – по ссылке) я показывал как сделать клиентский скрипт, который выполняет некоторый код после окончания загрузки страницы в SharePoint.

Эта, казалось бы, простая задача далеко не тривиально реализуется в SharePoint.

Причины

    1. SharePoint формирует интерфейс динамически. Многие блоки добавляются на страницу по событию body.onload. Это событие возникает позже, чем DOMContentLoaded. Именно это событие перехватывает jQuery.ready. Поэтому использование jQuery часто не приводит к хорошему результату. Подробнее об использовании jQuery в SharePoint.
    2. Minimal Download Strategy (MDS), появившийся в SharePoint 2013, загружает страницу один раз, потом обновляет блоки страницы, поэтому нужно выполнять дополнительные действия, чтобы скрипт выполнился после загрузки страницы под MDS.
    3. Механизм загрузки скриптов, о котором я писал ранее, требует чтобы скрипт самостоятельно оповещал об окончании выполнения.

Для скриптов в виртуальной файловой системе SharePoint

Чаще всего скрипты SharePoint деплоятся как файлы в виртуальной файловой системе. Это прекрасно работает как в on premises, так и в online.

Для размещения скриптов на странице используется контрол ScriptLink, в таком виде:

<SharePoint:ScriptLink Name="autofill.js" runat="server" OnDemand="true" LoadAfterUI="true" Localizable="false" />

или с помощью CustomAction ScriptLink в элементе решения

<CustomAction Location="ScriptLink" ScriptSrc="~site/Extensions/typescripttemplates.js" />

Внутри скрипта нужно выполнить следующие действия:

  1. Оповестить SharePoint об окончании загрузки.
  2. Добавить функцию, которую необходимо вызывать после загрузки страницы, в массив _spBodyOnLoadFunctions.
  3. Добавить зарегистрировать скрипт в системе MDS.

Код:

// IIFE для изоляции
(function () {
    "use strict";


                
                
                
                
            


10 вещей, которые надо знать при использовании jQuery в SharePoint

Для чего нужен jQuery в SharePoint? Обычно его используют для четырех целей:

  • Вызывать код JavaScript в момент загрузки страницы с помощью $(document).ready.
  • Использовать Ajax функции для доступа к данным на сервере.
  • Использовать готовые плагины,такие как tooltip или tabs, для того, чтобы расширить функционал сайта.
  • Проводить некоторые манипуляции с объектной модели документа (DOM).

Если Вы собираетесь использовать jQuery на страницах SharePoint, то вам нужно знать следующие вещи:  

 

1. Используйте mQuery и RequestExecutor в простых случаях

Если у вас простой случай, то Вы можете использовать библиотеку mQuery для манипуляции DOM и RequestExecutor для ajax запросов. Кроме того, вместо Ajax запросов гораздо выгоднее использовать JSOM и TypeScript для клиентской разработки. Об этом я писал ранее.

Если Вы, все таки, решили использовать jQuery, то вам нужно помнить следующее:

2. jQuery(document).ready срабатывает не вовремя

Это происходит потому, что $(document).ready взрывается при событии DOMContentLoaded. А это события создано для тех случаев, когда весь контент страницы загружается с сервера. Оно происходит после того как браузер скачал всю страницу, связанные файлы и всё распарсил. SharePoint использует механизмы динамического формирования страницы, когда скрипты в теле страницы запускаются и формируют части страницы. В этом случае использовать DOMContentLoaded, отрабатывает до того как сформирована страница. Гораздо более надежный способ вызова после загрузки страницы – с помощью события body.onload. Для этого в SharePoint есть готовые функции.

 

3. Используйте _spBodyOnLoadFunctions или _spBodyOnLoadFunctionNames

Эти два массива (да-да, обычные JS массивы). _spBodyOnLoadFunctionNames содержит имена глобальных функций, которые необходимо вызвать на событие body.onload. _spBodyOnLoadFunctions содержит объекты-функции, что гораздо удобнее, но доступно только в SharePoint 2013. Кроме того есть переменная _spBodyOnLoadCalled, которая равна true, если функции уже были выполнены.

Пример:

(function() {
    if (!_spBodyOnLoadCalled) {
        _spBodyOnLoadFunctions.push(pageLoad);
    } else {
        pageLoad();
    }


                
            


Обновление SPTypeScript

Вчера была опубликовано обновление для SharePoint TypeScript Definitions. Новую версию определений можно получить через NuGet:

http://www.nuget.org/packages/sharepoint.TypeScript.DefinitelyTyped/

Или командой в Package Manager

PM> Install-Package sharepoint.TypeScript.DefinitelyTyped

Что нового

Анимация

В SharePoint 2013 добавили анимацию и, как всегда забыли, выложить документацию по этому делу. Я раскопал как работает анимация. К сожалению возможности библиотеки очень ограничены. Анимация работает для следующих атрибутов элементов:

  • Позиция (x,y)
  • Размеры (ширина, высота)
  • Прозрачность

Есть два способа вызвать анимацию.

Простой:

SPAnimationUtility.BasicAnimator.FadeOut(element); 
SPAnimationUtility.BasicAnimator.FadeIn(element);
SPAnimationUtility.BasicAnimator.Resize(element, width, height);
SPAnimationUtility.BasicAnimator.Move(element, x, y);

И чуть более сложный:

var state = new SPAnimation.State();
state.SetAttribute(SPAnimation.Attribute.Opacity, 0.2);
var animation = new SPAnimation.Object(
                        SPAnimation.ID.Basic_Opacity, 
                        500,  /*duration*/
                        element, 
                        state);


                
            


SharePoint Script On Demand

В SharePoint 2013 довольно богатая клиентская библиотека. Ранее я уже писал об аналоге jQuery и об Ajax библиотеках. Одна из важнейших частей для разработки масштабного JavaScipt приложения – загрузчик скриптов. Такое тоже есть в SharePoint.

Почему необходимо управлять загрузкой скриптов

Исторически управление загрузкой скриптов появилось для увеличения быстродействия. Вы наверное знаете, что тег script в теле страницы заставляет браузер останавливать отрисовку страницы. Поэтому скрипты надо загружать как можно позже. Кроме того, в сложных приложениях, все скрипты не нужны на каждой странице, поэтому выгодно загружать их по требованию.

Но важнейшая задача управления загрузкой скриптов – создание полноценной модульности для javascript. Ведь сам язык не предоставляет инструмента описания связей между модулями и гарантий, что зависимости будут загружены до выполнения скрипта.

Обе причины особенно важны в SharePoint. Страницы SharePoint тяжелые, и лучше загружать скрипты как можно позже. Сами же страницы строятся из кучи независимых компонент (созданных разными разработчиками), поэтому модульность скриптов важна как нигде.

В мире веб-разработки фактически стандарт для управляемой загрузки скриптов – библиотека requirejs. Но в ней есть критический недостаток, её придумал не Microsoft, поэтому в SharePoint своя библиотек для загрузки скриптов. Называется она Script On Demand.

Script On Demand

Вся библиотека содержится в классе SP.SOD в файле init.js. Script On Demand спроектирован как неинтрузивная библиотека, в отличие от requirejs, то есть скрипты будут работать и без нее. Это важно в App Parts, которые по сути отдельные страницы в iframe. Там нет смысла откладывать загрузку скриптов.

Документация по SP.SOD есть на MSDN, но она там, мягко говоря, ужасная. В проекте SPTypeScript есть качественные определения типов для SP.SOD, они будут более полезны (SP.Init.d.ts).

Добавление скриптов на страницу

Есть серверный контрол ScriptLink, который позволяет указать в разметке aspx страницы скрипт. По умолчанию скрит будет загружаться сразу же, но асинхронно, то есть не будет блокировать рисование страницы.

У контрола ScriptLink несколько атрибутов:

  • Name – указывает имя скрипта. Если указать только имя файла, то скрипт будет загружаться из _layouts. Поддерживаются url tokens, такие как ~site и ~sitecollection.
  • Localizable – если стоит значение true и указано только имя скрипта, то скрипт будет за загружаться из _layouts/{langId}.
  • LoadAfterUI – если стоит значение true, скрипт будет добавлен в конец страницы (независимо от местоположения контрола ScriptLink) и загрузка начнется после рисования всего интерфейса.
  • OnDemand – если указано значение false или атрибут отсутствует, то генерируется такая разметка:
    <script type="text/javascript">
    // <![CDATA[
    document.write(
        '<script type="text/javascript" src="script.js"></' 
        + 'script>');
    // ]]>
    </script>
    
    
                    
                


Связанные элементы в SharePoint 2013

Вам наверное часто в решениях требовалось сделать возможность связать один элемент с другим. Причем не просто лукап сделать, а так чтобы можно было произвольно выбрать элемент и создать связь с ним.

Копая JSOM, я недавно обнаружил, что в SharePoint 2013 есть такой функционал.

“Изкаропки” он доступен в списке задач. У каждой задачи есть “связанные элементы”.

image

При нажатии на “добавить связанный элемент” появляется стандартный asset picker

image

Можно выбирать любой элемент в пределах коллекции сайтов.

Внутренности “связанных элементов”

“Связанные элементы” это кастомное поле с ID равным значению Microsoft.SharePoint.SPBuiltInFieldId.RelatedItems. Это поле скрытое и добавить его в список из интерфейса не получится. Но в решении вы совершенно спокойно можете добавить это поле в тип контента.

Сам касс поля определен в сборке Microsoft.SharePoint и доступен, в том числе, в Foundation. Для работы с полем доступны только клиентские API, серверный класс для них помечен как internal.

На клиенте можно обращаться с помощью классов SP.RelatedItemManager в sp.js (http://msdn.microsoft.com/en-us/library/jj838582.aspx) и Microsoft.SharePoint.Client.RelatedItemManager в сборке Micrsosoft.SharePoint.Client (http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.client.relateditemmanager.aspx).

Если интересна реализация поля, то смотрите с помощью IlSpy класс Microsoft.SharePoint.RelatedItemManager в сборке Microsoft.SharePoint. Рендеринг поля описан в файле sp.ui.relateditems.js

Реализация поля предельно простая – в текстовом поле сохраняется сериализованный в json массив элементов Microsoft.SharePoint.RelatedItem. Есть ограничение – не более 9 связанных элементов. Скорее всего оно связано с необходимостью secutrity trimming ссылок на связанные элменты, а это делается крайне медленно в SharePoint. Для security trimming ссылок в ленте новостей используется поиск+кеширование, но функционал “связанных элементов” рассчитан на работу в foundation и не может использовать такие возможности.

Применение

Из-за ограничения количества связанных элементов использовать данную возможность для разработки большой системы не получится. Хотя во многих сценариях данное поле может заменить лукапы. Кроме того API позволит вычислять “транзитивное замыкание” связанных элементов.

Наибольший интерес “связанные элементы” представляют как пример качественно сделанного расширения платформы. Оно включает в себя Custom Field Type с контролом, API на сервере и на клиенте, рендеринг поля в формах и использование asset picker. Если будете делать что-то подобное, то изучите реализацию “связанных элементов”.



SharePoint и Ajax

Как вы думаете, сколько способов сделать ajax запрос в SharePoint? А без jQuery и дополнительных библиотек? Нет, XMLHttpRequest руками писать на надо.

Sys.Net.WebRequest \ Sys.Net.WebRequestExecutor

Эти классы находятся в библиотеке MicrosoftAjax. Она подгружается на каждой странице SharePoint и вы можете использовать её на своих страницах.

Класс Sys.Net.WebRequest описывает параметры запроса, а Sys.Net.WebRequestExecutor, вернее его наследник, выполняет запрос с указанными параметрами. Можно создавать свои реализации WebRequestExecutor, например для тестирования или для проксирования запросов.

Недостаток этих классов в чрезмерной многословности.

var request = new Sys.Net.WebRequest();         
request.set_url(url);
request.set_httpVerb("GET");         
request.add_completed(function(executor, eventArgs) {             
    if(executor. get_responseAvailable()) {
        //do stuff
    }
});


                
            


Автокомплит в SharePoint 2013: пошаговое руководство

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

Вы уже видели новый элемент управления для выбора людей в SharePoint 2013? Этот элемент управления был сильно улучшен по сравнению с предыдущей версией SharePoint. Теперь этот элемент можно использовать в клиентском коде и спокойно внедрять на своих страницах. Кроме того появился отличный функционал автозаполнения.

070713_0434_LeveragingS1[1]

Замечательная новость: вы можете использовать функционал автозаполнения с любым текстовым полем. Эту функцию реализует контрол  SPClientAutoFill. Он находится в файле autofill.js в _layouts/15. Давайте посмотрим как сделать решение с его помощью.

Шаг первый: разметка и стили

Для того чтобы использовать SPClientAutoFill вам потребуется следующая разметка:

<div style='position: relative;'>
    <input type='text' id='autofillElement' />
    <div class='sp-peoplepicker-autoFillContainer' 
            id='autofillContainer' />
</div>


                
            


SharePoint + Javascript + Visual Studio = Love

Для тех кто еще не знаком с клиентской объектной моделью SharePoint, настоятельно рекомендую ознакомиться с ней. Client OM доступна как в C# (.NET и Silverlight), так и в Javascript.

.NET разработчики обычно не любят javascript, считают его убогим языком, приводящим к куче ошибок. И они в чем-то правы… Основной причиной называют динамическую типизацию и интерпретируемость javascript. На самом деле разработчика нужна не типизация и компиляция, а проверка кода до запуска и подсказки по коду. Обе возможности доступны в Visual Studio с расширениями.

Проверка кода до запуска

Для этого в галерее расширений visual studio есть два расширения:

  1. JSLint – встроенный в VS инструмент проверки кода javascript, который можно найти по адресу http://www.jslint.com/
  2. Javascript parser – расширение, которое парсит js код на лету (читай показывает ошибки) и предоставляет навигацию по коду.

Эти два расширения позволяют отловить наиболее частые ошибки в коде.

image

Кроме того рекомендую установить jscript editor extensions чтобы редактор был больше похож на редактор кода C#.

Подсказки по коду aka Intellisence

Эта возможность доступна начиная с Visual Studio 2008, но о ней до сих пор знает катастрофически малая часть разработчиков.  Чтобы intellicence для js заработал в visual studio, необходимо visual studio дать подсказку откуда брать файлы.

Если вы пишите javascript код в html\aspx\ascx\materpage файлах, то vs автоматически подтягивает все .js файлы из тегов script и серверного контрола ScriptManager. Далее VS парсит файлы и пытается построить подсказку по коду. Если же нужно обновить подсказку, то можно нажать ctrl+shift+j.

Если же код пишется в .js файле, то файлы, которые надо анализировать для построения подсказки надо указать в специальном теге:

///<reference path="c:\scripts\jquery-1.5.1.js"/>


Решение задач. Задача таймера, совсем конец.

Посты в этой серии:

  1. Список задач для проверки навыков.
  2. Создание задачи таймера.
  3. Использование подходящих классов.
  4. Передача команд задаче таймера.
  5. Взаимодействие веб-фронтэнда с задачами таймера (этот пост).

В прошлом посте был показан способ создать worker, который будет получать сообщения от frontend и обрабатывать их.

Теперь необходимо придумать как оправлять эти сообщения. В 2010 есть почти универсальный способ для размещения функционала – Ribbon. Даже если у вас возникает непреодолимое желание сделать ссылку\кнопку\пункт меню в другом месте, то скорее всего для целей usability надо будет повторить его в ribbon.

Для того чтобы добавить кнопку в ribbon надо создать custom action, я для этого использую cks:dev. Руководство по расширению риббона можно найти как на MSDN, так и в блогах глубоко уважаемых людей (надеюсь меня не забанят за такое количество ссылок).

Мой код получился такой:

<CustomAction Id="CleanupLibraryButton"
              Title="Cleanup"
              RegistrationType="List"
              RegistrationId="101"
              Location="CommandUI.Ribbon">
  <CommandUIExtension>
    <CommandUIDefinitions>
      <CommandUIDefinition Location="Ribbon.Library.Settings.Controls._children">
        <Button Id="Ribbon.Library.Settings.Cleanup"
                Command="CleanupLibraryCommand"
                TemplateAlias="o2"
                LabelText="Cleanup"
                Sequence="100"
                Image16by16="/_layouts/images/warning16by16.gif"
                Image32by32="/_layouts/images/CRIT_32.GIF"                   
                />
      </CommandUIDefinition>
    </CommandUIDefinitions>
    <CommandUIHandlers>
      <CommandUIHandler Command="CleanupLibraryCommand" 
                        CommandAction="???"/>
    </CommandUIHandlers>
  </CommandUIExtension>
</CustomAction>


7 способов улучшить поля в формах SharePoint 2013

Кастомизация форм – очень больная тема в SharePoint. InfoPath фактически умер, новые способы кастомизации появятся не раньше следующего релиза (назначенного на конец 2015 года), а для использования SPServices нужен jQuery старой версии, что само по себе несет проблемы, так еще и требует знания отображаемых имен полей, что делает решение ненадежным. Подробнее в моем курсе по клиентской разработке SharePoint.

Создавая TypeScript-определения для клиентской библиотеки SharePoint  сделал несколько примеров полей. Недавно я провел большой рефакторинг и выделил кастомные поля в отдельные, повторно используемые функции.

Все функции содержатся в файле typescripttemplaes.ts. Тем, кто не пользуется TypeScript (зря!), можно скачать .js файл в том же каталоге.

Как пользоваться typescripttemplates:

  1. Скачать файл и добавить .js в проект
  2. Сделать свой файл скрипта для полей, такого вида:
    module _ {
        function init() {
            CSR.override()
                .lookupAddNew("Master", "Add New Master item", true)
                .register();        
        }
    
    
                    
                


Загрузка скриптов в SharePoint

В прошедшем недавно семинаре про клиентской разработке в SharePoint (записи – по ссылке) я показывал как сделать клиентский скрипт, который выполняет некоторый код после окончания загрузки страницы в SharePoint.

Эта, казалось бы, простая задача далеко не тривиально реализуется в SharePoint.

Причины

    1. SharePoint формирует интерфейс динамически. Многие блоки добавляются на страницу по событию body.onload. Это событие возникает позже, чем DOMContentLoaded. Именно это событие перехватывает jQuery.ready. Поэтому использование jQuery часто не приводит к хорошему результату. Подробнее об использовании jQuery в SharePoint.
    2. Minimal Download Strategy (MDS), появившийся в SharePoint 2013, загружает страницу один раз, потом обновляет блоки страницы, поэтому нужно выполнять дополнительные действия, чтобы скрипт выполнился после загрузки страницы под MDS.
    3. Механизм загрузки скриптов, о котором я писал ранее, требует чтобы скрипт самостоятельно оповещал об окончании выполнения.

Для скриптов в виртуальной файловой системе SharePoint

Чаще всего скрипты SharePoint деплоятся как файлы в виртуальной файловой системе. Это прекрасно работает как в on premises, так и в online.

Для размещения скриптов на странице используется контрол ScriptLink, в таком виде:

<SharePoint:ScriptLink Name="autofill.js" runat="server" OnDemand="true" LoadAfterUI="true" Localizable="false" />

или с помощью CustomAction ScriptLink в элементе решения

<CustomAction Location="ScriptLink" ScriptSrc="~site/Extensions/typescripttemplates.js" />

Внутри скрипта нужно выполнить следующие действия:

  1. Оповестить SharePoint об окончании загрузки.
  2. Добавить функцию, которую необходимо вызывать после загрузки страницы, в массив _spBodyOnLoadFunctions.
  3. Добавить зарегистрировать скрипт в системе MDS.

Код:

// IIFE для изоляции
(function () {
    "use strict";


                
                
                
                
            


10 вещей, которые надо знать при использовании jQuery в SharePoint

Для чего нужен jQuery в SharePoint? Обычно его используют для четырех целей:

  • Вызывать код JavaScript в момент загрузки страницы с помощью $(document).ready.
  • Использовать Ajax функции для доступа к данным на сервере.
  • Использовать готовые плагины,такие как tooltip или tabs, для того, чтобы расширить функционал сайта.
  • Проводить некоторые манипуляции с объектной модели документа (DOM).

Если Вы собираетесь использовать jQuery на страницах SharePoint, то вам нужно знать следующие вещи:  

 

1. Используйте mQuery и RequestExecutor в простых случаях

Если у вас простой случай, то Вы можете использовать библиотеку mQuery для манипуляции DOM и RequestExecutor для ajax запросов. Кроме того, вместо Ajax запросов гораздо выгоднее использовать JSOM и TypeScript для клиентской разработки. Об этом я писал ранее.

Если Вы, все таки, решили использовать jQuery, то вам нужно помнить следующее:

2. jQuery(document).ready срабатывает не вовремя

Это происходит потому, что $(document).ready взрывается при событии DOMContentLoaded. А это события создано для тех случаев, когда весь контент страницы загружается с сервера. Оно происходит после того как браузер скачал всю страницу, связанные файлы и всё распарсил. SharePoint использует механизмы динамического формирования страницы, когда скрипты в теле страницы запускаются и формируют части страницы. В этом случае использовать DOMContentLoaded, отрабатывает до того как сформирована страница. Гораздо более надежный способ вызова после загрузки страницы – с помощью события body.onload. Для этого в SharePoint есть готовые функции.

 

3. Используйте _spBodyOnLoadFunctions или _spBodyOnLoadFunctionNames

Эти два массива (да-да, обычные JS массивы). _spBodyOnLoadFunctionNames содержит имена глобальных функций, которые необходимо вызвать на событие body.onload. _spBodyOnLoadFunctions содержит объекты-функции, что гораздо удобнее, но доступно только в SharePoint 2013. Кроме того есть переменная _spBodyOnLoadCalled, которая равна true, если функции уже были выполнены.

Пример:

(function() {
    if (!_spBodyOnLoadCalled) {
        _spBodyOnLoadFunctions.push(pageLoad);
    } else {
        pageLoad();
    }


                
            


Поиск в приложениях SharePoint. Часть 3.

В SharePoint 2013 появился REST веб-сервис, который позволяет делать поисковые запросы из JavaScript. В SharePoint 2010 есть только search.asmx, который требует генерировать и парсить большой объём XML (в лучших традициях SharePoint).

Чтобы упростить жизнь разработчику клиентских компонентов я написал REST веб-сервис для SharePoint 2010.

Реализация

За основу взял метод, который описывал ранее - Javascript-enabled SharePoint WCF services.

Контракт у сервиса очень простой:

[ServiceContract]
public interface ISearch
{
    [OperationContract]
    [WebGet(BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
    Stream Query(string q, int top, int skip, string select, string orderBy, bool includeRefiners, string refiners);
}

Параметры вызова:

  • q – текст запроса (обязательно).
  • top – количество результатов.
  • skip – с какой позиции в выборке отдавать результаты.
  • select – через запятую названия managed properties в результатах.
  • orderBy – через запятую названия managed properties по которым сортировать результат, после имени можно указать desc для сортировки по убыванию.
  • includeRefinerstrue или false, возвращать результаты уточнений или нет.
  • refiners - через запятую названия managed properties для формирования уточнений.

Реализация:

public System.IO.Stream Query(string q, int top, int skip, string select, string orderBy,
                    bool includeRefiners, string r) 
{
    using (new SPMonitoredScope("Execute Query Method"))
    {
        var site = SPContext.Current.Site;
        var result = GetSearchResults(site, q, top, skip, select, orderBy, includeRefiners, r);
        return ToJson(result);
    }
}

Метод GetSearchResults довольно простой, он передает параметры запроса в объект KeywordQuery и получает результат.

private static ResultTableCollection GetSearchResults(SPSite site, string q, int top, int skip, string select, string orderBy, bool includeRefiners, string r)
{
    var query = new KeywordQuery(site);
    query.QueryText = q;
    query.StartRow = skip;
    if (top > 0)
    {
        query.RowLimit = top;
    }


                
            


SPTypeScript Release 1.3

TypeScript неумолимо приближается к релизу, недавно вышла версия 0.9.5.

Вместе с этим мы продолжаем развивать наши определения типов JavaScript Object Model в SharePoint, чтобы вам было комфортно писать клиентский код для решений и приложений SharePoint.

На сайте проекта http://sptypescript.codeplex.com/ опубликован новый релиз, в который вошли:

  • Определения для Chrome Control для apps.
  • Определения для SPClientPeoplePicker для создания кастомных форм с контролом выбора людей.
  • Полные определения типов для пространств имен SP.Publishing и SP.DocumentManagement из файлов sp.publishing.js и sp.documentManagement.js соответственно. Они вам очень пригодятся для ECM\WCM сценариев.
  • Reputation object model – для социальных приложений.
  • Множество примеров и мелкие улучшения существующих определений.

Ссылка на релиз - http://sptypescript.codeplex.com/releases/view/115896

Также последнюю версию определений можно получить с помощью NuGet -http://www.nuget.org/packages/sharepoint.TypeScript.DefinitelyTyped/

Как использовать TypeScript для приложений SharePoint

Для начала установите последнюю версию TypeScript (0.9.5).

Создаете новый App для SharePoint в VisualStudio 2013

image

Теперь самое неприятное – надо поправить .csproj файл, чтобы включить компиляцию TypeScript. Для этого надо:

  • В контекстном меню проекта нажать Unload Project
  • На выгруженном проекте нажать Edit
  • В самом конце, перед закрывающим тегом Project надо добавить одну строчку:

    <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.targets" />

  • На выгруженном проекте нажать Reload Project
  • Верить что к релизу не придется исполнять эти танцы с бубном...

После этого надо выставить настройки проекта в свойствах проекта
image

Далее переименовываете App.js в _App.js. Удалять не надо, он еще пригодится.

image

Добавляете App.ts файл

image

Добавляете дефинишены для SharePoint и JQuery с помощью NuGet

image

Копируете содержимое _App.js в App.ts и удаляете _App.js и сразу получаете типизацию в .ts файле. Можно также сделать небольшой рефакторинг в стандартном шаблоне, чтобы максимально использовать типизацию:

image

Последний штрих – скомпилировать проект и добавить сгенерированные App.js и App.js.map в решение.

image

Теперь можно запускать приложение и будет работать отладка в .ts файле

image

Планы на будущее

Сейчас дефинишенами покрыто почти все API для которого можно хоть как-то найти документацию. К релизу TypeScript 1.0 мы выпустим версию SPTypeScript 1.5 (или 2.0). Если есть какой-то API SharePoint, для которого вы хотите видеть дефинишены в нашем проекте, пишите на CodePlex в раздел Discussions - http://sptypescript.codeplex.com/discussions.

Будем рады любому фидбеку.



Материалы со встречи RuSUG 17.10.2013

Мой доклад про TypeScript  в SharePoint



Доклад Виталия Жукова про поиск:



Спасибо всем, кто пришел.



Обновление SharePoint app на TypeScript

В марте я писал про то, как разрабатывать приложения для SharePoint c помощью TypeScript. С тех пор прошло почти полгода, появились новые версии компилятора TypeScript (не совместимые со старыми) и улучшились описания типов для SharePoint (http://sptypescript.codeplex.com). Настало время обновить пример.

Пример приложения

Приложение позволяет фиксировать часы на рабочем месте.

image

Приложение ведет список всех временных интервалов, зафиксированных нажатием кнопок check-in\check-out. Пользователю отображается сумма всех его часов.

Также есть app part с тем же функционалом, но доступный для размещения на любой странице сайта.

Скачать можно по ссылке - TimeTrackerApp v0.9

Подготовка

Для начала необходимо:

Для того чтобы при сборке проекта выполнялась компиляция  TypeScript необходимо добавить в .csproj файл следующие элементы:

<PropertyGroup>
    <TypeScriptTarget>ES3</TypeScriptTarget>
    <TypeScriptIncludeComments>true</TypeScriptIncludeComments>
    <TypeScriptSourceMap>true</TypeScriptSourceMap>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.targets" />

Библиотеки и определения

Прошлый раз я использовал библиотеки jQuery и knockoutjs с плагинами. В этот раз решил обойтись стандартными средствами SharePoint и небольшим хелпером из проекта sptypescript.

Чтобы все заработало необходимо добавить NuGet пакет sharepoint.TypeScript.DefinitelyTyped (http://www.nuget.org/packages/sharepoint.TypeScript.DefinitelyTyped/). Далее необходимо скопировать файл typescripttemplates.ts в проект, при необходимости поправить ссылку на sharepoint.d.ts.

Представление списка

Прошлый раз интерфейс был сделан на knockoutjs с асинхронной загрузкой данных. Это вызывало заметный лаг между отображением страницы и появлением интерфейса. Такое поведение очень сильно не нравилось и хотелось сделать лучше.

В новой версии интерфейс сделан на основе представления списка. Представление генерирует данные прямо в разметку страницы, и не требуется асинхронная загрузка. Кроме того, представление формирует разметку до рисования страницы. Для пользователя все выглядит, как-будто рисование происходит на сервере.

Для создания представления я воспользовался инструментами visual studio, но запрос пришлось вручную написать (незначимые детали убрал):

<View BaseViewID="2" Hidden="TRUE" >
  <ViewFields>
    <FieldRef Name="DurationInHours" />
    <FieldRef Name="ID" />
  </ViewFields>
  <Query>
    <Where>
      <Eq>
        <FieldRef Name="Author"/>
        <Value Type="Integer">
          <UserID/>
        </Value>
      </Eq>
    </Where>
  </Query> 
  <JSLink>~site/scripts/typescripttemplates.js|~site/scripts/view.js</JSLink>
</View>


                
            


Обновление SPTypeScript

Вчера была опубликовано обновление для SharePoint TypeScript Definitions. Новую версию определений можно получить через NuGet:

http://www.nuget.org/packages/sharepoint.TypeScript.DefinitelyTyped/

Или командой в Package Manager

PM> Install-Package sharepoint.TypeScript.DefinitelyTyped

Что нового

Анимация

В SharePoint 2013 добавили анимацию и, как всегда забыли, выложить документацию по этому делу. Я раскопал как работает анимация. К сожалению возможности библиотеки очень ограничены. Анимация работает для следующих атрибутов элементов:

  • Позиция (x,y)
  • Размеры (ширина, высота)
  • Прозрачность

Есть два способа вызвать анимацию.

Простой:

SPAnimationUtility.BasicAnimator.FadeOut(element); 
SPAnimationUtility.BasicAnimator.FadeIn(element);
SPAnimationUtility.BasicAnimator.Resize(element, width, height);
SPAnimationUtility.BasicAnimator.Move(element, x, y);

И чуть более сложный:

var state = new SPAnimation.State();
state.SetAttribute(SPAnimation.Attribute.Opacity, 0.2);
var animation = new SPAnimation.Object(
                        SPAnimation.ID.Basic_Opacity, 
                        500,  /*duration*/
                        element, 
                        state);


                
            


SharePoint Script On Demand

В SharePoint 2013 довольно богатая клиентская библиотека. Ранее я уже писал об аналоге jQuery и об Ajax библиотеках. Одна из важнейших частей для разработки масштабного JavaScipt приложения – загрузчик скриптов. Такое тоже есть в SharePoint.

Почему необходимо управлять загрузкой скриптов

Исторически управление загрузкой скриптов появилось для увеличения быстродействия. Вы наверное знаете, что тег script в теле страницы заставляет браузер останавливать отрисовку страницы. Поэтому скрипты надо загружать как можно позже. Кроме того, в сложных приложениях, все скрипты не нужны на каждой странице, поэтому выгодно загружать их по требованию.

Но важнейшая задача управления загрузкой скриптов – создание полноценной модульности для javascript. Ведь сам язык не предоставляет инструмента описания связей между модулями и гарантий, что зависимости будут загружены до выполнения скрипта.

Обе причины особенно важны в SharePoint. Страницы SharePoint тяжелые, и лучше загружать скрипты как можно позже. Сами же страницы строятся из кучи независимых компонент (созданных разными разработчиками), поэтому модульность скриптов важна как нигде.

В мире веб-разработки фактически стандарт для управляемой загрузки скриптов – библиотека requirejs. Но в ней есть критический недостаток, её придумал не Microsoft, поэтому в SharePoint своя библиотек для загрузки скриптов. Называется она Script On Demand.

Script On Demand

Вся библиотека содержится в классе SP.SOD в файле init.js. Script On Demand спроектирован как неинтрузивная библиотека, в отличие от requirejs, то есть скрипты будут работать и без нее. Это важно в App Parts, которые по сути отдельные страницы в iframe. Там нет смысла откладывать загрузку скриптов.

Документация по SP.SOD есть на MSDN, но она там, мягко говоря, ужасная. В проекте SPTypeScript есть качественные определения типов для SP.SOD, они будут более полезны (SP.Init.d.ts).

Добавление скриптов на страницу

Есть серверный контрол ScriptLink, который позволяет указать в разметке aspx страницы скрипт. По умолчанию скрит будет загружаться сразу же, но асинхронно, то есть не будет блокировать рисование страницы.

У контрола ScriptLink несколько атрибутов:

  • Name – указывает имя скрипта. Если указать только имя файла, то скрипт будет загружаться из _layouts. Поддерживаются url tokens, такие как ~site и ~sitecollection.
  • Localizable – если стоит значение true и указано только имя скрипта, то скрипт будет за загружаться из _layouts/{langId}.
  • LoadAfterUI – если стоит значение true, скрипт будет добавлен в конец страницы (независимо от местоположения контрола ScriptLink) и загрузка начнется после рисования всего интерфейса.
  • OnDemand – если указано значение false или атрибут отсутствует, то генерируется такая разметка:
    <script type="text/javascript">
    // <![CDATA[
    document.write(
        '<script type="text/javascript" src="script.js"></' 
        + 'script>');
    // ]]>
    </script>
    
    
                    
                


SharePoint и Ajax

Как вы думаете, сколько способов сделать ajax запрос в SharePoint? А без jQuery и дополнительных библиотек? Нет, XMLHttpRequest руками писать на надо.

Sys.Net.WebRequest \ Sys.Net.WebRequestExecutor

Эти классы находятся в библиотеке MicrosoftAjax. Она подгружается на каждой странице SharePoint и вы можете использовать её на своих страницах.

Класс Sys.Net.WebRequest описывает параметры запроса, а Sys.Net.WebRequestExecutor, вернее его наследник, выполняет запрос с указанными параметрами. Можно создавать свои реализации WebRequestExecutor, например для тестирования или для проксирования запросов.

Недостаток этих классов в чрезмерной многословности.

var request = new Sys.Net.WebRequest();         
request.set_url(url);
request.set_httpVerb("GET");         
request.add_completed(function(executor, eventArgs) {             
    if(executor. get_responseAvailable()) {
        //do stuff
    }
});


                
            


Почему вам стоит использовать TypeScript

Если вы еще не в курсе: JavaScript победил. На сегодняшний день это самый кроссплатформенный язык, доступный для любых устройств. На нем можно создавать веб-приложения (клиент и сервер), в том числе с оффлайн-режимом работы, десктопные приложения (для Windows 8), приложения для смартфонов и планшетов (PhoneGap), расширения для Microsoft Office, SharePoint и Dynamics. Код на JavaScript работает в СУБД, таких как MongoDB и даже Hadoop в Windows Azure (BigData однако).

На Javascript уже написаны Doom и эмулятор Linux. Фактически решая любую задачу, кроме написания модуля ядра ОС, вы встретитесь с JavaScript. Если вы еще не знаете JavaScript, то вам следует срочно начать его изучать.

У JavaScript  много недостатков

Многие разработчики испытывают такую реакцию на JavaScript:

image

(картинка взята отсюда)

Большую часть людей пугает отсутствие intellisense при наборе кода и манипуляции с HTML\CSS. Но это не самые большие проблемы.

Самая большая проблема JavaScript в том, что его придумал не Microsoft.

Основные недостатки JavaScript:

  • Динамическая типизация, которая вызывает множество регрессионных ошибок.
  • Отсутствие модульности. Нет ни модулей, ни классов, прототипное ООП рвет мозг тем, кто пишет на C++\Java\C#.
  • Неочевидное поведение во многих местах.

Для того чтобы не писать JavaScript были созданы компиляторы Java –> JavaScript, C# –> JavaScript, LLVM –> JavaScript. Но все это приводит к тому, что на программу на исходном языке накладываются существенные ограничения, а также существующие библиотеки для JavaScript не используются.

TypeScript исправляет часть недостатков

Microsoft, посмотрев на эту картину, решил что нужен язык, который с одной стороны исправляет проблемы, с другой стороны максимально близок к JavaScript, чтобы использовать существующие наработки.

Так и появился язык TypeScript (ссылка на оффсайт). TypeScript является надмножеством JavaScript. То есть любой корректный код на JavaScript также является корректным кодом на TypeScript.

TypeScript использует статическую типизацию, то есть все типы проверяются при компиляции. Кстати сам компилятор TypeScript написан на TypeScript и является open source (ссылка на репозитарий).

TypeScript добавляет возможность объявлять модули, классы и интерфейсы. Это позволяет масштабировать разработку сложных JavaScript приложений.

На выходе получается обычный JavaScript, который не требует дополнительных библиотек или специальных компонентов.

TypeScript в действии

При наборе кода в VisualStudio доступна богатая подсказка:

tsintellisence

Поддерживаются классы, аннотации и вывод типов, работает интерактивная отладка.

С легкостью можно использовать в TypeScript внешние библиотеки, например jquery:

image

При несовпадении типов компилятор ругается:

image

Компиляция TypeScript  происходит при сборке проекта, проверяя многие ошибки без запуска.

Ну и самая главная фича, от вида которой я чуть не расплакался:

image

Кто еще не до конца вдохновился может глянуть на raytracer на TypeScript, результат работы.

Как начать использовать TypeScript

Если вы используете VisualStudio, то вам необходимо поставить два расширения:

Тогда у вас появится вот такой режим редактирования:

Слева код на TypeScript, справа результат компиляции на JavaScript. Таким образом использование TypeScript поможет вам лучше понять и изучить JavaScript.

Тем, кто не использует visual studio, повезло чуть меньше. На сегодня доступны плагины для распространенных текстовых редакторов, а также инструменты командной строки.

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

Множество определений типов для популярных библиотек можно найти в проекте DefinitelyTyped. Судя по нику автора проекта это наш соотечественник.

Заключение

Это была вводная статья. В следующий раз больше примеров и реальное применение TypeScript.



Javascript-enabled SharePoint WCF services

К сожалению очень мало толковой информации о том, как создать WCF веб-сервис для SharePoint, который будет доступен как для WS-* клиентов, так и для Javascript.

Да-да, я знаю что уже вышел SharePoint 2013 и .NET 4.5, то что WCF уже не модно, и надо юзать WebAPI и REST. НО не факт что можно будет расширять API для SharePoint 2013, а WebAPI в SharePoint 2013 не работает (или по крайней мере это еще никто не сделал).

Так что пока используем WCF, благо его возможностей более чем достаточно для решения задачи.

Для начала надо поставить расширение студии CKS Dev (правильно говорить “секасдев”, @amarkeev гарантирует это), в нем есть шаблон для WCF сервиса

image

Этот пункт создает веб-сервис с BasicHttpBinding.

В SharePoint не обязательно параметры указывать в web.config, достаточно указать Factory в .svc файле, что и делает данный шаблон.

Какие есть Factory и зачем они нужны можно узнать по ссылке.

В принципе можно и этот сервис использовать в javascript коде, но придется долго и мучительно генерировать и парсить XML для SOAP. Чего делать крайне не хочется.

Для того, чтобы работать с теплым ламповым JSON достаточно сделать несколько изменений.

  1. Скопировать .svc файл и поставить ему те же параметры развертывания, что у исходного сервиса. Я даю сервисам имя <servicename>.json.svc
  2. В новом файле .svc зменить MultipleBaseAddressBasicHttpBindingServiceHostFactory на MultipleBaseAddressWebServiceHostFactory
  3. В интерфейсе сервиса добавить атрибуты методам, например
    [ServiceContract]
    public interface ITestService
    {
        [OperationContract]
        [WebGet(BodyStyle = WebMessageBodyStyle.Bare, 
                RequestFormat = WebMessageFormat.Json, 
                ResponseFormat = WebMessageFormat.Json)]
        //[WebInvoke(Method="POST",
        //        BodyStyle = WebMessageBodyStyle.Bare,
        //        RequestFormat = WebMessageFormat.Json,
        //        ResponseFormat = WebMessageFormat.Json)]
        string HelloWorld();
    }

И все, код сервиса править не надо. Атрибуты WebGet и WebInvoke можно найти в сборке System.SeviceModel.Web.

Код для вызова сервиса (javascript):

var webServerRelativeUrl = _spPageContextInfo.webServerRelativeUrl != "/" 
                           ? _spPageContextInfo.webServerRelativeUrl 
                           : "";


                
            


SharePoint + Javascript + Visual Studio = Love

Для тех кто еще не знаком с клиентской объектной моделью SharePoint, настоятельно рекомендую ознакомиться с ней. Client OM доступна как в C# (.NET и Silverlight), так и в Javascript.

.NET разработчики обычно не любят javascript, считают его убогим языком, приводящим к куче ошибок. И они в чем-то правы… Основной причиной называют динамическую типизацию и интерпретируемость javascript. На самом деле разработчика нужна не типизация и компиляция, а проверка кода до запуска и подсказки по коду. Обе возможности доступны в Visual Studio с расширениями.

Проверка кода до запуска

Для этого в галерее расширений visual studio есть два расширения:

  1. JSLint – встроенный в VS инструмент проверки кода javascript, который можно найти по адресу http://www.jslint.com/
  2. Javascript parser – расширение, которое парсит js код на лету (читай показывает ошибки) и предоставляет навигацию по коду.

Эти два расширения позволяют отловить наиболее частые ошибки в коде.

image

Кроме того рекомендую установить jscript editor extensions чтобы редактор был больше похож на редактор кода C#.

Подсказки по коду aka Intellisence

Эта возможность доступна начиная с Visual Studio 2008, но о ней до сих пор знает катастрофически малая часть разработчиков.  Чтобы intellicence для js заработал в visual studio, необходимо visual studio дать подсказку откуда брать файлы.

Если вы пишите javascript код в html\aspx\ascx\materpage файлах, то vs автоматически подтягивает все .js файлы из тегов script и серверного контрола ScriptManager. Далее VS парсит файлы и пытается построить подсказку по коду. Если же нужно обновить подсказку, то можно нажать ctrl+shift+j.

Если же код пишется в .js файле, то файлы, которые надо анализировать для построения подсказки надо указать в специальном теге:

///<reference path="c:\scripts\jquery-1.5.1.js"/>