Tutorial: criar um widget personalizado

  • Versão de lançamento: Washingtondc
  • Atualizado 1 de fev. de 2024
  • 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 de 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é Todos > Portal de serviços > Configuraçã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
      • 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 widget, abra o widget Pedido rápido.
    6. Adicione o modelo simples a seguir 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ância

    Depois de adicionar seu widget e criar um modelo básico, você pode definir scripts avançados de cliente e servidor que permitem aos usuários consultar dados de uma tabela de instância. Você pode passar o modelo de dados entre o cliente e o servidor consultando os 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 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 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-model-options Configura o comportamento do modelo ng. Neste modelo, o ng-model atualiza o modelo depois que um usuário parou 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

    Exiba 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 é 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 widget, abra o widget 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 de 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 Item do catálogo de SC é um widget do sistema básico que permite ao usuário exibir e comprar Catálogo de serviços itens.

    Procedimento

    1. Inspecione o widget Item do catálogo de SC.
      Antes de incorporar o widget Item do catálogo de SC, inspecione o widget para entender os dados aos quais ele precisa de acesso. Pode ser necessário atualizar o cliente do widget de pedido rápido ou o script 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 de 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 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 declaraçã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 widget, abra o widget 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 publica 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 de 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 de 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 em angular são componentes reutilizáveis que podem ser adicionados a vários widgets. Usando a tabela Provedores em angular do 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 diretivas 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é Todos > Portal de serviços > Configuração do Portal de serviços > Tabelas do Portal > Provedor em Angular de Widget.
      A tabela Provedores em angular do widget é aberta.
    2. Clique em 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 Categoria no Catálogo de serviços.

      3. Clique em Salvar.
    4. Associe a nova diretiva Angular ao Widget de pedido rápido.
      1. Navegue até<yourInstanceURL> /sp_config?id=widget_editor.
      2. Abra o widget de pedido rápido.
      3. Em Listas relacionadas, selecione Provedores em angular.
      4. Na lista Provedores em angular, clique em Novo para associar um provedor em angular existente ao widget de pedido rápido.
      5. Adicione os seguintes valores ao formulário.
        • Provedor em angular: categoryIcon
        • Widget: pedido rápido
      6. Clique em Salvar.
    5. Adicione a diretiva categoryIcon ao seu modelo HTML de pedido rápido.
      1. No 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>
        
    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.