Tutorial: criar um widget personalizado

  • Versão de lançamento: Yokohama
  • Atualizado 30 de jan. de 2025
  • 10 min. de leitura
  • Siga este tutorial para criar um widget personalizado que exibe Catálogo de serviços itens. Use este tutorial como um modelo para ajudá-lo a entender o poder de script avançado do Portal de serviços.

    Neste tutorial, você criará o widget de pedido rápido. Este widget:
    • Exibe itens populares para o usuário antes de qualquer pesquisa.
    • Consulta o Catálogo de serviços e 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 de pedido rápido.
    • Usa um provedor angular para exibir um ícone de categoria ao lado de cada item consultado.

    Criar um widget e configurar um modelo

    Crie o widget de 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é Tudo > Portal de serviços > Configuração do Portal de serviços e clique em Editor de widgets.
    2. Clique em Criar um novo widget.
    3. Defina os seguintes valores.
      • Nome do Widget: Pedido rápido
      • ID do widget: quick_order
      • Criar uma página de teste: Ativo
      • ID da página: quick_order

      Adicionar um widget a uma página de teste cria um registro em cada uma das seguintes tabelas:

      • sp_page
      • sp_container
      • sp_linha
      • sp_column
      • sp_instance
      • sp_widget
      Nota:
      Você pode usar o Editor de páginas na Configuração do Portal de serviços para exibir a hierarquia de elementos na página de teste.
    4. Clique em Enviar.
    5. No Editor de widgets, abra o widget de 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 o seguinte URL:<yourInstanceUrl> /sp?id=quick_order.

      Seu modelo de widget é exibido na página de teste.

      Renderização de widget em uma página

    Adicionar um script de servidor para consultar uma tabela de instâncias

    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. No Editor de widgets, abra o widget de 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 angulares. Para saber mais sobre essas diretivas, revise a Referência de API angular.

      Tabela 1. Diretivas angulares usadas no modelo
      Diretiva angular Descrição
      ng-model Lê e grava automaticamente mudanças de valor na variável do modelo c.data.keywords.
      ng-modelo-opções Configura o comportamento do ng-model. Neste modelo, o ng-model atualiza o modelo depois que um usuário para de digitar por 250 milissegundos.
      ng-mudança Executa c.server.update() depois que o valor do modelo muda. Esta função publica o objeto de dados no script do servidor. Depois que o script é executado, o objeto de dados é atualizado automaticamente com os novos valores do objeto de dados gerado pelo servidor.
      ng-repetir 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ídas pelos valores de cada item.
    5. Adicione o seguinte script ao campo CSS - SCSS :
      .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 por ipad.

      A pesquisa exibe resultados para o iPad.

    Gerenciar o estado vazio de um widget

    Exibir uma lista de itens populares para o usuário antes que qualquer termo de pesquisa seja inserido.

    Antes de Iniciar

    Função necessária: administrador ou sp_admin

    Por Que e Quando Desempenhar Esta Tarefa

    Como nenhuma pesquisa foi executada quando o widget foi inicializado, a variável de entrada do servidor é indefinida. Este estado vazio pode causar confusão quando um usuário interage pela primeira vez com o widget. Para resolver esse problema, forneça ao widget algo para exibir quando a variável de entrada estiver vazia. Esses dados iniciais podem orientar os usuários na interação inicial com o widget.

    Procedimento

    1. No Editor de widgets, abra o widget de Pedido rápido.
    2. Substitua o script do 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 apresenta uma nova função getPopularItems() para consultar o banco de dados e retornar itens populares quando a variável de entrada estiver 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.

      Uma caixa de pesquisa com o texto "Comece a digitar aqui para pesquisar a lista de itens do catálogo".

    Incorporar um widget existente

    Habilite o usuário a exibir e comprar Catálogo de serviços itens no widget de 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 base que permite ao usuário exibir e comprar Catálogo de serviços itens.

    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 a quais dados ele precisa de acesso. Pode ser necessário atualizar o script de cliente ou servidor do widget de pedido rápido para garantir que os dados corretos sejam passados para o widget incorporado.
      1. Navegar 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 client script.
      4. Examine o script do servidor.

        Observe que o objeto de dados inclui uma propriedade sys_id preenchida pelos objetos de entrada ou de opções. Se nem a entrada nem as opções incluírem um sys_id, o método $sp.getParameter() recuperará o sys_id da cadeia de caracteres de consulta da solicitação.

        Exemplo de script de servidor usando uma instrução If Else para recuperar o sys_id.

        Para preencher o objeto de entrada, você pode passar um sys_id de item do catálogo do client script do widget de pedido rápido.

    2. No Editor de widgets, abra o widget de Pedido rápido.
    3. Substitua o client script 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 definir o objeto {sys_id: item_id}. 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 ao clicar usando a diretiva ng-click.
      • Exibe o widget de Item do catálogo SC incorporado usando a diretiva sp-widget.
    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 de pesquisa, o item é aberto no widget de item do catálogo SC incorporado.

      Página de teste mostrando um item selecionado exibido em um widget incorporado.

    Criar uma diretiva reutilizável e adicioná-la a um widget

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

    Antes de Iniciar

    Função necessária: administrador ou sp_admin

    Por Que e Quando Desempenhar Esta Tarefa

    Os provedores angulares permitem criar diretrizes e serviços angulares que podem ser injetados no controlador de client script. 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é Tudo > Portal de serviços > Configuração do Portal de serviços > Tabelas do Portal > Provedor 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
      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 item Catálogo de serviços. O ícone exibido é o ícone definido no registro de Categoria no Catálogo de serviços.

      3. Selecione Save (Salvar).
    4. Associe a nova diretiva angular ao widget de pedido rápido.
      1. Navegar até Tudo > Portal de serviços > Widgets.
      2. Abra o widget de Pedido rápido.
      3. Em Listas relacionadas, selecione Provedores angulares.
      4. Na lista Provedores angulares, selecione Editar e associe o provedor angular categoryIcon ao widget de pedido rápido.
      5. Selecione Save (Salvar).
    5. Adicione a diretiva categoryIcon ao seu modelo HTML de pedido rápido.
      1. No Editor de widgets, abra o widget de 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>
        
    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.