Didacticiel : Créer un widget personnalisé

  • Rversion finale: Zurich
  • Mis à jour 31 juil. 2025
  • 10 minutes de lecture
  • Suivez ce tutoriel pour créer un widget personnalisé qui affiche Catalogue de services les éléments. Utilisez ce didacticiel comme modèle pour vous aider à comprendre la puissance de script avancée du Portail de services.

    Dans ce tutoriel, vous allez créer le widget Commande rapide. Ce widget :
    • Affiche les éléments les plus courants à l’utilisateur avant toute recherche.
    • Interroge et Catalogue de services affiche les options disponibles à l’utilisateur.
    • Inclut un widget d’élément de catalogue SC intégré, permettant à l’utilisateur d’afficher et de commander des éléments 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é.

    Créer un widget et configurer un modèle

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

    Avant de commencer

    Rôle requis : admin ou sp_admin

    Procédure

    1. Accédez à la Tous > Portail de services > Configuration 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 : actif
      • ID de la page : quick_order

      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
      Remarque :
      Vous pouvez utiliser l’éditeur de page dans la configuration de Portail de services pour afficher la hiérarchie des éléments sur votre page de test.
    4. Cliquez sur Envoyer.
    5. Dans 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.

      Rendu de widget sur une page

    Ajouter un script serveur pour interroger une table d’instance

    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 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 éventuelles au serveur.

    Avant de commencer

    Rôle requis : admin ou sp_admin

    Procédure

    1. Dans l’éditeur de widget, ouvrez le widget Commande rapide.
    2. Sélectionnez Script serveur pour ouvrir le champ 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é sur 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.

      Tableau 1. Directives d’angle utilisées dans le modèle
      Directive d’angle Description
      ng-model Lit et écrit automatiquement les changements de valeur dans la variable de modèle c.data.keywords.
      ng-model-options Configure le comportement de modèle de nouvelle génération. Dans ce modèle, ng-model met à jour le modèle après qu’un utilisateur a arrêté de taper pendant 250 millisecondes.
      changement de nouvelle génération Exécute c.server.update() après modification de la valeur du modèle. 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.
      répétition ng-repeat 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.
    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 changements.

      Au fur et à mesure que vous tapez dans la zone de recherche, les éléments de catalogue correspondants apparaissent. Essayez de rechercher iPad.

      La recherche affiche les résultats pour iPad.

    Gérer l’état vide d’un widget

    Afficher une liste des éléments les plus courants à l’utilisateur avant que les termes de recherche ne soient saisis.

    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 est initialisé, la variable d’entrée serveur n’est pas définie. Cet état vide peut entraîner une confusion lorsqu’un utilisateur interagit pour la première fois avec le widget. 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 l’interaction initiale avec votre widget.

    Procédure

    1. Dans 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 les plus courants renvoyés par le script serveur.

    4. Actualisez l’aperçu de votre page de test pour afficher les changements.

      Le widget affiche les éléments les plus courants à l’utilisateur avant toute entrée de recherche.

      Zone de recherche avec le texte « Commencez à taper ici pour rechercher la liste des éléments de catalogue ».

    Incorporer un widget existant

    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 du 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’intégrer le widget d’élément de catalogue SC, inspectez le widget pour comprendre à quelles données il a besoin d’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 incorporé.
      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 du serveur.

        Notez que l’objet de données comprend 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() récupère le sys_id à partir de la chaîne de requête de la demande.

        Exemple de script serveur utilisant une instruction If Else pour récupérer le sys_id.

        Pour renseigner l’objet d’entrée , vous pouvez transmettre un sys_id d’élément de catalogue à partir du script client du widget Commande rapide.

    2. Dans 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 publie sur le script du 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 d’élément de catalogue SC intégré à l’aide de la directive sp-widget.
    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 changements.

      Lorsque vous sélectionnez un résultat de recherche, l’élément s’ouvre dans le widget Élément de catalogue SC intégré.

      Page de test affichant un élément sélectionné affiché dans un widget incorporé.

    Créer une directive réutilisable et l’ajouter à un widget

    Les fournisseurs d’angle sont des composants réutilisables qui peuvent être ajoutés à plusieurs widgets. À l’aide de la table Fournisseurs d’angles 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 Angular vous permettent de créer des directives et des services Angular 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 Tous > Portail de services > Configuration du Portail de services > Tables de portails > Fournisseur 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
      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 de catégorie du Catalogue de services.

      3. Sélectionnez Enregistrer.
    4. Associez la nouvelle directive Angular au widget Commande rapide.
      1. Accédez à la Tous > Portail de services > Widgets.
      2. Ouvrez le widget Commande rapide.
      3. Dans 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.
    5. Ajoutez la directive categoryIcon à votre modèle HTML de commande rapide.
      1. Dans 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>
        
    6. Actualisez l’aperçu de votre page de test pour afficher les changements.

      Une icône de catégorie s’affiche en regard de chaque résultat.