Desenvolvimento de um componente baseado no editor em massa: o componente Lista de produtos
Esta seção fornece uma visão geral de como usar o editor em massa e fornece uma descrição do componente existente do Geometrixx com base no editor em massa: o componente Lista de produtos .
O componente Lista de produtos permite que os usuários exibam e editem uma tabela de dados. Por exemplo, você pode usar o componente Lista de produtos para representar produtos em um catálogo. As informações são apresentadas em uma tabela de HTML padrão e qualquer edição é executada na variável Editar , que contém um widget BulkEditor. (Esse editor em massa é exatamente o mesmo que o acessível em /etc/importers/bulkeditor.html ou pelo menu Ferramentas ). O componente Lista de produtos foi configurado para funcionalidade específica e limitada do editor em massa. Toda parte do editor em massa (ou componentes derivados do editor em massa) pode ser configurada.
Com o editor em massa, é possível adicionar, modificar, excluir, filtrar e exportar as linhas, salvar modificações e importar um conjunto de linhas. Cada linha é armazenada como um nó na própria instância do componente Lista de produtos . Cada célula é uma propriedade de cada nó. Essa é uma opção de design e pode ser facilmente alterada, por exemplo, você pode armazenar nós em outro lugar no repositório. A função do servlet de consulta é retornar a lista dos nós a serem exibidos; o caminho de pesquisa é definido como uma instância da Lista de produtos.
O código-fonte do componente Lista de produtos está disponível no repositório em /apps/geometrixx/components/productlist e é composto por várias partes, como todos os componentes do AEM:
- Renderização de HTML: a renderização é feita em um arquivo JSP (https://experienceleague.adobe.com/apps/geometrixx/components/productlist/productlist.jsp?lang=pt-BR). O JSP lê os subnós do componente Lista de produtos atual e exibe cada um deles como uma linha de uma tabela de HTML.
- Caixa de diálogo Editar, que é onde você define a configuração do Editor em massa. Configure a caixa de diálogo para atender às necessidades do componente: colunas disponíveis e possíveis ações executadas na grade ou na pesquisa. Consulte propriedades de configuração do editor em massa para obter informações sobre todas as propriedades de configuração.
Esta é uma representação XML dos subnós da caixa de diálogo:
<editor
jcr:primaryType="cq:Widget"
colsSelection="[ProductId,ProductName,Color,CatalogCode,SellingSku]"
colsValue="[ProductId,ProductName,Color,CatalogCode,SellingSku]"
contentMode="false"
exportURL="/etc/importers/bulkeditor/export.tsv"
extraCols="Selection"
hideColsSelection="false"
hideContentMode="true"
hideDeleteButton="false"
hideExportButton="false"
hideExtraCols="true"
hideImportButton="false"
hideInsertButton="false"
hideMoveButtons="false"
hidePathCol="true"
hideRootPath="true"
hideSaveButton="false"
hideSearchButton="false"
importURL="/etc/importers/bulkeditor/import"
initialSearch="true"
insertedResourceType="geometrixx/components/productlist/sku"
queryParams=""
queryURL="/etc/importers/bulkeditor/query.json"
saveURL="/etc/importers/bulkeditor/save"
xtype="bulkeditor">
<saveButton
jcr:primaryType="nt:unstructured"
text="Save modifications"/>
<searchButton
jcr:primaryType="nt:unstructured"
text="Apply filter"/>
<queryParamsInput
jcr:primaryType="nt:unstructured"
fieldDescription="Enter here your filters"
fieldLabel="Filters"/>
<searchPanel
jcr:primaryType="nt:unstructured"
height="200">
<defaults
jcr:primaryType="nt:unstructured"
labelWidth="150"/>
</searchPanel>
<grid
jcr:primaryType="nt:unstructured"
height="275"/>
<store jcr:primaryType="nt:unstructured">
<sortInfo
jcr:primaryType="nt:unstructured"
direction="ASC"
field="CatalogCode"/>
</store>
<colModel
jcr:primaryType="nt:unstructured"
width="150"/>
<colsMetadata jcr:primaryType="nt:unstructured">
<Selection
jcr:primaryType="nt:unstructured"
checkbox="true"
forcedPosition="0"
headerText=""/>
<ProductId
jcr:primaryType="nt:unstructured"
cellCls="productlist-cell-productid"
headerText="Product Id"/>
<ProductName
jcr:primaryType="nt:unstructured"
cellStyle="background-color: #FFCC99;"
headerText="Product Name"/>
<CatalogCode
jcr:primaryType="nt:unstructured"
cellStyle="background-color: #EDEDED;"
headerText="Catalog Code"/>
<Color jcr:primaryType="nt:unstructured">
<editor
jcr:primaryType="nt:unstructured"
store="[Blue,Red,Yellow]"
triggerAction="all"
typeAhead="true"
xtype="combo"/>
</Color>
<SellingSku
jcr:primaryType="nt:unstructured"
headerText="Sku Id"/>
</colsMetadata>
</editor>
Propriedades de configuração do editor em massa
Todas as partes do editor em massa podem ser configuradas. A tabela a seguir lista todas as propriedades de configuração do editor em massa.
Configuração de metadados de colunas
É possível configurar para cada coluna:
-
propriedades de exibição: estilo html, classe CSS e somente leitura
-
uma caixa de seleção
-
uma posição forçada
Colunas CSS e somente leitura
O editor em massa tem três configurações de coluna:
- Nome da classe CSS da Célula (cellCls): um nome de classe CSS adicionado a cada célula da coluna configurada.
- Estilo da célula (cellStyle): um estilo HTML adicionado a cada célula da coluna configurada.
- Somente leitura (readOnly): somente leitura é definido para cada célula da coluna configurada.
A configuração deve ser definida como a seguinte:
"colsMetadata": {
"Column name": {
"cellStyle": "html style",
"cellCls": "CSS class",
"readOnly": true/false
}
}
O exemplo a seguir pode ser encontrado no componente da lista de produtos (https://experienceleague.adobe.com/apps/geometrixx/components/productlist/dialog/items/editor/colsMetadata?lang=pt-BR):
<colsMetadata jcr:primaryType="nt:unstructured">
<Selection
jcr:primaryType="nt:unstructured"
checkbox="true"
forcedPosition="0"
headerText=""/>
<ProductId
jcr:primaryType="nt:unstructured"
cellCls="productlist-cell-productid"
headerText="Product Id"/>
<ProductName
jcr:primaryType="nt:unstructured"
cellStyle="background-color: #FFCC99;"
headerText="Product Name"/>
<CatalogCode
jcr:primaryType="nt:unstructured"
cellStyle="background-color: #EDEDED;"
headerText="Catalog Code"/>
<Color jcr:primaryType="nt:unstructured">
<editor
jcr:primaryType="nt:unstructured"
store="[Blue,Red,Yellow]"
triggerAction="all"
typeAhead="true"
xtype="combo"/>
</Color>
<SellingSku
jcr:primaryType="nt:unstructured"
headerText="Sku Id"/>
</colsMetadata>
Caixa de seleção
Se a propriedade de configuração da caixa de seleção estiver definida como true, todas as células da coluna serão renderizadas como caixas de seleção. Uma caixa marcada envia true para o servlet Save do servidor, false caso contrário. No menu de cabeçalho, também é possível selecionar tudo ou selecionar nenhum. Essas opções serão ativadas se o cabeçalho selecionado for o cabeçalho de uma coluna de caixa de seleção.
No exemplo anterior, a coluna de seleção contém apenas caixas de seleção como caixa de seleção="true".
Posição forçada
Os metadados de posição forçada forcedPosition permitem especificar onde a coluna é colocada na grade: 0 é o primeiro lugar e <number of="" columns="">-1 é a última posição. Qualquer outro valor será ignorado.
No exemplo anterior, a coluna de seleção é a primeira coluna como forcedPosition="0".
Servlet de consulta
Por padrão, o servlet Query pode ser encontrado em /libs/wcm/core/components/bulkeditor/json.java
. Você pode configurar outro caminho para recuperar os dados.
O servlet Query funciona da seguinte maneira: recebe uma consulta GQL e as colunas a serem retornadas, calcula os resultados e envia os resultados para o editor em massa como um fluxo JSON.
No caso do componente Lista de produtos , os dois parâmetros enviados para o servlet Consulta são os seguintes:
- query: "path:/content/geometrixx/en/customers/jcr:content/par/productlist Cube"
- cols: "Selection,ProductId,ProductName,Color,CatalogCode,SellingSku"
e o fluxo JSON retornado é o seguinte:
{
"hits": [{
"jcr:path": "/content/geometrixx/en/products/jcr:content/par/productlist/1258674828905",
"ProductId": "21",
"ProductName": "Cube",
"Color": "Blue",
"CatalogCode": "43244",
"SellingSku": "32131"
}
],
"results": 1
}
Cada ocorrência corresponde a um nó e suas propriedades, e é exibida como uma linha na grade.
Você pode estender o servlet Query para retornar um modelo de herança complexo ou nós de retorno armazenados em um local lógico específico. O servlet Query pode ser usado para fazer qualquer tipo de computação complexa. A grade pode então exibir linhas que são uma agregação de vários nós no repositório. A modificação e o salvamento dessas linhas devem, nesse caso, ser gerenciadas pelo Servlet Salvar.
Salvar servlet
Na configuração padrão do editor em massa, cada linha é um nó e o caminho desse nó é armazenado no registro de linha. O editor em massa mantém o link entre a linha e o nó pelo caminho jcr. Quando um usuário edita a grade, uma lista de todas as modificações é criada. Quando um usuário clica em Salvar, uma consulta POST é enviada para cada caminho com os valores de propriedades atualizados. Essa é a base do conceito do Sling e funciona bem se cada célula for uma propriedade do nó. Mas se o servlet Query estiver implementado para fazer o cálculo de herança, esse modelo não poderá funcionar como uma propriedade retornada pelo servlet Query pode ser herdada de outro nó.
O conceito de servlet Save é que as modificações não são publicadas diretamente em cada nó, mas são publicadas em um servlet que faz o trabalho de salvamento. Isso dá a esse servlet a possibilidade de analisar as modificações e salvar as propriedades no nó direito.
Cada propriedade atualizada é enviada para o servlet no seguinte formato:
-
Nome do parâmetro: <jcr path="">/<property name="">
Exemplo: /content/geometrixx/en/products/jcr:content/par/productlist/1258674859000/SellingSku
-
Valor: <value>
Exemplo: 12123
O servlet precisa saber onde a propriedade catalogCode é armazenada.
Uma implementação padrão Salvar servlet está disponível em /libs/wcm/bulkeditor/save/POST.jsp e é usada no componente Lista de produtos . Leva todos os parâmetros da solicitação (com um <jcr path="">/<property name=""> ) e grava propriedades em nós usando a API JCR. Ele também cria um nó se eles não existirem (linhas inseridas na grade).
O código padrão não deve ser usado como está, pois reimplementa o que o servidor faz nativamente (um POST on <jcr path="">/<property name="">) e, portanto, é apenas um bom ponto de partida para criar um servlet Save que gerenciará um modelo de herança de propriedade.