среда, 30 апреля 2014 г.

Спам фильтр Outlook.com

У меня возник вопрос и я его отправил в службу поддержки MVA.
Мне пришел ответ:


Письмо было помечено: Будьте осторожны. Этот отправитель не прошел нашу проверку и, возможно, является мошенником.Обратите внимание на отправителя. Домен microsoft.

вторник, 29 апреля 2014 г.

Отправить ссылку на элемент из рабочего процесса

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

Сформировать письмо и отправить пользователю ссылку:

К сожалению, если использовать способ как картинке выше, то мы получим следующую ссылку:
http://server/Lists/ListName/81_.000

Где 81 - это Id текущего элемента. Такая ссылка на элемент работать не будет.
Что бы создать рабочую ссылку нужно использовать встроенный в SharePoint Designer 2013 построитель строк и сформировать такое:
[%Контекст рабочего процесса:URL адрес текущего сайта %]/Lists/listname/Dispform.aspx?ID=[%Текущий элемент:ID%]




Для этого получаем URL текущего сайта:



И Id текущего элемента:


Теперь у нас есть рабочая ссылка на элемент.

Стоить отметить, что в приведенном примере мы указываем ссылку на форму просмотра.
У нас остается возможность формировать ссылку сразу на форму изменения элемента.


UPD:
Можно использовать контекст рабочего процесса и получить ссылку на документ:
Но при этом нельзя будет сформировать ссылку сразу на форму редактирования.
Создается ссылка на форму просмотра, чего почти всегда достаточно.




понедельник, 28 апреля 2014 г.

Как сменить отображаемое имя поля Id

Порой заказчик просит добавить поле, которое будет уникальным и увеличиваться на 1 для каждого нового элемента. Писать свой custom field type не имеет смысла, т.к. этим требованиям полностью удовлетворяет поле Id. Его же часто просят переименовать. Что невозможно.
Но заказчик требует что-то вроде этого:

Для того, что бы это реализовать необходимо создать ново поле с типом Integer(Целое) и добавить его в представление:


Потом создаем рабочий процесс списка, который после добавления присвоит значение поля 'Id' полю 'Номер':


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


Показать поле "Создан" на форме элемента

Некоторые поля, например 'Id' или 'Создано' ('Created') невозможно отображать изначально на формах. В SharePoint Designer они в списке столбцов не отображаются. Заказчик просит изобразить на форме примерно следующее:


Для этого необходимо создать новую форму и добавить в нужное Вам место следующий серверный элемент SharePoint:


В итоге у нас получится примерно следующее:
Не очень красиво, необходимо сменить формат даты. Что бы было еще и на нашем языке.
Для этого мы с Вами попробует библиотеку momentjs.com

Для этого ее надо скачать и подключить к странице. Что бы мы могли отобразить время на нашем языке - качать необходимо moment-with-langs.min.js
Теперь получаем дату в старом формате, меняем и вставляем обратно в страницу.
Что бы пользователь не видел сам процесс обработки - прячем контейнер со старой датой:

<tr>
    <td colspan="2">
        <h1>
            Заявка создана:
            <span id="DateCreationLabel" style="color:navy;display:none">
                <SharePoint:ListItemProperty Property="Created" ID="CreatedDateField" runat="server" />
            </span>
        </h1>
    </td>
</tr>

Над html выше - выполняем JS ниже:

var date = $('#DateCreationLabel').text();
    if (moment(date).isValid()) {
        moment.lang('ru');
        date = moment(date).format('LL');
        $('#DateCreationLabel').text(date);
    }
    $('#DateCreationLabel').show();
После выполнения кода видим следующее:
Вполне приемлемо.

Tabs in SharePoint form

Опишу краткий пример как добавить функционал jQuery UI к формам SharePoint на примере табов.
Каких то особых изменений при добавлении на обычную страницу не имеется.
Создайте новую форму просмотра.
Добавьте на нее html перед таблицей с полями:
<div id="tabs">
    <ul>
        <li><a href="#FieldGroup1">Поле 1 и 2</a></li>
        <li><a href="#FieldGroup2">Поле 3 и 4</a></li>    
    </ul>
    <div id="FieldGroup1"></div>     
    <div id="FieldGroup2"></div>
</div>

Потом сделайте ссылки на необходимые файлы В нашем случае это сама библиотека jQuery, библиотека jQuery UI и на CSS:
<script type="text/javascript" src="/ScriptLibrary/jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="/ScriptLibrary/jquery-ui-1.10.4.min.js"></script>
<link href="/ScriptLibrary/jquery-ui-1.10.4.min.css" rel="stylesheet">
<script type="text/javascript">
function myOnload(){
    $('#tabs').tabs();
}
_spBodyOnLoadFunctionNames.push("myOnload");
</script>

