- PVSM.RU - https://www.pvsm.ru -
Данная заметка поможет решить например такие задачи как:
SharePoint предоставляет богатые возможности для разграничения прав доступа. Можно раздавать уникальные права на узлы, на списки внутри узлов, на элементы внутри списков. Но как бы хорошо не было всегда немного не хватает. Хорошо бы еще раздавать права на поля элементов списков — такой возможности “из коробки” не предусмотрено. Реализации этой хотелки и посвящена заметка.
Есть несколько вариантов раздать права на поля списка:
Все варианты (без дополнительных мер) не применимы для случаев, когда требуется высокий уровень секретности. Если поле не выводится на форме, пользователь может увидеть его в представлении списка или выгрузить список в Excel. Если у пользователя есть права на список он может получать/редактировать данные с помощью специальных утилит. Продвинутые товарищи могут редактировать элементы списков прямо в браузере — набирая несложные JS-команды в отладчике.
Шаблон по которому рисуются формы списков находится в файле DefaultTemplates.ascx (папка CONTROLTEMPLATES) и называется ListForm (Листинг 1).
<SharePoint:RenderingTemplate id="ListForm" runat="server">
<Template>
<span id='part1'>
<SharePoint:InformationBar runat="server"/>
<div id="listFormToolBarTop">
<wssuc:ToolBar CssClass="ms-formtoolbar" id="toolBarTbltop" RightButtonSeparator=" " runat="server">
<Template_RightButtons>
<SharePoint:NextPageButton runat="server"/>
<SharePoint:SaveButton runat="server"/>
<SharePoint:GoBackButton runat="server"/>
</Template_RightButtons>
</wssuc:ToolBar>
</div>
<SharePoint:FormToolBar runat="server"/>
<SharePoint:ItemValidationFailedMessage runat="server"/>
<table class="ms-formtable" style="margin-top: 8px;" border="0" cellpadding="0" cellspacing="0" width="100%">
<SharePoint:ChangeContentType runat="server"/>
<SharePoint:FolderFormFields runat="server"/>
<SharePoint:ListFieldIterator runat="server"/>
<SharePoint:ApprovalStatus runat="server"/>
<SharePoint:FormComponent TemplateName="AttachmentRows" runat="server"/>
</table>
<table cellpadding="0" cellspacing="0" width="100%"><tr><td class="ms-formline"><img src="/_layouts/images/blank.gif" width='1' height='1' alt="" /></td></tr></table>
<table cellpadding="0" cellspacing="0" width="100%" style="padding-top: 7px"><tr><td width="100%">
<SharePoint:ItemHiddenVersion runat="server"/>
<SharePoint:ParentInformationField runat="server"/>
<SharePoint:InitContentType runat="server"/>
<wssuc:ToolBar CssClass="ms-formtoolbar" id="toolBarTbl" RightButtonSeparator=" " runat="server">
<Template_Buttons>
<SharePoint:CreatedModifiedInfo runat="server"/>
</Template_Buttons>
<Template_RightButtons>
<SharePoint:SaveButton runat="server"/>
<SharePoint:GoBackButton runat="server"/>
</Template_RightButtons>
</wssuc:ToolBar>
</td></tr></table>
</span>
<SharePoint:AttachmentUpload runat="server"/>
</Template>
</SharePoint:RenderingTemplate>
Листинг 1. Шаблон по которому рисуются формы списков — ListForm
Контрол
<SharePoint:ListFieldIterator runat=«server»/>
отвечает за вывод полей. Идея заключается в том, что бы сделать свой ListFieldIterator и подключить его для нужных списков.
Можно сделать несколько ListFieldIterator-оров для разных списков, можно даже для каждой формы (NewForm.aspx, DispForm.aspx, EditForm.aspx) одного и того же списка назначить свой итератор.
1. Сделать наследника ListFieldIterator — Листинг 2.
public class MyFieldIterator : ListFieldIterator
{
protected override void CreateChildControls()
{
// массивы названий полей можно получать динамически
// здесь, для примера, они прохардкожены
var readOnlyFieldsInternalNames = new string[] { "Title", "Status" };
var excludeFieldsInternalNames = new string[] { "SalesPoint" };
for (int ii = 0; ii < base.Fields.Count; ii++)
{
var currentFiledInternalName = base.Fields[ii].InternalName;
if (base.IsFieldExcluded(base.Fields[ii]) ||
excludeFieldsInternalNames.Contains(currentFiledInternalName))
continue;
var fieldIterator = new ListFieldIterator()
{
ControlMode = readOnlyFieldsInternalNames.Contains(currentFiledInternalName) ?
SPControlMode.Display :
SPContext.Current.FormContext.FormMode,
ExcludeFields = string.Join(";#", base.Fields.Cast<SPField>()
.Where(ff => ff.InternalName != currentFiledInternalName)
.Select(ff => ff.InternalName).ToArray())
};
this.Controls.Add(fieldIterator);
}
}
}
Листинг 2. Наследник ListFieldIterator который прячет и переводит в ReadOnly заданные поля
Ничего сложного. Здесь для каждого поля, которое нужно отобразить, создается свой ListFieldIterator с нужным ControlMode. В ExcludeFields передается строка содержащая поля которые нужно исключить, т.е. все кроме текущего.
2. Сделать файл MyListForm.aspx и положить его в папку CONTROLTEMPLATES
В MyListForm.aspx скопируйте весь <SharePoint:RenderingTemplate id=«ListForm» runat=«server»>, замените id=«ListForm» на id=«MyListForm”, <SharePoint:ListFieldIterator runat=»server"/> на <My:MyFieldIterator runat=«server»> — Листинг 3.
...
<%@ Register TagPrefix="My" Assembly="$SharePoint.Project.AssemblyFullName$" namespace="My" %>
<SharePoint:RenderingTemplate id="MyListForm" runat="server">
…
<%--<SharePoint:ListFieldIterator runat="server"/>--%>
<My:MyFieldIterator runat="server" />
...
</SharePoint:RenderingTemplate>
Листинг 3. Свой шаблон вывода формы списков
Отметим, что MyListForm.aspx обязательно должен лежать в корне CONTROLTEMPLATES, если положить в под-папку не взлетит.
3. Указать для какой формы использовать шаблон MyListForm.
Для этого в ListDefinition укажите Template для нужной формы — Листинг 4.
...
<Forms>
<Form Type="DisplayForm" Url="DispForm.aspx" SetupPath="pagesform.aspx" WebPartZoneID="Main" />
<Form Type="EditForm" Url="EditForm.aspx" SetupPath="pagesform.aspx" WebPartZoneID="Main" Template="MyListForm" />
<Form Type="NewForm" Url="NewForm.aspx" SetupPath="pagesform.aspx" WebPartZoneID="Main" Template="MyListForm"/>
...
Листинг 4. ListDefinition с указанием шаблонов для вывода форм
Теперь вы знаете как управлять отображением полей на стандартных формах списков SharePoint.
Пример можно развить в нечто более интересное. Например мы сделали активность для рабочего процесса Nintex которая в PropertyBag элемента списка пишет правила — какие поля показывать, какие скрывать и для каких групп пользователей. Потом наш ListFieldIterator читает и применяет эти настройки. Таким образом у пользователей появилась возможность создавать более сложные рабочие процессы.
spuser.blogspot.ru/2011/04/how-to-easily-implement-sharepoint.html [2]
Автор: Alex_BBB
Источник [3]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/sharepoint/21578
Ссылки в тексте:
[1] JS-библиотечки: https://splistformutility.codeplex.com/
[2] spuser.blogspot.ru/2011/04/how-to-easily-implement-sharepoint.html: http://spuser.blogspot.ru/2011/04/how-to-easily-implement-sharepoint.html
[3] Источник: http://habrahabr.ru/post/160977/
Нажмите здесь для печати.