---
sourceDocument: Interface utilisateur de la Now Platform Xanadu
sourceDocumentLink: https://servicenow-prod.fluidtopics.net/r/fr-FR/xanadu/platform-user-interface

 Release :

    - xanadu

ft:locale :

    - fr-FR

ft:publication_title :

    - Interface utilisateur de la Now Platform Xanadu

ft:clusterId :

    - platux

bundleId :

    - platux

workflow :

    - Platform


---

# Didacticiel : Créer un widget personnalisé

# Didacticiel : Créer un widget personnalisé {#ariaid-title1}

* Rversion finale: Xanadu
* 
* Mis à jour 1 août 2024
* 
* ![](https://www.servicenow.com/docs/portal-asset/ico-clock) 10 minutes de lecture

Suivez ce didacticiel pour créer un widget personnalisé qui affiche Catalogue de services des éléments. Utilisez ce didacticiel comme modèle pour vous aider à comprendre la puissance de scripting avancée du Portail de servicesfichier .  
Dans ce didacticiel, vous allez créer le widget Commande rapide. Ce widget :

* Affiche les éléments les plus courants pour l'utilisateur avant toute recherche.
* Interroge et Catalogue de services affiche les options disponibles pour l'utilisateur.
* Inclut un widget d'élément de catalogue SC intégré, permettant à l'utilisateur d'afficher et de commander des articles dans le widget de commande rapide.
* Utilise un fournisseur d'angle pour afficher une icône de catégorie en regard de chaque élément interrogé.
{#adv-widget-tutorial__ul_n2x_lkh_xz}

## Créer un widget et configurer un modèle {#ariaid-title2}

Créez le widget Commande rapide pour interroger les éléments dans le Catalogue de servicesfichier .

### Avant de commencer

Rôle requis : admin ou sp_admin

### Procédure

1. Accédez à la ToutPortail de servicesConfiguration du Portail de services et cliquez sur Éditeur de widget.
2. Cliquez sur Créer un widget.
3. Définissez les valeurs suivantes.  
   * Nom du widget : commande rapide
   * ID de widget : quick_order
   * Créer une page de test : active
   * ID de page : quick_order
   {#create-widget__ul_tf5_rjh_xz}  
   L'ajout d'un widget à une page de test crée un enregistrement dans chacune des tables suivantes :  
   * sp_page
   * sp_container
   * sp_row
   * sp_column
   * sp_instance
   * sp_widget
   {#create-widget__ul_ag2_wqh_xz}  
   Remarque :  
   Vous pouvez utiliser l'éditeur de page dans la configuration du portail de services pour afficher la hiérarchie des éléments sur votre page de test.
4. Cliquez sur Envoyer.
5. Depuis l'éditeur de widget, ouvrez le widget Commande rapide.
6. Ajoutez le modèle simple suivant au champ HTML.  

       <div class="panel panel-primary">
        <div class="panel-heading">Request an item from the catalog</div>
        <div class="panel-body">
          My catalog results
        </div>
       </div>

7. Cliquez sur Enregistrer.
8. Prévisualisez votre page de test dans un nouvel onglet à l'aide de l'URL suivante : `<yourInstanceUrl>/sp ?id=quick_order`.  
   Votre modèle de widget s'affiche sur la page de test.

## Ajouter un script serveur pour interroger une table d'instance {#ariaid-title3}

Après avoir ajouté votre widget et créé un modèle de base, vous pouvez définir des scripts client et serveur avancés qui permettent aux utilisateurs d'interroger les données à partir d'une table d'instance. Vous pouvez transmettre le modèle de données entre le client et le serveur en interrogeant les données de la base de données, en les affichant à l'utilisateur et en renvoyant les mises à jour au serveur.

### Avant de commencer

Rôle requis : admin ou sp_admin

### Procédure

1. Depuis l'éditeur de widget, ouvrez le widget Commande rapide.
2. Sélectionnez Script serveur pour ouvrir le champ de script serveur.
3. Remplacez le script serveur par défaut par le script personnalisé suivant.  

       (function() {
       	if (input.keywords != null && input.keywords != '')
       		data.items = getCatalogItems(input.keywords);
       	
       	function getCatalogItems(keywords) {
       		var sc = new GlideRecord('sc_cat_item');
       		sc.addActiveQuery();
       		sc.addQuery('123TEXTQUERY321', keywords);
       		sc.addQuery('sys_class_name', 'NOT IN', 'sc_cat_item_wizard,sc_cat_item_content');
       		sc.addQuery('sc_catalogs', 'e0d08b13c3330100c8b837659bba8fb4');
       		sc.setLimit(100);
       		sc.orderByDesc("ir_query_score");
       		sc.query();
       		var results = [];
       		while (sc.next()) {
       			if (!$sp.canReadRecord(sc))
       				continue;

       			var item = {};
       			$sp.getRecordDisplayValues(item, sc, 'name,price,sys_id');
       			item.category = sc.getValue('category');
       			results.push(item);
       		}
       		return results;
       	}
       })();

   Ce script effectue une recherche par mot clé dans la table sc_cat_item à l'aide de la méthode de requête 123TEXTQUERY321.
4. Remplacez le modèle HTML par le script suivant :  

       <div class="panel panel-primary">
        <div class="panel-heading">Request an item from the catalog</div>
        <div class="panel-body">
          <input class="form-control" type="search" placeholder="Start typing here to search the list of catalog items" ng-model="c.data.keywords" ng-change="c.server.update()" ng-model-options="{debounce: 250}" />
          <ul class="list-group result-container">
            <li class="list-group-item" ng-repeat="item in c.data.items">
              <a href>{{item.name}}</a><span class="pull-right">{{item.price}}</span>
            </li>
          </ul>
        </div>
       </div>

   Ce modèle ajoute un champ de recherche et affiche les résultats de la requête exécutée dans le script serveur à l'aide des directives Angular suivantes. Pour en savoir plus sur ces directives, consultez la [référence de l'API Angular](https://docs.angularjs.org/api/ng/directive).  
   {#add-scripts__table_q2x_tzw_xz__entry__2}

   | Directive angulaire | Description |
   |-|-|
   | modèle ng | Lit et écrit automatiquement les changements de valeur dans la variable `de modèle c.data.keywords`. |
   | options de modèle ng | Configure le comportement du modèle ng. Dans ce modèle, ng-model met à jour le modèle après qu'un utilisateur a arrêté la saisie pendant 250 millisecondes. |
   | ng-changement | Exécute `c.server.update()` une fois que la valeur du modèle a changé. Cette fonction publie l'objet de données dans le script serveur. Une fois le script exécuté, l'objet de données est automatiquement mis à jour avec les nouvelles valeurs de l'objet de données généré par le serveur. |
   | ng-répéter | Crée un modèle à partir de l'élément parent et des éléments enfants. Pour chaque `élément dans c.data.items`, une instance du modèle est créée et les expressions `{{item.name}}` et `{{item.price}}` sont remplacées par les valeurs de chaque élément. |
   [Tableau 1. Directives angulaires utilisées dans le modèle]

   {#add-scripts__table_q2x_tzw_xz}
5. Ajoutez le script suivant au champ CSS - SCSS :  

       .result-container {
        margin-top: 10px;
       }

6. Actualisez l'aperçu de votre page de test pour afficher les modifications.  
   Lorsque vous tapez dans la zone de recherche, les éléments de catalogue correspondants apparaissent. Essayez de rechercher ipad.

## Gérer l'état vide d'un widget {#ariaid-title4}

Affichez une liste des éléments les plus courants pour l'utilisateur avant la saisie des termes de recherche.

### Avant de commencer

Rôle requis : admin ou sp_admin

### Pourquoi et quand exécuter cette tâche

Étant donné qu'aucune recherche n'a été exécutée lorsque le widget a été initialisé, la variable d'entrée du serveur n'est pas définie. Cet état vide peut entraîner une confusion lorsqu'un utilisateur interagit avec le widget pour la première fois. Pour résoudre ce problème, donnez à votre widget quelque chose à afficher lorsque la variable d'entrée est vide. Ces données initiales peuvent guider vos utilisateurs lors de leur première interaction avec votre widget.

### Procédure

1. Depuis l'éditeur de widget, ouvrez le widget Commande rapide.
2. Remplacez le script serveur existant par le script suivant :  

       (function() {
       	if (input.keywords != null && input.keywords != '')
       		data.items = getCatalogItems(input.keywords);
       	else data.items = getPopularItems();

       	function getCatalogItems(keywords) {
       		var sc = new GlideRecord('sc_cat_item');
       		sc.addActiveQuery();
       		sc.addQuery('123TEXTQUERY321', keywords);
       		sc.addQuery('sys_class_name', 'NOT IN', 'sc_cat_item_wizard,sc_cat_item_content');
       		sc.addQuery('sc_catalogs', 'e0d08b13c3330100c8b837659bba8fb4');
       		sc.setLimit(100);
       		sc.orderByDesc("ir_query_score");
       		sc.query();
       		var results = [];
       		while (sc.next()) {
       			if (!$sp.canReadRecord(sc))
       				continue;

       			var item = {};
       			$sp.getRecordDisplayValues(item, sc, 'name,price,sys_id');
       			item.category = sc.getValue('category');
       			results.push(item);
       		}
       		return results;
       	}
       	
       	function getPopularItems() {
       		var items = [];
       		var count = new GlideAggregate('sc_req_item');
       		count.addAggregate('COUNT','cat_item');
       		count.groupBy('cat_item');
       		count.addQuery('cat_item.sys_class_name', 'NOT IN', 'sc_cat_item_guide,sc_cat_item_wizard,sc_cat_item_content');
       		count.addQuery('cat_item.sc_catalogs', 'e0d08b13c3330100c8b837659bba8fb4');
       		count.orderByAggregate('COUNT', 'cat_item');
       		count.query();
       		while (count.next() && items.length < 9) {
       			if (!$sp.canReadRecord("sc_cat_item", count.cat_item.sys_id.getDisplayValue()))
       				continue; // user does not have permission to see this item

       			var item = {};
       			item.name = count.cat_item.name.getDisplayValue();
       			item.category = count.cat_item.category.toString();
       			item.price = count.cat_item.price.getDisplayValue();
       			item.sys_id = count.cat_item.sys_id.getDisplayValue();
       			items.push(item);
       		}
       		return items;
       	}
       })();

   Ce script introduit une nouvelle fonction `getPopularItems()` pour interroger la base de données et renvoyer les éléments populaires lorsque la variable d'entrée est vide.
3. Remplacez le modèle HTML par le script suivant :  

       <div class="panel panel-primary">
         <div class="panel-heading">Request an item from the catalog</div>
         <div class="panel-body">
           <input class="form-control" type="search" placeholder="Start typing here to search the list of catalog items" ng-model="c.data.keywords" ng-change="c.server.update()" ng-model-options="{debounce: 250}" />
           <h5 ng-if="!c.data.keywords">Showing the most popular items</h5>
           <ul class="list-group result-container">
             <li class="list-group-item" ng-repeat="item in c.data.items">
               <a href>{{item.name}}</a><span class="pull-right">{{item.price}}</span>
             </li>
           </ul>
         </div>
         <div class="panel-footer" ng-if="c.data.keywords">
           <ng-pluralize count="c.data.items.length"
                        when="{'0': 'No items found for ',
                            '1': 'One item matching ',
                            'other': 'Found {} items matching '}">
           </ng-pluralize>
           {{c.data.keywords}}
         </div>
       </div>

   Ce script fournit un modèle pour afficher les éléments populaires renvoyés par le script serveur.
4. Actualisez l'aperçu de votre page de test pour afficher les modifications.  
   Le widget affiche les éléments les plus courants pour l'utilisateur avant toute entrée de recherche.

## Incorporer un widget existant {#ariaid-title5}

Permettez à l'utilisateur d'afficher et d'acheter Catalogue de services des éléments dans le widget Commande rapide en incorporant le widget Élément de catalogue SC.

### Avant de commencer

Rôle requis : admin ou sp_admin

### Pourquoi et quand exécuter cette tâche

Au lieu de dupliquer le code, vous pouvez intégrer des widgets pour tirer parti des fonctionnalités préexistantes. Le widget Élément de catalogue SC est un widget du système de base qui permet à l'utilisateur d'afficher et d'acheter Catalogue de services des éléments.

### Procédure

1. Inspectez le widget Élément de catalogue SC.  
   Avant d'incorporer le widget Élément de catalogue SC, inspectez le widget pour comprendre à quelles données il doit accéder. Vous devrez peut-être mettre à jour votre script client ou serveur de widget Commande rapide pour vous assurer que les données correctes sont transmises au widget intégré.
   1. Accédez à `<yourInstanceURL>/sp_config ?id=widget_editor`.
   2. Ouvrez le widget Élément de catalogue SC.
   3. Notez que l'ID du widget est `widget-sc-cat-item`.  
      Vous allez utiliser cet ID pour intégrer le modèle de widget dans le script client.
   4. Examinez le script serveur.  
      Notez que l'objet de données inclut une propriété sys_id renseignée par les objets d'entrée ou d'options. Si ni l'entrée ni les options n'incluent de sys_id, la méthode [$sp.getParameter()](https://www.servicenow.com/docs/access?context=c_GlideSPScriptableScopedAPI&version=xanadu&pubname=xanadu-api-reference&ft:locale=en-US) récupère le sys_id à partir de la chaîne de requête de la demande.

      Pour renseigner l'objet d'entrée , vous pouvez transmettre un élément de catalogue sys_id à partir du script client du widget Commande rapide.
   {#embed-widget__substeps_x34_wkc_yz}
2. Depuis l'éditeur de widget, ouvrez le widget Commande rapide.
3. Remplacez le script client du widget Commande rapide par le script suivant.  

       function($location, spUtil) {
         var c = this;
       	
       	c.select = function(item_id) {
       		if (c.openItem == item_id) {
       			c.openItem = null;
       			return;
       		}
       		
       		renderCatalogItemWidget(item_id);
       	}
       	
       	function renderCatalogItemWidget(item_id) {
       		c.catalogItemWidget = null;
       		spUtil.get("widget-sc-cat-item", {sys_id: item_id}).then(function(response){
       			c.catalogItemWidget = response;
       			c.openItem = item_id;
       		});
       	}
       }

   Ce script utilise `spUtil.get()` pour récupérer le modèle de widget par ID (`widget-sc-cat-item`) et définir l'objet `{sys_id : item_id}` . Cet objet est publié sur le script serveur en tant qu'entrée.
4. Remplacez le modèle HTML par le script suivant :  

       <div class="panel panel-primary">
         <div class="panel-heading">Request an item from the catalog</div>
         <div class="panel-body">
           <input class="form-control" type="search" placeholder="Start typing here to search the list of catalog items" ng-model="c.data.keywords" ng-change="c.server.update()" ng-model-options="{debounce: 250}" />
           <h5 ng-if="!c.data.keywords">Showing the most popular items</h5>
           <ul class="list-group result-container">
             <li class="list-group-item" ng-repeat="item in c.data.items">
               <a href ng-click="c.select(item.sys_id)">{{item.name}}</a><span class="pull-right">{{item.price}}</span>
               <div class="catalog-item" ng-if="item.sys_id == c.openItem">
                   <sp-widget ng-if="c.catalogItemWidget" widget="c.catalogItemWidget" />
               </div>
             </li>
           </ul>
         </div>
         <div class="panel-footer" ng-if="c.data.keywords">
           <ng-pluralize count="c.data.items.length"
                        when="{'0': 'No items found for ',
                            '1': 'One item matching ',
                            'other': 'Found {} items matching '}">
           </ng-pluralize>
           {{c.data.keywords}}
         </div>
       </div>

   Ce modèle :  
   * Ajoute un comportement au clic à l'aide de la directive ng-click.
   * Affiche le widget Élément de catalogue SC intégré à l'aide de la directive sp-widget.
   {#embed-widget__ul_ygs_bsg_zz}
5. Remplacez le CSS par le script suivant :  

       .result-container {
         margin-top: 10px;
       }

       .catalog-item {
         background-color: #f5f5f5;
         padding: 10px;
         @include border-top-radius($panel-border-radius);
         @include border-bottom-radius($panel-border-radius);
       }

6. Actualisez l'aperçu de votre page de test pour afficher les modifications.  
   Lorsque vous sélectionnez un résultat de recherche, l'élément s'ouvre dans le widget Élément de catalogue SC intégré.

## Créer une directive réutilisable et l'ajouter à un widget {#ariaid-title6}

Les fournisseurs d'angle sont des composants réutilisables qui peuvent être ajoutés à plusieurs widgets. À l'aide de la table Fournisseurs d'angle de widget, créez une directive qui affiche une icône de catégorie en regard de chaque résultat dans le widget Commande rapide.

### Avant de commencer

Rôle requis : admin ou sp_admin

### Pourquoi et quand exécuter cette tâche

Les fournisseurs d'angle vous permettent de créer des directives et des services d'angle qui peuvent être injectés dans votre contrôleur de script client. Le code d'un fournisseur diffère d'une directive ou d'un service Angular typique car il doit être anonyme, sans être ajouté à un module spécifique.

### Procédure

1. Accédez à la ToutPortail de servicesConfiguration du Portail de servicesTables de portailsFournisseur d'angles de widget.  
   La table Fournisseurs d'angles de widget s'ouvre.
2. Sélectionnez Nouveau pour créer un nouvel enregistrement.
3. Remplissez le formulaire.
   1. Ajoutez le type et le nom.  
      * Type : Directive
      * Nom : categoryIcon
      {#reusable-directive__ul_tf5_rjh_xz}
   2. Ajoutez le script client.  

          function() {
            return {
              template: '<span class="fa fa-stack fa-lg"><i class="fa fa-circle fa-stack-2x"></i><i class="fa fa-{{::icon}} fa-stack-1x fa-inverse"></i></span>',
              restrict: 'E',
              replace: true,
              scope: {
                category: '='
              },
              link: function(scope, element) {
          					
          var _iconMap = {
          		"b06546f23731300054b6a3549dbe5dd8": "tablet", /* Tablets */
          		"15706fc0a0a0aa7007fc21e1ab70c2f": "question", /* Can we help you? */
          		"d68eb4d637b1300054b6a3549dbe5db2": "mobile-phone", /* Mobiles */
          		"109cdff8c6112276003b17991a09ad65": "print", /* Office and Print */
          		"5d643c6a3771300054b6a3549dbe5db0": "print", /* Printers */
          		"2c0b59874f7b4200086eeed18110c71f": "plug", /* Peripherals */
          		"2809952237b1300054b6a3549dbe5dd4": "desktop" /* Software */
          	};
          			
          	scope.icon = _iconMap[scope.category] || "shopping-cart";
              }
            }
          }

      Ce script associe le sys_id de l'enregistrement de catégorie à l'élément Catalogue de services . L'icône qui s'affiche est l'icône définie dans l'enregistrement Catégorie du Catalogue de services.
   3. Sélectionnez Enregistrer.
   {#reusable-directive__substeps_crw_pcd_yz}
4. Associez la nouvelle directive Angular au widget Quick Order.
   1. Accédez à la ToutPortail de servicesWidgets.
   2. Ouvrez le widget Commande rapide.
   3. Sous Listes connexes, sélectionnez Fournisseurs d'angle.
   4. Dans la liste Fournisseurs d'angle, sélectionnez Modifier et associez le fournisseur d'angle categoryIcon au widget Commande rapide.
   5. Sélectionnez Enregistrer.
   {#reusable-directive__substeps_uqt_y3d_yz}
5. Ajoutez la directive categoryIcon à votre modèle HTML de commande rapide.
   1. Depuis l'éditeur de widget, ouvrez le widget Commande rapide.
   2. Remplacez le modèle HTML par le script suivant.  

          <div class="panel panel-primary">
            <div class="panel-heading">Request an item from the catalog</div>
            <div class="panel-body">
              <input class="form-control" type="search" placeholder="Start typing here to search the list of catalog items" ng-model="c.data.keywords" ng-change="c.server.update()" ng-model-options="{debounce: 250}" />
              <h5 ng-if="!c.data.keywords">Showing the most popular items</h5>
              <ul class="list-group result-container">
                <li class="list-group-item" ng-repeat="item in c.data.items">
                  <a href ng-click="c.select(item.sys_id)"><category-icon category="item.category" style="margin-right: 10px"></category-icon>{{item.name}}</a><span class="pull-right">{{item.price}}</span>
                  <div class="catalog-item" ng-if="item.sys_id == c.openItem">
                      <sp-widget ng-if="c.catalogItemWidget" widget="c.catalogItemWidget" />
                    </div>
                </li>
              </ul>
            </div>
            <div class="panel-footer" ng-if="c.data.keywords">
              <ng-pluralize count="c.data.items.length"
                           when="{'0': 'No items found for ',
                               '1': 'One item matching ',
                               'other': 'Found {} items matching '}">
              </ng-pluralize>
              {{c.data.keywords}}
            </div>
          </div>

   {#reusable-directive__substeps_pww_rkd_yz}
6. Actualisez l'aperçu de votre page de test pour afficher les modifications.  
   Une icône de catégorie s'affiche en regard de chaque résultat.