Как результат Вы увидите табы. Теперь необходимо в них добавить поля. Представим что в нашем списке 2 поля: Title; Title2. Добавьте в div c id="FieldGroup1" html:
<div id="FieldGroup1">
<table border="0" cellspacing="0" width="100%">    
 <tr>
  <td width="190px" valign="top" class="ms-formlabel">
   <H3 class="ms-standardheader">
    <nobr>Title<span class="ms-formvalidation"> *</span>
    </nobr>
   </H3>
  </td>
  <td width="400px" valign="top" class="ms-formbody">
   <SharePoint:FormField runat="server" id="ff1{$Pos}" ControlMode="New" FieldName="Title" __designer:bind="{ddwrt:DataBind('i',concat('ff1',$Pos),'Value','ValueChanged','ID',ddwrt:EscapeDelims(string(@ID)),'@Title')}"/>
   <SharePoint:FieldDescription runat="server" id="ff1description{$Pos}" FieldName="Title" ControlMode="New"/>
  </td>
 </tr>
</table>

а в div c id="FieldGroup2" html:
<div id="FieldGroup2">
<table border="0" cellspacing="0" width="100%">    
 <tr>
  <td width="190px" valign="top" class="ms-formlabel">
   <H3 class="ms-standardheader">
    <nobr>Title2<span class="ms-formvalidation"> *</span>
    </nobr>
   </H3>
  </td>
  <td width="400px" valign="top" class="ms-formbody">
   <SharePoint:FormField runat="server" id="ff1{$Pos}" ControlMode="New" FieldName="Title2" __designer:bind="{ddwrt:DataBind('i',concat('ff1',$Pos),'Value','ValueChanged','ID',ddwrt:EscapeDelims(string(@ID)),'@Title2')}"/>
   <SharePoint:FieldDescription runat="server" id="ff1description{$Pos}" FieldName="Title2" ControlMode="New"/>
  </td>
 </tr>
</table>

Для скриншотов я использовал вариант с 4 столбцами: Title,Title2,Title3,Title4.
Все нажатия кнопки "сохранить" все данные удачно попадают в список.

Должен Вас заранее предупредить, что Вам придется самим реализовать механизм, который будет подсвечивать вкладки, в которых имеются незаполненные, но обязательные к заполнению поля. В противном случае пользователь подумает что форма сломалась.

InfoPath умер. Редактирование форм. Замена и аналоги.

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

Как можно редактировать формы сейчас? Ниже перечислены основные способы:

  1. JavaScript
  2. Nintex Forms
  3. SPForm
  4. K2
Есть и менее популярные решения, например pistachio.

П. 2 разработан нашими соотечественниками.
Все платные, кроме п. 1, он же и самый трудоемкий.
При самостоятельном редактировании форм, используя JavaScript, помимо привычного jQuery есть крайне полезная библиотека SPServices.

Редактирование JS для SharePoint

JSOM становиться все популярнее. Разработчиков SharePoint все плотнее толкают в сторону клиентской разработки. Так же появился CSR и TypeScript c полезными дополнениями. И несмотря на явное сопротивление, я все же начинаю все активнее писать JavaScript код. Создав несколько решений используя JavaScript, вместо Custom field type, удалось получить небольшой опыт удачного использования окружения и инструментов. Главный вывод который я сделал - не использовать для редактирования JS кода SharePoint Designer 2013.
Необходимо делать ссылку на файл c JS кодом, а сам файл класть в библиотеку. Подключать по WebDav к проводнику. Включить версионность в библиотеке со скриптами. Дальше Вы можете редактировать код в Visual Studio или Webstorm:


Для JS рекомендую использовать webstorm. Он не много стоит.

SharePoint End User Viewer Tool

Порой возникает необходимость просмотра списка пользователей SharePoint и удаления некоторых пользователей. Рекомендую использовать SharePoint End User Viewer Tool.


Так как видно на скрине, можно посмотреть часть полей. Вся информация берется из hidden user list.
Как с ним работать с помощью Power Shell или С# можно узнать подробнее в этом посте.

SharePoint custom file uploader by JSOM & REST\oData

SharePoint имеет встроенную возможность прикреплять файлы к элементам списка.

Но нет возможности иметь 2 поля. Что бы логически разделять документы.
Такого столбца просто нет в списке.
Так же нет возможности задать библиотеку, куда складывать вложения.
Что бы просмотреть вложенные элементы, необходимо открыть элемент списка.
Решением может быть создание своего custom field type.
Использовать серверный код для реализации функционала. В таком случае ограничений почти нет.
Можно купить. Есть несколько предложений на рынке.
Я же кратко покажу как добавить такой функционал без серверного кода.
Решение должно иметь возможность явно указать библиотеку, куда складывать файлы.
Не блокировать интерфейс на время загрузки.
Иметь возможность загрузки файлов большого размера.
Решение должно сразу же отображать загруженный файл и предоставлять возможность его удаления.
Все должно быть без постбэков.
Все будет сделано на JavaScript.

