Créer des contrôles d’UX à l’SharePoint des add-ins hébergés par un fournisseur

Créez des contrôles d’SharePoint dans des applications hébergées par un fournisseur qui fonctionnent et se comportent comme des contrôles d’UX sur le site web hôte.

Cet article décrit trois exemples qui vous montrent comment implémenter des contrôles d’UX dans votre application hébergée par un fournisseur :

  • Core.PeoplePicker – vous montre comment ajouter un contrôle s’il s’agit de personnes.

  • Core.TaxonomyMenu Vous montre comment implémenter un contrôle de – menu de taxonomie localisable.

  • Core.TaxonomyPicker vous montre comment implémenter un contrôle de – s’il s’agit de la taxonomie.

Ces exemples utilisent JavaScript et le JSOM pour communiquer avec SharePoint, et utilisent la bibliothèque entre domaines pour gérer les appels de fonction entre le add-in et le domaine du site hôte.

Notes

Le code dans cet article est fourni tel quel, sans garantie d’aucune sorte, expresse ou implicite, y compris mais sans s’y limiter, aucune garantie implicite d’adéquation à un usage particulier, à une qualité marchande ou une absence de contrefaçon.

Contrôle Sélecteur de personnes

L’exemple Core.PeoplePicker vous montre comment implémenter un contrôle s’il s’agit de personnes dans un application hébergée par un fournisseur. Lorsque l’utilisateur commence à taper un nom dans la zone de saisie de texte, le contrôle recherche dans le magasin de profils utilisateur des correspondances potentielles et les affiche dans l’interface utilisateur. Le add-in affiche un contrôle configurable et extensible de s’il s’exécute sur un hôte distant et interroge le magasin de profils utilisateur sur le site hôte pour qu’il corresponde aux entrées utilisateur.

Contrôle Sélecteur de personnes

Contrôle Sélecteur de personnes

Notes

La solution Visual Studio pour l’exemple contient un module nommé « Factice » pour s’assurer que lorsque le module est déployé, il crée un site web de module. Un site web de add-in est requis pour les appels entre domaines.

Le dossier Scripts du projet Core.PeoplePickerWeb contient des fichiers app.js et peoplepickercontrol.js (ainsi que des fichiers de ressources du s picker de personnes pour une prise en charge linguistique supplémentaire). Le app.js récupère le contexte client à l’aide de la bibliothèque entre domaines et raccorde le code HTML dans le fichier Default.aspx dans le contrôle du s picker de personnes. Le fichier Default.aspx contient les balises qui implémentent la zone de texte et la fonctionnalité de <div> recherche de personnes.

<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" />


Le app.js crée et configure ensuite un contrôle s’il s’agit de personnes.

//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();


Le contrôle du s picker de personnes interroge l’objet ClientPeoplePickerWebServiceInterface dans la bibliothèque JSOM pour lancer des recherches pour les utilisateurs dont les noms correspondent aux chaînes de caractères entrées.

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); }));

Contrôle de menu de taxonomie

L’exemple Core.TaxonomyMenu vous montre comment implémenter un contrôle de menu de taxonomie localisable qui est rempli à partir du magasin de termes dans un add-in hébergé par un fournisseur. Le add-in définit également les langues, groupes, ensembles et termes du magasin de termes requis pour remplir le menu, et vérifie les préférences de langue de l’utilisateur pour définir la langue d’affichage.

Le add-in implémente une classe TaxonomyHelper (CSOM) qui définit le magasin de termes et le remplit avec des termes. Il charge ensuite dans le dossier racine du site un fichier JavaScript qui affiche les liens de navigation.

Le add-in définit le magasin de termes sur le site hôte. Il utilise des objets et des méthodes CSOM pour créer un groupe de termes et un ensemble de termes, puis remplit l’ensemble de termes avec quatre termes.

Écran de configuration du magasin de termes

Écran de configuration du magasin de termes

