使用 SharePoint 提供程序托管的加载项创建 UX 控件

在 SharePoint 提供程序托管的加载项中创建 UX 控件,这些控件的工作和行为方式与主机 Web 上的 UX 控件类似。

本文描述了三个示例,向你介绍如何在提供程序托管的外接程序中实施 UX 控件:

这些示例使用 JavaScript 和 JSOM 与 SharePoint 通信,使用跨域库处理从加载项到主机网站集的函数调用。

注意

本文中的代码按原样提供,不提供任何明示或暗示的担保,包括对特定用途适用性、适销性或不侵权的默示担保。

人员选取器控件

Core.PeoplePicker 示例展示了如何在提供程序托管加载项中实现人员选取器控件。 如果用户开始在文本输入框中键入姓名,此控件便会在用户配置文件存储中搜索可能的匹配项,并将它们显示在 UI 中。 加载项显示的人员选取器控件不仅可配置,也可扩展,负责在远程主机上运行,并查询主机网站上的用户配置文件存储,以匹配用户输入。

人员选取器控件

人员选取器控件

注意

此示例的 Visual Studio 解决方案包含一个名为“虚拟”的模块,以确保在加载项部署时创建加载项 Web。 若要执行跨域调用,必须有加载项 Web。

Core.PeoplePickerWeb 项目的“脚本”文件夹包含 app.js 和 peoplepickercontrol.js 文件(以及用于提供其他语言支持的人员选取器资源文件)。 app.js 文件使用跨域库获取客户端上下文,并将 Default.aspx 文件中的 HTML 挂接到人员选取器控件。 Default.aspx 文件包含 <div> 标记,这些标记可实现文本框和人员搜索功能。

<div id="divAdministrators" class="cam-peoplepicker-userlookup ms-fullWidth">
  <span id="spanAdministrators"></span>
<asp:TextBox ID="inputAdministrators" runat="server" CssClass="cam-peoplepicker-edit" Width="70"></asp:TextBox>
</div>
<div id="divAdministratorsSearch" class="cam-peoplepicker-usersearch ms-emphasisBorder"></div>
<asp:HiddenField ID="hdnAdministrators" runat="server" />


然后,app.js 文件创建并配置人员选取器控件。

//Make a people picker control.
//1. context = SharePoint Client Context object
//2. $('#spanAdministrators') = SPAN that will 'host' the people picker control
//3. $('#inputAdministrators') = INPUT that will be used to capture user input
//4. $('#divAdministratorsSearch') = DIV that will show the 'drop-down' of the picker
//5. $('#hdnAdministrators') = INPUT hidden control that will host resolved users
peoplePicker = new CAMControl.PeoplePicker(context, $('#spanAdministrators'), $('#inputAdministrators'), $('#divAdministratorsSearch'), $('#hdnAdministrators'));
// required to pass the variable name here!
peoplePicker.InstanceName = "peoplePicker";
// Hook up everything.
peoplePicker.Initialize();


人员选取器控件查询 JSOM 库中的 ClientPeoplePickerWebServiceInterface 对象,以开始搜索名称与输入的字符串匹配的用户。