Для начала создайте новую форму просмотра.
Это можно сделать в SharePoint Designer.
Имя папки для хранения файлов- "Documents".
Библиотека указывается в html элементе для загрузки файлов:
onchange="UploadFile('Documents', 'fileinputInit')"
Добавьте в нее html:
<tr> 
    <td width="190px" valign="top" class="ms-formlabel"> 
        <h3 class="ms-standardheader"> 
            <nobr>Документы по открытию</nobr> 
        </h3> 
    </td> 
    <td width="400px" valign="top" class="ms-formbody"> 
        <input style="margin-left:2px" type="button" id="browseButton" value="Добавить файл ..." onclick="fileinputInit.click()" />
        <input type='file' id='fileinputInit' onchange="UploadFile('Documents', 'fileinputInit')" style='position:absolute;visibility:hidden;' multiple="multiple" /> 
        <div id="attachedFilesInit"> 
            <h2 id="initAnchor"></h2> 
        </div> 
    </td>
</tr> 
Этот html надо вставить в таблицу полями формы.
Что бы поле загрузки располагалось после поле "Название", вставьте код выше после указанного ниже:
    <td width="190px" valign="top" class="ms-formlabel"> 
        <h3 class="ms-standardheader"> 
            <nobr> 
                Название<span class="ms-formvalidation"> *</span> 
            </nobr> 
        </h3> 
    </td> 
    <td width="400px" valign="top" class="ms-formbody"> 
        <SharePoint:FormField runat="server" id="ff1{$Pos}" ControlMode="New" FieldName="Title" __designer:bind="{ddwrt:DataBind('i',concat('ff1',$Pos),'Value','ValueChanged','ID',ddwrt:EscapeDelims(string(@ID)),'@Title')}" /> 
        <SharePoint:FieldDescription runat="server" id="ff1description{$Pos}" FieldName="Title" ControlMode="New" /> 
    </td> 
</tr>
 Потом добавить после:

Этот JS




Решение работает асинхронно.
Загрузки делалась именно с помощью REST, т.к. JSOM имеет ограничение файла на загрузку в 2 Mb.

В результате у Вас должно быть как на гиф ниже:

Решение есть куда дорабатывать.
Для начала отключить возможность сабмита формы, на время загрузки.
И индикатор загрузки в список файлов.



пятница, 18 апреля 2014 г.

SkyDrive, SkyDrive Pro, OneDrive, OneDrive for Business


У некоторых может возникнуть путаница с ПО для синхронизации с облачными сервисами по хранению данных от Microsoft. Особенно после переименования SkyDrive в OneDrive. 
Я решил составить маленькую таблицу с описанием. 


Старое название Новое название Применение
SkyDrive OneDrive Для использования частными лицами. Работает  с учётными записями Microsoft (Outlook.com, Hotmail.com, Live.com)
SkyDrive Pro OneDrive for Business Для организаций. Работает с Office 365 и On Premise


Так же могут на год осчастливить гигабайтами при покупке девайсов с ПО от Microsoft.  
Кстати, изначально Microsoft выделял для SkyDrive(OneDrive) 25 Gb, теперь только 7 Gb. 
При этом можно получить 3 GB если включить функцию отправки фото в SkyDrive на Вашем телефоне. И еще до 5 Gb за рекомендации друзьям. 

Всю остальную информацию Вы можете получить из официального блога.

среда, 16 апреля 2014 г.

Баг SharePoint Designer 2013

В связи с известиями о прекращении развития InfoPath и его отсутствии в новой версии SharePoint, а следовательно и невозможности миграции форм - было принято решение реализовать задачу с использованием JavaScript. Все делать исключительно на клиенте.

Изначально весь JS вставлял в стандартные формы списка.
Периодически весь JS код переставал работать.
Причиной было поведение SharePoint Designer 2013.
В код, который сбрасывал состояние элемента:

window.reset = function (e) {
   e.wrap('<form>').closest('form').get(0).reset();
   e.unwrap();
}


Дизайнер добавлял:
<head> 
<meta name="WebPartPageExpansion" content="full" /> 
</head> 
В итоге я получал:
window.reset = function (e) { 
    console.log("Начало выполнения функции 'window.reset"); 
    e.wrap('<head> 
    <meta name="WebPartPageExpansion" content="full" /> 
    </head> 
    <form>').closest('form').get(0).reset(); 
    e.unwrap(); 
}


Решить удалось подключая код отдельным файлом.
Как и должно быть.
   

вторник, 15 апреля 2014 г.