Lorsque vous choisissez le bouton Du magasin de termes du programme d’installation, le add-in :

  • S’assure que les langues requises (anglais, allemand, français et suédois) sont activées dans le magasin de termes.
  • Crée un groupe de termes et un ensemble de termes et remplit l’ensemble de termes avec quatre nouveaux termes.

Le code suivant de la classe TaxonomyHelper vérifie que les langues requises sont activées et, si ce n’est pas le cas, il les active.

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();

Enfin, le code suivant dans la même classe TaxonomyHelper crée chaque nouveau terme, ainsi que des étiquettes pour les langues allemande, française et suédois. Il définit également une valeur pour la propriété _ Sys _ Nav _ SimpleLinkUrl, qui est équivalente à la propriété Simple Link ou Header de l’outil de gestion du magasin de termes. Dans ce cas, l’URL de chaque terme pointe vers le site racine.

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);

Ensuite, le add-in insère le topnav.js dans le dossier racine du site hôte. Ce fichier contient le JavaScript qui insère les liens de cet ensemble de termes dans la navigation de la page d’accueil du site hôte. L’interface utilisateur du add-in vous montre également comment les liens de navigation apparaîtront sur le site hôte une fois que le add-in a téléchargé le fichier JavaScript.

Le code suivant dans le fichier topnav.js utilise JSOM pour vérifier la langue préférée de l’utilisateur.

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");

Le add-in détermine ensuite si la préférence de langue de l’utilisateur correspond à l’une des langues activées. S’il trouve une correspondance, le code suivant obtient les termes et les étiquettes associées pour la langue préférée de l’utilisateur.

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

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

Enfin, le code suivant dans le fichier topnav.js insère des liens qui contiennent les termes dans l’élément de navigation supérieur du site hôte.

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);

Contrôle du soche de taxonomie

L’exemple Core.TaxonomyPicker vous montre comment implémenter un contrôle de s’il s’agit d’une taxonomie dans un application hébergée par un fournisseur. Lorsque l’utilisateur commence à taper un terme dans la zone de saisie de texte, le contrôle recherche dans le magasin de termes des correspondances potentielles et les affiche dans une liste sous la zone d’entrée.

Le add-in crée une page HTML qui est conforme aux exigences du s picker de taxonomie JSOM, puis ajoute et configure le contrôle. Il utilise la bibliothèque JSOM pour interroger le magasin de termes du site hôte. Le s picker de taxonomie communique avec le service de métadonnées gérées SharePoint, qui nécessite une autorisation d’écriture au niveau de l’étendue des autorisations de taxonomie afin qu’il puisse lire des ensembles de termes fermés et écrire dans des ensembles de termes ouverts. Assurez-vous que le fichier AppManifest.xml a définie l’autorisation d’écriture au niveau de l’étendue appropriée.

Le dossier Scripts du projet Core.TaxonomyPicker contient des fichiers app.js et taxonomypickercontrol.js (ainsi qu’un fichier de ressources du s picker de taxonomie pour une prise en charge linguistique supplémentaire). Le app.js récupère le contexte client à l’aide de la bibliothèque entre domaines et raccorde le code HTML dans le fichier Default.aspx dans le contrôle de s’il s’y rapporte. Le fichier Default.aspx contient le champ masqué qui implémente la zone de texte et la fonctionnalité de sélection de taxonomie. Il ajoute également une liste à puces pour afficher les suggestions renvoyées par le magasin de termes.

<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>

Le app.js crée et configure ensuite un contrôle de s’il s’agit de la taxonomie.

// 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);
                                });
                        });


Le contrôle du s picker de taxonomie utilise le code suivant pour ouvrir une instance TaxonomySession dans le JSOM afin de charger tous les termes à partir du magasin de termes.

// 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));

Le contrôle du s picker de taxonomie recherche ensuite les correspondances potentielles à partir des termes chargés et ajoute de nouveaux termes au magasin de termes selon les besoins.

Voir aussi