---
sourceDocument: Interface do usuário da Now Platform Yokohama
sourceDocumentLink: https://servicenow-prod.fluidtopics.net/r/pt-BR/yokohama/platform-user-interface

 Release :

    - yokohama

ft:locale :

    - pt-BR

ft:publication_title :

    - Interface do usuário da Now Platform Yokohama

ft:clusterId :

    - platux

bundleId :

    - platux

workflow :

    - Platform


---

# Tutorial: Criar um widget personalizado

# Tutorial: Criar um widget personalizado {#ariaid-title1}

* Versão de lançamento: Yokohama
* 
* Atualizado 30 de jan. de 2025
* 
* ![](https://www.servicenow.com/docs/portal-asset/ico-clock) 10 min. de leitura

Siga este tutorial para criar um widget personalizado que é exibido Catálogo de serviçositens. Use este tutorial como um modelo para ajudar você a entender o poder de script avançado do Portal de serviços.  
Neste tutorial, você criará o widget Pedido rápido. Este widget:

* Exibe itens populares para o usuário antes de qualquer pesquisa.
* Consulta o. Catálogo de serviçose exibe as opções disponíveis para o usuário.
* Inclui um widget de item do catálogo SC incorporado, permitindo que o usuário exiba e solicite itens no widget Pedido rápido.
* Usa um provedor angular para exibir um ícone de categoria ao lado de cada item consultado.
{#adv-widget-tutorial__ul_n2x_lkh_xz}

## Crie um widget e configure um modelo {#ariaid-title2}

Crie o widget Pedido rápido para consultar itens no Catálogo de serviços.

### Antes de Iniciar

Função necessária: administrador ou sp_admin

### Procedimento

1. Navegar até TudoPortal de serviçosConfiguração do Portal de serviços e clique em Editor de widget .
2. Clique em Criar um novo widget.
3. Defina os seguintes valores.  
   * Nome do widget : Pedido rápido
   * ID do widget : quick_order
   * Crie uma página de teste : Ativo
   * ID da página : quick_order
   {#create-widget__ul_tf5_rjh_xz}  
   A adição de um widget a uma página de teste cria um registro em cada uma das seguintes tabelas:  
   * sp_page
   * sp_contêiner
   * sp_row
   * coluna_sp
   * sp_instance
   * sp_widget
   {#create-widget__ul_ag2_wqh_xz}  
   Nota:  
   Você pode usar o Editor de páginas na Configuração do portal de serviços para exibir a hierarquia de elementos na sua página de teste.
4. Clique em Enviar.
5. Em Editor de widget , Abra o widget Pedido rápido.
6. Adicione o seguinte modelo simples ao campo 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. Clique em Salvar.
8. Visualize sua página de teste em uma nova guia usando a seguinte URL: `<yourInstanceUrl>/sp?id_quick_order `.  
   Seu modelo de widget é exibido na página de teste.

## Adicionar um script de servidor para consultar uma tabela de instância {#ariaid-title3}

Depois de adicionar seu widget e criar um modelo básico, você pode definir scripts avançados de cliente e servidor que permitem que os usuários consultem dados de uma tabela de instância. Você pode passar o modelo de dados entre o cliente e o servidor consultando dados do banco de dados, exibindo-os para o usuário e enviando todas as atualizações de volta para o servidor.

### Antes de Iniciar

Função necessária: administrador ou sp_admin

### Procedimento

1. Em Editor de widget , Abra o widget Pedido rápido.
2. Selecione Script do servidor para abrir o campo de script do servidor.
3. Substitua o script do servidor padrão pelo script personalizado a seguir.  

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

   Este script executa uma pesquisa de palavra-chave na tabela sc_cat_item usando o método de consulta 123TEXTQUERY321.
4. Substitua o modelo HTML pelo seguinte script:  

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

   Este modelo adiciona um campo de pesquisa e exibe os resultados da consulta realizada no script do servidor usando as seguintes diretivas Angular. Para saber mais sobre essas diretivas, revise [Referência da API Angular](https://docs.angularjs.org/api/ng/directive).  
   {#add-scripts__table_q2x_tzw_xz__entry__2}

   | Diretiva angular | Descrição |
   |-|-|
   | ng-model | Lê e grava automaticamente mudanças de valor na variável do modelo `c.data.palavras-chave `. |
   | ng-model-options | Configura o comportamento do ng-model. Neste modelo, ng-model atualiza o modelo após um usuário parar de digitar por 250 milissegundos. |
   | mudança de ng | Executa `c.server.update() `depois que o valor do modelo muda. Esta função publica o objeto de dados no script do servidor. Após a execução do script, o objeto de dados é atualizado automaticamente com os novos valores do objeto de dados gerado pelo servidor. |
   | repetição de ng | Cria um modelo a partir do elemento primário e dos elementos secundários. Para cada `item em c.data.items `, uma instância do modelo é criada e as expressões `(item.name}} `e. `(item.price) `são substituídos pelos valores de cada item. |
   [Tabela 1. Diretivas angulares usadas no modelo]

   {#add-scripts__table_q2x_tzw_xz}
5. Adicione o script a seguir ao CSS - SCSS campo:  

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

6. Atualize a visualização da página de teste para exibir as mudanças.  
   Conforme você digita na caixa de pesquisa, os itens do catálogo correspondentes são exibidos. Tente pesquisar ipad .

## Gerencie o estado vazio de um widget {#ariaid-title4}

Exiba uma lista de itens populares para o usuário antes de inserir quaisquer termos de pesquisa.

### Antes de Iniciar

Função necessária: administrador ou sp_admin

### Por Que e Quando Desempenhar Esta Tarefa

Nenhuma pesquisa foi executada quando o widget é inicializado, o servidor entrada a variável está indefinida. Este estado vazio pode causar confusão quando um usuário interage pela primeira vez com o widget. Para resolver esse problema, dê ao widget algo para exibir quando entrada a variável está vazia. Esses dados iniciais podem orientar seus usuários ao interagir inicialmente com seu widget.

### Procedimento

1. Em Editor de widget , Abra o widget Pedido rápido.
2. Substitua o script de servidor existente pelo seguinte script:  

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

   Este script introduz uma nova função `GetPopularItems() `para consultar o banco de dados e retornar itens populares quando entrada a variável está vazia.
3. Substitua o modelo HTML pelo seguinte script:  

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

   Este script fornece um modelo para exibir os itens populares retornados do script do servidor.
4. Atualize a visualização da página de teste para exibir as mudanças.  
   O widget exibe itens populares para o usuário antes de qualquer entrada de pesquisa.

## Incorporar um widget existente {#ariaid-title5}

Permita que o usuário exiba e compre Catálogo de serviçosItens no widget Pedido rápido incorporando o widget Item do catálogo SC.

### Antes de Iniciar

Função necessária: administrador ou sp_admin

### Por Que e Quando Desempenhar Esta Tarefa

Em vez de duplicar o código, você pode incorporar widgets para aproveitar a funcionalidade pré-existente. O widget de item do catálogo SC é um widget do sistema de base que permite que o usuário exiba e compre Catálogo de serviçositens.

### Procedimento

1. Inspecione o widget de item do catálogo SC.  
   Antes de incorporar o widget de item do catálogo SC, inspecione o widget para entender quais dados ele precisa acessar. Pode ser necessário atualizar o script do cliente do widget de pedido rápido ou do servidor para garantir que os dados corretos sejam passados para o widget incorporado.
   1. Navegue até `<yourInstanceURL>/sp_config?id_widget_editor `.
   2. Abra o widget Item do catálogo SC.
   3. Observe que o ID do widget é `widget-sc-cat-item `.  
      Você usará este ID para incorporar o modelo de widget no script do cliente.
   4. Examine o script do servidor.  
      Observe que dados o objeto inclui uma propriedade sys_id preenchida por entrada ou opções objetos. Se nenhum dos dois entrada nor opções inclua um sys_id, o. [SP.getParameter()](https://www.servicenow.com/docs/access?context=c_GlideSPScriptableScopedAPI&version=yokohama&pubname=yokohama-api-reference&ft:locale=en-US)o método recupera o sys_id da cadeia de caracteres de consulta da solicitação.

      Para preencher o. entrada Objeto, você pode passar um sys_id de item do catálogo do script do cliente do widget de pedido rápido.
   {#embed-widget__substeps_x34_wkc_yz}
2. Em Editor de widget , Abra o widget Pedido rápido.
3. Substitua o script do cliente do widget de pedido rápido pelo script a seguir.  

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

   Este script usa `SPUtil.get() `Para recuperar o modelo de widget por ID ( `widget-sc-cat-item `) e defina o. `(sys_id: item_id) `objeto. Este objeto é publicado no script do servidor como entrada .
4. Substitua o modelo HTML pelo seguinte script:  

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

   Este modelo:  
   * Adiciona o comportamento de clique usando a diretiva ng-click.
   * Exibe o widget de item do catálogo SC incorporado usando a diretiva sp-widget.
   {#embed-widget__ul_ygs_bsg_zz}
5. Substitua o CSS pelo seguinte script:  

       .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. Atualize a visualização da página de teste para exibir as mudanças.  
   Quando você seleciona um resultado da pesquisa, o item é aberto no widget Item do catálogo SC incorporado.

## Crie uma diretiva reutilizável e adicione-a a um widget {#ariaid-title6}

Os provedores Angular são componentes reutilizáveis que podem ser adicionados a vários widgets. Usando a tabela Provedores angulares de widget, crie uma diretiva que mostre um ícone de categoria ao lado de cada resultado no widget Pedido rápido.

### Antes de Iniciar

Função necessária: administrador ou sp_admin

### Por Que e Quando Desempenhar Esta Tarefa

Os provedores Angular permitem criar diretivas e serviços Angular que podem ser injetados no controlador de script do cliente. O código em um provedor difere de uma diretiva ou serviço Angular típico porque deve ser anônimo, sem ser anexado a um módulo específico.

### Procedimento

1. Navegar até TudoPortal de serviçosConfiguração do Portal de serviçosTabelas do PortalProvedor em Angular de Widget.  
   A tabela Provedores angulares de widget é aberta.
2. Selecione Novo para criar um novo registro.
3. Preencha o formulário.
   1. Adicione o tipo e o nome.  
      * Tipo : Diretiva
      * Nome : CategoryIcon
      {#reusable-directive__ul_tf5_rjh_xz}
   2. Adicione o client script.  

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

      Este script associa o sys_id do registro de categoria ao Catálogo de serviçositem. O ícone exibido é o ícone definido no registro de categoria no Catálogo de serviços.
   3. Selecione Salvar.
   {#reusable-directive__substeps_crw_pcd_yz}
4. Associe a nova diretiva angular ao widget de pedido rápido.
   1. Navegar até TudoPortal de serviçosWidgets.
   2. Abra o widget Pedido rápido.
   3. Em Listas relacionadas , selecione Provedores Angular .
   4. Na lista Provedores Angular, selecione Editar E associe o provedor angular categoryIcon ao widget Pedido rápido.
   5. Selecione Salvar.
   {#reusable-directive__substeps_uqt_y3d_yz}
5. Adicione a diretiva categoryIcon ao seu modelo HTML de pedido rápido.
   1. Em Editor de widget , Abra o widget Pedido rápido.
   2. Substitua o modelo HTML pelo script a seguir.  

          <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. Atualize a visualização da página de teste para exibir as mudanças.  
   Um ícone de categoria é exibido ao lado de cada resultado.


