Semi automatização de preenchimento de dialogs no AEM
Tags: aem, automation, javascript, jquery
Published: 2023-09-13 13:17:57

Autoração de conteúdo de páginas pode ser uma das tarefas mais desestimulantes para desenvolvedores. Neste artigo buscarei explicar um exemplo de semi automatização para facilitar este processo. Devido à particularidades do editor do AEM, uma automatização completa não foi possível, mas esta solução está aberta a contribuições!
Essa solução foi construída em parceria com [Felipe Martins](linkedin.com/in/felipe-martins-maria-29041994).

### Campos de Preenchimento

Os campos a serem preenchidos estavam dentro de um multifield sem limite de elementos, e cada elemento contava com:
- Textfield
- Pathfield
- Menu dropdown com duas opções

A dialog que usamos de exemplo para preenchimento é a seguinte:

![Dialog modelo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qlh165evr5gvrbtnnun1.png)

Cada campo tem um comportamento diferente para ser preenchido. É importante salientar que o pathfield recebia um path de arquivo do DAM do próprio AEM.

### Desenvolvimento da solução

Neste caso, precisamos fazer duas listas com as opções a serem completadas. Os elementos precisam ser inseridos um a um, como o exemplo a seguir:

```
var links = ["/content/website/language-masters/en/home/arquivo01.pdf",
"/content/website/language-masters/en/home/arquivo02.pdf",
"/content/website/language-masters/en/home/arquivo03.pdf"]

var idsLinks = ["Arquivo 01","Arquivo 02","Arquivo 03"]
```

Neste exemplo temos três elementos, o primeiro link fará par com o primeiro idLink e assim sucessivamente.

#### ✏️ Textfield

Como o editor do AEM conta com um HTML próprio, vamos utilizar as classes e ids já existentes nessa estrutura para acessar o campo de Textfield. Nesse caso, encontramos a única ocorrência de uma tag "mãe" e vamos acessar a classe correta na hierarquia para modificação.
Foi importante identificar uma classe única para que a função não se perdesse e pudesse encontrar mais de uma opção de modificação. Dessa forma, encontramos a classe `coral-Well`, que será a "mãe", enquanto e desceremos algumas tags até encontrarmos o campo de inserção de texto para popular o nosso textfield. Dessa forma:

```
$(".coral-Well div div.coral-Form-fieldwrapper:eq(0) input")[0].value = idsLinks[i];
```

A [função eq()](https://api.jquery.com/eq/) serve para identificar a posição do elemento. Usamos `value` para adicionar o valor do índice correto, buscando-o na nossa lista `idsLinks`.

#### ✏️ Pathfield

Para popular o pathfield com conteúdo do DAM do AEM, utilizamos a função [attr()](http://api.jquery.com/attr/). É importante que o path esteja completo, desde `/content...` até a propriedade do arquivo (no nosso caso, `.../arquivo01.pdf`).
O número de índice do `eq()` mudou porque os campos da dialog do AEM tem o mesmo nome (`.coral-Form-fieldwrapper`), e precisamos especificar qual dessas filhas de `.coral-Well` queremos.

```
$("div.coral-Well div div.coral-Form-fieldwrapper:eq(1) foundation-autocomplete coral-taglist coral-tag").attr("value",links[numeral]);
```

⚠️ *Atenção* : Essa forma de preenchimento do pathfield não popula o campo de dialog do AEM visualmente, é necessário salvar as alterações para que o path entre corretamente.

#### ✏️ Menu dropdown

Usamos a mesma lógica hierárquica para acessarmos nossa tag e/ou nossa classe desejada. A diferença de um seletor é que usaremos a função `click` ao invés de popularmos com algum tipo de texto.

```
$(".coral-Well div div.coral-Form-fieldwrapper:eq(2) coral-select coral-overlay coral-selectlist coral-selectlist-item")[1].click();
```

Também utilizamos a posição `[1]` para especificar que queremos selecionar a segunda opção que apareça ao abrir o dropdown.

### Montando a função

Agora que desmembramos os campos e definimos suas especificidades, devemos aplicar todas essas ações em uma função e aplicar um índice que vai ser sempre modificado, porque a partir do momento que preenchermos um bloco de campos de um elementos, deveremos passar para o próximo. Por isso, vamos abraçar as funcionalidades dentro da função `preencheCampos()`.

Além disso, precisamos de um índice para iteração, que vamos chamar de `numeral`

⚠️ *Atenção* : é importante evitarmos usar índices com letras, como tradicionalmente usamos (`i`, `z`, entre outros), porque o editor do AEM guarda arquivos minificados que trabalham com variáveis com estes nomes. Então é sempre bom escolher uma variável de nome mais específico, para não ser alterado pelo próprio AEM.

Este `numeral` será importante para posicionarmos os campos, ele funciona na iteração como o tradicional `i`, e se certifica que estamos seguindo o array na ordem certa, enquanto o índice for menor do que `idsLinks.length` (mas poderia ser menor do que `links.length`, também, uma vez que eles têm a mesma quantidade de elementos e fazem duplas entre si).

Para adicioná-lo, também vamos usar a função `eq()` associada à classe única (.coral-Well), dessa forma:

```
$(".coral-Well:eq(" + numeral + ") div div.coral-Form-fieldwrapper:eq(0) input")[0].value = idsLinks[numeral];
```

Também será necessário um segundo índice para o click no botão de `Add`, porque o mesmo botão muda de posição de acordo com a quantidade de elementos que inserimos no multifield. Logo, teremos que iterá-lo com + 2 posições, dessa forma:

```
$(".coral-Form-fieldwrapper coral-multifield button.coral3-Button.coral3-Button--secondary")[numeralAdd].click();
numeralAdd+=2;
```

Por fim, montando todas essas partes, podemos finalmente construir uma função de preenchimento de campos, lembrando que é necessário atribuirmos o valor de 0 para o índice `numeral` e 2 para o índice `numeralAdd`, para que caminhe de dois em dois.

```
numeral = 0;
numeralAdd = 2;
```

A função fica assim, então:

```
function preencheCampos(){
	console.log("Criando link do index " + numeral + ". ID " + idsLinks[numeral]);
	// Popula o textfield
	$(".coral-Well:eq(" + numeral + ") div div.coral-Form-fieldwrapper:eq(0) input")[0].value = idsLinks[numeral];
	
	// Define o pathfield
	$("div.coral-Well:eq(" + numeral + ") div div.coral-Form-fieldwrapper:eq(1) foundation-autocomplete coral-taglist coral-tag").attr("value",links[numeral]);

	// Seleciona uma opção no menu dropdown
	$(".coral-Well:eq(" + numeral + ") div div.coral-Form-fieldwrapper:eq(2) coral-select coral-overlay coral-selectlist coral-selectlist-item")[1].click();

	numeral++;
	// Clica no botão de add para adicionar um novo elemento
	if(numeral < idsLinks.length)
		$(".coral-Form-fieldwrapper coral-multifield button.coral3-Button.coral3-Button--secondary")[numeralAdd].click();
	else
		alert("Fim");
	numeralAdd+=2;
}
```

### Por que semi automatizado?

O editor do AEM pode ficar pesado com um loop de preenchimento e as tentativas de funções para automatizar de forma integral não foram bem sucedidas. Deixo esse tópico aberto à contribuições para pensar em formas de preenchimento de dialog de forma totalmente automatizada.