if (searchText.length >= parent.GetMinimalCharactersBeforeSearching()) {
                            resultDisplay = 'Searching...';
                            if (typeof resultsSearching != 'undefined') {
                                resultDisplay = resultsSearching;
                            }

                  var searchbusy = parent.Format('<div class=\'ms-emphasisBorder\' style=\'width: 400px; padding: 4px; border-left: none; border-bottom: none; border-right: none; cursor: default;\'>{0}</div>', resultDisplay);
                            parent.PeoplePickerDisplay.html(searchbusy);
                            // Display the suggestion box.
                            parent.ShowSelectionBox();

                   var query = new SP.UI.ApplicationPages.ClientPeoplePickerQueryParameters();
                            query.set_allowMultipleEntities(false);
                            query.set_maximumEntitySuggestions(2000);
                            query.set_principalType(parent.GetPrincipalType());
                            query.set_principalSource(15);
                            query.set_queryString(searchText);
                            var searchResult = SP.UI.ApplicationPages.ClientPeoplePickerWebServiceInterface.clientPeoplePickerSearchUser(parent.SharePointContext, query);

                  // Update the global queryID variable so that you can correlate incoming delegate calls.
                            parent._queryID = parent._queryID + 1;
                            var queryIDToPass = parent._queryID;
                            parent._lastQueryID = queryIDToPass;

                  // Make the SharePoint request.
                            parent.SharePointContext.executeQueryAsync(Function.createDelegate(this, function () { parent.QuerySuccess(queryIDToPass, searchResult); }),
                                                Function.createDelegate(this, function () { parent.QueryFailure(queryIDToPass); }));

分类菜单控件

Core.TaxonomyMenu 示例展示了如何在提供程序托管加载项中,实现从术语库填充内容的可本地化分类菜单控件。 加载项还设置填充菜单所必需的术语库语言、术语组、术语集和术语,并检查用户语言首选项,以便设置显示语言。

加载项实现 TaxonomyHelper 类 (CSOM),此类用于设置术语库,并在其中填充术语。 随后,它将显示导航链接的 JavaScript 文件上传到网站根文件夹中。

加载项在主机网站上设置术语库。 它使用 CSOM 对象和方法来创建术语组和术语集,然后在术语集中填充四个术语。

术语库设置屏幕

术语库设置屏幕

选择“设置术语库”按钮时,加载项可:

  • 确保所需语言(英语、德语、法语和瑞典语)已在术语库中启用。
  • 创建术语组和术语集并使用四个新术语填充术语集。

TaxonomyHelper 类中的下列代码负责验证是否已启用必需语言;如果没有,将会进行启用。

var languages = new int[] { 1031, 1033, 1036, 1053 };
            Array.ForEach(languages, l => { 
                if (!termStore.Languages.Contains(l)) 
                    termStore.AddLanguage(l); 
            });

            termStore.CommitAll();
            clientContext.ExecuteQuery();

// Create the term group.
termGroup = termStore.CreateGroup("Taxonomy Navigation", groupId);
                clientContext.Load(termGroup);
                clientContext.ExecuteQuery();

最后,同一 TaxonomyHelper 类中的下列代码负责新建每个术语,以及德语、法语和瑞典语的标签。 它还为 _Sys_Nav_SimpleLinkUrl 属性设置一个值,该值等效于术语库管理工具中的 简单链接或标头 属性。 在此示例中,每个术语的 URL 指回根网站。

var term = termSet.CreateTerm(termName, 1033, Guid.NewGuid());
term.CreateLabel(termNameGerman, 1031, false);
term.CreateLabel(termNameFrench, 1036, false);
term.CreateLabel(termNameSwedish, 1053, false);
term.SetLocalCustomProperty("_Sys_Nav_SimpleLinkUrl", clientContext.Web.ServerRelativeUrl);

接下来,加载项将 topnav.js 文件插入主机网站的根文件夹。 此文件中的 JavaScript 将链接从此术语集插入主机网站的主页导航。 加载项 UI 还会显示在加载项上传 JavaScript 文件后,导航链接在主机网站上的显示效果。

topnav.js 文件中的下列代码使用 JSOM 检查用户的首选语言。

var targetUser = "i:0#.f|membership|" + _spPageContextInfo.userLoginName;
        context = new SP.ClientContext.get_current();
var peopleManager = new SP.UserProfiles.PeopleManager(context);
var userProperty = peopleManager.getUserProfilePropertyFor(targetUser, "SPS-MUILanguages");

然后,加载项确定用户语言首选项是否与已启用的语言之一匹配。 如果找到匹配项,下面的代码会获取用户首选语言对应的术语和关联标签。

while (termEnumerator.moveNext()) {
    var currentTerm = termEnumerator.get_current();
    var label = currentTerm.getDefaultLabel(lcid);

    termItems.push(currentTerm);
    termLabels.push(label);
    context.load(currentTerm);

最后,topnav.js 文件中的下列代码会将包含术语的链接插入主机网站的顶部导航元素。

html += "<ul style='margin-top: 0px; margin-bottom: 0px;'>"
        for (var i in termItems) {
            var term = termItems[i];
            var termLabel = termLabels[i];
            var linkName = termLabel.get_value() != 0 ? termLabel.get_value() : term.get_name();
            var linkUrl = term.get_localCustomProperties()['_Sys_Nav_SimpleLinkUrl'];

            html += "<li style='display: inline;list-style-type: none; padding-right: 20px;'><a href='" + linkUrl + "'>" + linkName + "</a></li>";
        }
        html += "</ul>";

        $('#DeltaTopNavigation').html(html);
        SP.UI.Notify.removeNotification(nid);

分类选取器控件

Core.TaxonomyPicker 示例展示了如何在提供程序托管加载项中实现分类选取器控件。 如果用户开始在文本输入框中键入术语,此控件便会在术语库中搜索可能的匹配项,并将它们显示在输入框下面的列表中。

加载项先创建符合 JSOM 分类选取器要求的 HTML 页,再添加并配置控件。 它使用 JSOM 库来查询主机网站的术语库。 分类选取器与 SharePoint Managed Metadata Service 通信,这就需要在分类权限范围内拥有写入权限,以便可以从关闭的术语集读取术语,并将术语写入打开的术语集。 请确保 AppManifest.xml 文件已在适当的范围内设置了写入权限。

Core.TaxonomyPicker 项目的“脚本”文件夹包含 app.js 和 taxonomypickercontrol.js 文件(以及用于提供其他语言支持的分类选取器资源文件)。 app.js 文件使用跨域库提取客户端上下文,并将 Default.aspx 文件中的 HTML 挂钩到分类选取器控件。 Default.aspx 文件包含实现文本框和分类选取器功能的隐藏字段。 它还添加项目符号列表,用于显示从术语库返回的建议。

<div style="left: 50%; width: 600px; margin-left: -300px; position: absolute;">
            <table>
                <tr>
                    <td class="ms-formlabel" valign="top"><h3 class="ms-standardheader">Keywords Termset:</h3></td>
                    <td class="ms-formbody" valign="top">
                        <div class="ms-core-form-line" style="margin-bottom: 0px;">
                            <asp:HiddenField runat="server" id="taxPickerKeywords" />
                        </div>
                    </td>
                </tr>
            </table>

            <asp:Button runat="server" OnClick="SubmitButton_Click" Text="Submit" />

            <asp:BulletedList runat="server" ID="SelectedValues" DataTextField="Label" />
</div>

然后,app.js 文件创建并配置分类选取器控件。

// Load scripts for calling taxonomy APIs.
                    $.getScript(layoutsRoot + 'init.js',
                        function () {
                            $.getScript(layoutsRoot + 'sp.taxonomy.js',
                                function () {
                                    // Bind the taxonomy picker to the default keywords term set.
                                    $('#taxPickerKeywords').taxpicker({ isMulti: true, allowFillIn: true, useKeywords: true }, context);
                                });
                        });


分类选取器控件使用下面的代码打开 JSOM 中的 TaxonomySession 实例,以加载术语库中的所有术语。

// Get the taxonomy session by using CSOM.
            var taxSession = SP.Taxonomy.TaxonomySession.getTaxonomySession(spContext);
            //Use the default term store...this could be extended here to support additional term stores.
            var termStore = taxSession.getDefaultSiteCollectionTermStore();

            // Get the term set based on the properties of the term set.
            if (this.Id != null)
                this.RawTermSet = termStore.getTermSet(this.Id); // Get term set by ID.
            else if (this.UseHashtags)
                this.RawTermSet = termStore.get_hashTagsTermSet(); // Get the hashtags term set.
            else if (this.UseKeywords)
                this.RawTermSet = termStore.get_keywordsTermSet(); // Get the keywords term set.

            // Get all terms for the term set and organize them in the async callback.
            this.RawTerms = this.RawTermSet.getAllTerms();
            spContext.load(this.RawTermSet);
            spContext.load(this.RawTerms);
            spContext.executeQueryAsync(Function.createDelegate(this, this.termsLoadedSuccess), Function.createDelegate(this, this.termsLoadedFailed));

然后,分类选取器控件从加载的术语中查找可能的匹配项,并根据需要将新术语添加到术语库中。

另请参阅