# Manual de Customização

# Segurança e Acesso

O menu de Segurança e Acesso, é o local onde se criam usuários e onde é definido as permissões de acesso.

# Usuário

É onde são criadas as contas para acesso ao sistema. Cada usuário tem suas informações divididos em 3 grupos:

#### Dados Pessoais

[![usuario_dados_pessoais.png](http://wiki.agilityflow.io/uploads/images/gallery/2019-01-Jan/scaled-840-0/usuario_dados_pessoais.png)](http://wiki.agilityflow.io/uploads/images/gallery/2019-01-Jan/usuario_dados_pessoais.png)

São os campos tais como nome, e-mail, data de nascimento, sexo e foto. Além disso, também é possível definir o usuário gestor.

##### Usuário Gestor

Esse usuário servirá para os casos de uma etapa em um fluxo de trabalho, ter como regra a aprovação do gestor do usuário da etapa anterior.

<p class="callout info">Por exemplo: em um fluxo de solicitação de reembolso, a primeira etapa é o cadastro da despesa para reembolso. A segunda etapa, pode ter como aprovador o gestor do usuário da primeira etapa. É exatamente o usuário informado no campo usuário gestor, que será usado nesse momento como o aprovador da etapa. Na prática, serviria para um funcionário solicitar o reembolso de uma despesa e essa solicitação, antes de ir para o financeiro, passasse pelo crivo do gestor desse funcionário.</p>

#### Dados de Acesso

[![usuario_dados_de_acesso.png](http://wiki.agilityflow.io/uploads/images/gallery/2019-01-Jan/scaled-840-0/usuario_dados_de_acesso.png)](http://wiki.agilityflow.io/uploads/images/gallery/2019-01-Jan/usuario_dados_de_acesso.png)

Aqui é definido o nome do usuário e a senha. Além disso, define-se aqui se conta está ativa ou não. Essa função, serve para desativar futuramente uma conta, sem precisar removê-la, podendo reativar a qualquer momento.

##### Perfil

Perfil é um conjunto de funcionalidades que esse usuário terá acesso. Para maiores detalhes, consulte a página de [configuração de perfil](http://wiki.agilityflow.io/books/manual-do-desenvolvedor/page/perfil-de-acesso) desse manual.

<span style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Oxygen, Ubuntu, Roboto, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400;">Para atribuir um perfil a um usuário, basta selecionar o perfil desejado na lista de seleção e clicar no botão </span>[![image-1549032455512.png](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/scaled-840-0/image-1549032455512.png)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/image-1549032455512.png)<span style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Oxygen, Ubuntu, Roboto, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400;">.</span>

<p class="callout info">É possível atribuir mais de um perfil por usuário.</p>

#### Grupo de usuários

[![usuario_grupo_de_usuario.png](http://wiki.agilityflow.io/uploads/images/gallery/2019-01-Jan/scaled-840-0/usuario_grupo_de_usuario.png)](http://wiki.agilityflow.io/uploads/images/gallery/2019-01-Jan/usuario_grupo_de_usuario.png)

Grupo de usuários é um conjunto de outros usuários ao qual esse usuário vai pertencer. Para maiores detalhes, consulte a página de [configuração grupos de usuário](http://wiki.agilityflow.io/books/manual-do-desenvolvedor/page/grupo-de-usu%C3%A1rio) desse manual.

<p class="callout warning"><span style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Oxygen, Ubuntu, Roboto, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400;">Um usuário, pode pertencer a </span>*n*<span style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Oxygen, Ubuntu, Roboto, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400;"> grupos de usuário.</span></p>

### Excluindo um usuário

Para excluir basta entrar na lista de Usuário, no menu Segurança e Acesso, localizado na barra vertical, selecionar um ou mais usuários, e em seguida, clicar no ícone [![Ícone_excluir.png](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/scaled-840-0/%C3%8Dcone_excluir.png)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/%C3%8Dcone_excluir.png). Note que esse ícone fica inativo caso não haja nenhum usuário selecionado.

Outra forma, é clicando em um dos usuários. Quando isso é feito, abre-se os detalhes do usuário. O ícone de exclusão também encontra-se nessa tela.

<p class="callout danger">Ao excluir um usuário, você não pode mais recuperar a conta excluída. Caso você acredite que essa conta será utilizada novamente no futuro, você pode desativá-la, mudando o campo "ativo" nas configurações do usuário.</p>

# Perfil de Acesso

O perfil de acesso é o nome que se dá no agility**flow**, a um grupo de funcionalidades e permissões que um usuário pode ter.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-05-May/scaled-840-0/image-1557171018826.png)

Nessa tela, é possível definir o nome do perfil, e ainda associar usuários a ele.

<p class="callout success">O campo "Código(ID)" é preenchido automaticamente pelo sistema.</p>

#### Funcionalidades

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-01-Jan/scaled-840-0/image-1548955439565.png)

Primeiro, é necessário definir o tipo de funcionalidade. São duas opções:

- [Formulário](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/chapter/formul%C3%A1rios)
- [Report](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/report)

Ao selecionar uma dessas opções, o campo Funcionalidade é habilitado com as opções referentes ao tipo escolhido.

Feito isso, as funções vão aparecer para serem configuradas. Todas elas tem como opção para configuração, as opções Sim e Não. Para [Report](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/report) a única opção disponível é *"Pode Visualizar o Report?"*.

Para os [formulários](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/chapter/formul%C3%A1rios), mais opções estão disponíveis:

- Cadastrar
- Consultar
- Imprimir
- Editar
- Exportar Excel

<p class="callout warning">Sempre ao criar um formulário novo, não se esqueça de adicionar ele aos perfis que devem acessá-lo.</p>

#### Permite criar Board/Kanban

Caso marcado, os usuários associados a esse perfil poderão criar [quadros (kanban)](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/quadros-%28kanban%29 "Quadros (Kanban)") para os formulários.

#### Dashboards para esse perfil

Nessa opção, é possível associar dashboards para serem visualizados por esse perfil de usuário. Isso significa, que todos os dashboards aqui associados ficarão disponíveis para serem acessados por esse usuário.

#### Perfil com acesso TOTAL ao agilityflow

##### "<span style="text-decoration: underline;">Master</span>"

Esse perfil concede acesso completo e irrestrito a plataforma. Tipicamente, pouquíssimos usuários devem ter esse perfil.

# Grupo de Usuário

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-01-Jan/scaled-840-0/image-1548955979832.png)

É a forma que se tem de agrupar usuários para serem utilizados em uma determinada ação no seu fluxo e/ou processo. Essa opção é útil para agrupar usuários com diferentes níveis, qualificações ou perfis de acesso. Com isso, é possível que algumas funções do Agilityflow sejam disponibilizadas a esse grupo específico, e não a todo um perfil, por exemplo.

#### Exemplo de utilização:

Suponhamos que dentro da sua empresa tenha um projeto temporário chamado **Projeto X**, e que <span style="text-decoration: underline;">apenas</span> as pessoas que fazem parte desse projeto possam solicitar reembolso de jantar e transporte. Sendo que o Gestor seja o responsável por aprovar esse reembolso.

<p class="callout warning">Para esse exemplo estamos supondo que você ainda não possua um formulário para solicitação de reembolso</p>

1. Passo 1: Criar o grupo de usuários **"Projeto X"**: 
    - No menu, entre em **Segurança e Acesso** &gt; **Grupo de usuário.** Clique na opção **Novo.**
    - Preencha o formulário de Grupo de usuário sendo o nome "**Projeto X**", e no campo Usuário associe todos os usuários participantes desse projeto, depois clique em **Salvar.**
2. Passo 2: Criar o formulário para o usuário cadastrar a "**Solicitação de Reembolso**": 
    - No menu, entre em **Customizar Agilityflow** &gt; **Formulário.** Clique na opção **Novo Formulário.**
    - Crie um formulário do tipo "**Formulário com fluxo de etapas**" e o nome "**Solicitação de reembolso**".
    - Na aba "**Etapas do Fluxo**" crie 1 etapa chamada "**Aprovação de reembolso**".
    - Dentro de **"Etapas do Fluxo"** vá até a aba "**Usuários com permissão para cadastrar (Etapa Inicial)",** clique em **"Grupo de usuário"**  e no combo que aparecerá selecione o grupo **"Projeto X",** clique em **"Adicionar".**
    - Vá até a aba "**Responsáveis da Etapa",** clique na etapa que você criou **"Aprovação de reembolso",** e selecione **"O gestor do aprovador da etapa X"**
    - Agora termine a construção do formulário com os campos que você achar necessário, isso é, na aba "**Formulário",** defina os campos que precisarão ser preenchidos na solicitação de reembolso e logo em seguida monte a tela. Na aba "**Lista e consulta**" selecione os campos que deverão fazer parte da lista e da ordenação da lista.
    - Agora clique em "**Salvar e publicar**"
    - Pronto!

Você acaba de definir que apenas os usuário que fazem parte do **Projeto X**, conseguirão cadastrar uma nova **"Solicitação de reembolso"**  (definição feita no passo 5 acima). O único pré-requisito é que o perfil do usuário dê acesso a esse formulário "**Solicitação de Reembolso**" que criamos.

# Single Sign-On - Configurar integração com o AD (Active Directory)

<div id="bkmrk-"></div>Para acessar os detalhes desse conteúdo, [clique aqui.](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/single-sign-on---configurar-integra%C3%A7%C3%A3o-com-o-ad-%28active-directory%29)

# Single Sign-On - Configurar a integração com o ADFS (Active Directory Federation Services)

Para acessar os detalhes desse conteúdo, [clique aqui.](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/como-configurar-a-integra%C3%A7%C3%A3o-com-o-adfs "Como configurar a integração com o ADFS")

# Formulários

Tudo o que você precisa saber sobre formulários no agilityflow.

# Introdução

Os formulários têm uma importância única no agility**flow**. É através dele, que informações serão inseridas no sistema. A partir daí, serão gerados fluxos de trabalho, os gráficos no dashboard, os relatórios e muito mais.

Para isso, basta clicar no ícone do Devcenter [![image-1549032010112.png](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/scaled-840-0/image-1549032010112.png)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/image-1549032010112.png) localizado na Barra Vertical, e em seguida em Menu.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/scaled-840-0/image-1549035143345.png)

  
Ao clicar em "Consultar" [![image-1549032435961.png](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/scaled-840-0/image-1549032435961.png)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/image-1549032435961.png), é possível ver a lista de menus já existentes.

Clicando em "Novo Menu" [![image-1549032455512.png](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/scaled-840-0/image-1549032455512.png)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/image-1549032455512.png), o usuário irá criar um novo Menu na Barra Vertical.

Ao criar um novo formulário, será necessário definir uma série de informações, que darão a característica desejada a esse formulário.

#### Formulários Nativos

Os formulários nativos são formulários que o agilityflow trás por padrão. Como por exemplo, o formulário de cadastro de usuários. Essa parte do sistema também é construída usando o agilityflow.

Os fomulários nativos vem por padrão ocultados no [devcenter](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/chapter/devcenter "Devcenter"). Para listá-los, basta clicar na opção "Mostrar formulários nativos do Agilityflow" na tela de consulta dos formulários.

<p class="callout info">Os formulários nativos são marcados com uma etiqueta, para fácil identificação.</p>

Os formulários nativos, são formulários que existem no agilityflow e servem para a utilização do sistema. Por exemplo ao criar um usuário, é utilizado um formulário nativo para a obtenção dos dados do usuário.

# Definição Básica

Nessa aba você configura as informações gerais da estrutura do seu formulário ou fluxo.

Abaixo detalhamos essas configurações.

Os campos **Nome** e **ícone**, são as primeiras definições na criação de um novo formulário.

Abaixo, um vídeo explicando como alterar o ícone de um formulário.

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="425" src="https://player.vimeo.com/video/327351674" width="760"></iframe>

Uma definição importante, é o tipo do formulário. São dois os tipos disponíveis:

#### Tipos de Formulário

##### Formulário simples

É um formulário usado para cadastro e armazenagem de informações.

##### Formulário com fluxo de etapas

É um formulário também usado para cadastro e armazenagem de informações. Porém, baseado nessas informações, é criado um fluxo de trabalho onde pode se definir etapas de aprovação e interação entre usuários do sistema. Para mais detalhes sobre esse tipo de formulário, consulte o capítulo [Formulário com Fluxo de Etapas](http://wiki.agilityflow.io/books/manual-b%C3%A1sico-de-customiza%C3%A7%C3%A3o/page/formul%C3%A1rio-com-fluxo-de-etapas).

O campo Descrição, permite que o usuário defina uma breve explicação sobre aquele formulário.

Na opção Menu, é possível mostrar ou não esse formulário em algum Menu. O Menu principal, mostra esse formulário da [Barra de Menu Vertical](http://wiki.agilityflow.io/books/manual-do-usu%C3%A1rio/page/barra-vertical-menu-principal "Barra Vertical / Menu Principal") do agility**flow**. Além disso, é possível usar um dos submenus já disponíveis, ou ainda, [criar um novo Menu](http://wiki.agilityflow.io/books/manual-b%C3%A1sico-de-customiza%C3%A7%C3%A3o/page/menu "Menu").

<p class="callout warning">Caso você queira criar um novo menu, você deve criá-lo antes de criar o formulário, para que esse menu esteja disponível nesse campo.</p>

#### Janela do formulário

É possível também, definir a forma como esse formulário vai abrir. São 3 formas:

[![janela_formulario.gif](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/janela_formulario.gif)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/janela_formulario.gif)

##### Lightbox

É uma janela secundária sobreposta a uma janela principal, sem a criação de uma nova guia ou nova janela. Ao escolher essa opção, você também pode definir o tamanho do lightbox: fullscreen, grande, médio ou pequeno.

##### Na mesma página

Abre o formulário inteiro, na janela atual.

##### Uma nova aba do navegador

Abre o formulário inteiro, em uma nova janela.

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="425" src="https://player.vimeo.com/video/332437464" width="760"></iframe>

#### Relacionamento com outros formulários

Nesse ponto, se define a possibilidade desse formulário ser incluído como um [formulário relacionado](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/formul%C3%A1rios-relacionados "Formulários Relacionados") a outro formulário.

##### Pode ser usado como tabela filha de um outro formulário (Tabela de Formulário Relacionado)

Ao marcar essa opção, esse formulário fica habilitado a ser incluído dentro de outros formulários.

##### Abrir apenas através de um formulário pai

A opção "Abrir apenas através de um formulário pai", inibe que esse formulário seja aberto da maneira convencional, permitindo apenas que ele seja aberto através de outro formulário.

### Dados Técnicos

Esse é o nome da tabela que será gerado no banco de dados. Esse é o nome que será usado depois para a criação de [relatórios](http://wiki.agilityflow.io/books/manual-do-usu%C3%A1rio/page/relat%C3%B3rios "Relatórios") e [dashboards](http://wiki.agilityflow.io/books/manual-do-usu%C3%A1rio/page/dashboards "Dashboards"). Normalmente, não é necessário alterar o nome que o sistema sugere.

# Formulário com fluxo de etapas

O formulário com fluxo de etapas, possui todas as características de um [formulário](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/chapter/formul%C3%A1rios "Formulários") comum. Todas as propriedades, características, campos e etc estão presentes em um fluxo com etapas.

Para entender melhor o seu funcionamento, consulte o capítulo [Formulário com fluxo de etapas](http://wiki.agilityflow.io/books/manual-do-usu%C3%A1rio/page/formul%C3%A1rio-com-fluxo-de-etapas "Formulário com fluxo de etapas") no [manual do usuário](http://wiki.agilityflow.io/books/manual-do-usu%C3%A1rio "Manual do Usuário").

A criação de um formulário com etapas segue os mesmos princípios da criação de um [formulário](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/chapter/formul%C3%A1rios "Formulários") comum. Abaixo, as diferenças.

### Definição Básica

Deve-se primeiro marcar a opção formulário com fluxo de etapas, dentro dos dados básicos, na aba Definição Básica. Quando isso é feito, a aba para configuração das etapas "Etapas do Fluxo" é habilitada.

### Etapas do Fluxo

Nesse ponto definimos as etapas do fluxo que esse formulário terá.

> O que são etapas de um fluxo?

Etapas, são pontos de edição/revisão/inclusão de dados de um formulário. Em cada etapa, além de se modificar o formulário, há uma ação necessária a ser executada por um ou mais usuários definidos. As ações são: aprovar, retornar etapa ou reprovar.

Em qualquer fluxo, a primeira etapa é criada automaticamente pelo agilityflow. É a "Etapa inicial (cadastro)". Essa etapa é fixa e não é possível alterar.

Nesse ponto, é possível adicionar novas etapas. Ao clicar em "Adicionar Etapa", o usuário define o nome da etapa e o número máximo de dias que essa etapa tem para ser aprovada. Nessa tela também, é possível reordenar as etapas. Para isso, basta clicar no ícone [![image-1551235146917.png](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/scaled-840-0/image-1551235146917.png)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/image-1551235146917.png) e arrastar a etapa para a posição desejada.

> O que acontece com o histórico se eu removo uma etapa?

Qualquer fluxo já encerrado ou em andamento, não serão alterados e não terão o histórico afetado. Apenas os novos cadastrados a partir daquela data, é que terão seu comportamento modificado.

O mesmo acontece quando se altera o nome de uma etapa ou a ordem é modificada. Nada acontece com os fluxos encerrados ou em andamento. Apenas os novos são impactados.

### Usuários com permissão para cadastrar (Etapa Inicial)

É onde são definidos os usuários que podem criar um novo registro e iniciar um novo fluxo.

Esses usuários podem ser adicionados individualmente, procurando pelo nome. Ao ser encontrado a conta do usuário desejada, clica-se em adicionar. O usuário entra na lista abaixo. Clicando no ícone ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/scaled-840-0/image-1551373040695.png), é possível remover a conta da lista.

A mesma mecânica funciona para adicionar múltiplos usuários, usando o perfil de usuário ou grupo. Ao selecionar o perfil (ou grupo) desejado, todos os usuários associados estarão autorizados a fazer o cadastro.

### Responsáveis da etapa

Provavelmente, a parte mais importante da definição de um fluxo de etapa, são os responsáveis por cada uma delas. Na prática, são as pessoas que garantirão que o processo controlado por esse fluxo, cumpram todos os requerimentos e entregue um resultado satisfatório, livre de erros e retrabalhos.

Para cada etapa, é preciso escolher os responsáveis pela aprovação. Isso pode ocorrer de duas formas:

#### Aprovação não dinâmica

É a opção padrão. Nela é necessário definir um aprovador, que pode ser de dois tipos.

##### A partir de uma lista pré-definida

Funciona da mesma forma que escolha dos [usuários com permissão para cadastrar a etapa inicial](#bkmrk-%E2%A0-4).

##### O gestor do aprovador da etapa X

Todo usuário pode possuir um [gestor](http://wiki.agilityflow.io/link/3#bkmrk-usu%E3%A1rio-gestor) cadastrado no seu usuário. É esse usuário que será o aprovador. Escolhendo essa opção, deverá também ser escolhida a etapa da qual seu responsável, terá seu gestor como responsável dessa etapa.

#### Aprovação dinâmica

Para que ocorra uma aprovação dinâmica, é necessário que se configurem regras. É possível existir mais de uma regra.

Cada regra tem um nome e uma descrição, que são textos escolhidos pelo usuário. Além disso, essa regra pode ser de dois tipos:

##### Condicional

Na regra condicional, uma determinada situação deve estar presente. São dois tipos de condição:

- Se o campo: qualquer campo do formulário pode ser escolhido e ser comparado com um valor fixo definido pelo usuário. Essa comparação pode ser igual, maior ou igual, menor ou igual, maior que, menor que, diferente de, conter ou não conter;
- Se o usuário: qualquer usuário do sistema pode ser escolhido e ser comparado (aprovou ou não aprovou) a uma etapa.

Para qualquer uma das regras, podem se adicionar mais condições.

Caso a condição se estabeleça, é necessário definir um método de aprovação:

- Aprovação automática: o fluxo é aprovado sem que nenhum usuário tenha que realizar uma ação no sistema;
- Não é automática (definir aprovadores): é necessário selecionar os aprovadores, assim como é feito na aprovação não dinâmica.

<p class="callout warning">É importante definir a regra e a regra contrária. Por exemplo, caso se queira que haja uma aprovação automática quando o campo Valor for menor que 100, além dessa regra, é necessário criar a regra para quando o campo Valor for igual ou maior que 100.</p>

##### Definida pelo aprovador

Há dois campos para ser preenchidos:

- O aprovador da etapa: escolhe-se o uma das etapas do fluxo. Isso servirá como base para a configuração do campo ação.
- Ação: 
    - Aprovará esta etapa também: o mesmo aprovador da etapa escolhida acima, aprovará essa também
    - Define o aprovador dessa etapa através da lista pré-definida abaixo: escolhe-se os usuários que estarão disponíveis para serem selecionados pelo aprovador da etapa "X", definida no passo anterior.

### Permissões de acesso

Nesse ponto, é possível definir quais processos os usuários podem visualizar:

#### Sim, o usuário pode visualizar APENAS os fluxos que participou

O usuário visualiza apenas os fluxos em que ele esteja envolvido, seja cadastrando o registro ou participando de alguma etapa do fluxo.

#### Não, o usuário pode visualizar TODOS os fluxos, incluindo os que não participou

O usuário visualiza todos os registros dos formulários, independente da sua participação ou não do fluxo.

# Divisão e agrupamento dos campos

É possível criar um grupo de informações para manter organizado os campos do seu formulário. Por padrão, um grupo já vem criado chamado de Dados mas você pode alterá-lo e/ou criar outros.   
Por exemplo, em um formulário de cadastro de cliente, você pode organizar os campos em Dados Pessoais, Endereço e Contato, e dentro desses grupos, colocar os campos referentes a cada um dos grupos.

[![grupo_de_informacoes.png](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/scaled-840-0/grupo_de_informacoes.png)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/grupo_de_informacoes.png)

Outra definição, além do nome, é a ordem que será mostrado na lista, e se ele deve aparecer aberto ou recolhido quando o formulário for visualizado. Para ordenar os grupos, basta clicar no ícone ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/scaled-840-0/image-1551235146917.png) e arrastar para a posição desejada.

Mesmo escolhendo uma das opções por padrão, o usuário poderá abrir ou fechar esse grupo quando quiser.

[![grupo_info_aberto_fechado.gif](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/grupo_info_aberto_fechado.gif)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/grupo_info_aberto_fechado.gif)

Por fim, no menu "Ações", é possível definir todas as opções referentes a cada grupo de informações.[![acoes.png](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/scaled-840-0/acoes.png)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/acoes.png)

  
<iframe allowfullscreen="allowfullscreen" frameborder="0" height="425" src="https://player.vimeo.com/video/332437563" width="760"></iframe>

<p class="callout danger">Ao remover um grupo de informação, todos os campos que pertencem a ele também são removidos.</p>

# Campos e componentes do formulário

Esse é o momento, onde podemos adicionar campos ao nosso formulário. Cada campo é inserido dentro de um grupo de informação, criado no passo anterior.

<p class="callout info">Uma vez criado, o campo só pode ser mudado do grupo de informações acessando o menu "Configurações".</p>

Ao clicar em adicionar, aparecem os diversos tipos de campos, disponíveis no agility**flow**:

[![tipos_de_campos.png](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/scaled-840-0/tipos_de_campos.png)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/tipos_de_campos.png)

#### Campo Textbox

Esse campo deve ser usado para qualquer dado que seja um texto ou um número. Depois, é possível definir mais detalhes, como uma máscara numérica, para telefone ou moeda, por exemplo. Para maiores detalhes, leia o capítulo de [configuração](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/textbox " Configuração do Campo Textbox") do campo textbox.

#### Label Dinâmica

É um campo não editável pelo usuário e seu preenchimento ocorre através de um outro campo. Para maiores detalhes, leia o capítulo de [configuração](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/label-din%C3%A2mica "Configuração do Campo Label Dinâmica") do campo Label Dinâmica.

#### Upload

Permite que o usuário envie arquivos do computador para o formulário. Quando o formulário é aberto pelo celular, é possível que o usuário acione a câmera para o envio de fotos. Nas configurações adicionais, é possível validar a quantidade de itens (maior, menor ou igual a "x" itens enviados) e também as extensões permitidas ou proibidas. Para maiores detalhes, leia o capítulo de [configuração](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/upload "Configuração do Campo Upload") do campo Upload.

#### Lista de seleção (Combo)  
  
[![lista_para_selecao.gif](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/lista_para_selecao.gif)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/lista_para_selecao.gif)

Esse campo, permite que o usuário escolha uma opção pré-determinada. A origem dos dados pode ser através de duas formas:

##### Lista Estática

O usuário insere as opções nas configurações do campo. Com isso, o usuário que acessa o formulário não é pode criar novas opções.

##### Lista Dinâmica

Nessa opção, os dados têm como origem um outro formulário. Ao selecionar esse outro formulário, é necessário informar qual o campo desse formulário será exibido.

<p class="callout danger">Esse campo não deve ser usado quando há muitas opções. Isso por que, todas as opções desse campo são lidas quando a página é carregada. Se houver muitos itens, o carregamento da página pode ser afetado. Para esses casos, usar o campo pesquisa com auto completar.</p>

Para maiores detalhes, leia o capítulo de [configuração](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/lista-de-sele%C3%A7%C3%A3o-%28combo%29 "Configuração do Campo Lista de seleção (Combo)") do campo Lista de Seleção.

#### Pesquisa com auto completar

É similar ao Lista de Seleção, com a diferença que esse campo apenas tem os itens com origem em uma lista dinâmica. Além disso, as opções provenientes dessa lista, somente são mostradas após o usuário começar a digitar. Para maiores detalhes, leia o capítulo de [configuração](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/lista-com-auto-completar "Configuração do Campo Lista com auto completar") do campo Label Dinâmica.

<p class="callout warning">Esse campo deve ser usado quando o número de itens seja elevado. </p>

#### Checkbox (Único)

Esse campo permite o usuário responder a uma pergunta cuja resposta tem duas opções. Nesse campo, é possível definir o texto quando o campo está marcado, e quando o campo está desmarcado. O texto escolhido quando o campo está marcado, será mostrado na tela, enquanto o texto do campo quando está desmarcado, apenas será mostrado na listagem e no filtro de dados.

Para maiores detalhes, leia o capítulo de [configuração](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/checkbox-%28%C3%BAnico%29 "Configuração do Campo Checkbox (Único)") do campo Checkbox.

#### Lista aberta com escolha única (Radio)

Esse campo é muito similar ao tipo Lista de Seleção, mudando apenas a forma como é apresentado. Abaixo, um exemplo do campo radio (Lista aberta com escolha única):

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1553779844628.png)

<p class="callout warning">Quando a fonte dos dados for dinâmica, a opção de criar um novo item não está disponível no campo Lista aberta com escolha única (Radio).</p>

Para maiores detalhes, leia o capítulo de [configuração](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/radio "Configuração do Campo Radio") do campo Lista aberta com escolha única (Radio).

#### Fórmula

O campo de fórmula faz dois tipos de cálculos: com campos numéricos e com campos com data/hora. É na definição do campo que seleciona-se o tipo de cálculo. Ao escolher o tipo, serão mostrados os campos disponíveis para serem usados.

- Fórmula Numérica: é possível fazer as 4 operações aritméticas (soma, subtração, divisão e multiplicação) nesse campo. Para isso, basta selecionar um ou mais campos com a máscara do tipo numérico e escrever a fórmula.

<div id="bkmrk--0"><iframe allowfullscreen="allowfullscreen" frameborder="0" src="https://player.vimeo.com/video/316087003"></iframe>

</div><div id="bkmrk--1"></div>- Fórmula por data/hora: nessa opção, é possível subtrair um campo do tipo data/hora, por outro campo do tipo data/hora. Como resultado, é possível obter:  
    
    - Número de Dias
    - Número de Meses
    - Número de Anos
    - Número de Semanas
    - Número de Horas:Minutos

<p class="callout info">Para fórmula com datas, só é possível fazer a operação de subtração.</p>

Para maiores detalhes, leia o capítulo de [configuração](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/f%C3%B3rmula "Fórmula") do campo Fórmula.

#### Campo com Múltipla Escolha

Apesar do visual um pouco diferente, tem comportamento similar ao campo checkbox, mas permite a escolha de mais de uma opção. Para maiores detalhes, leia o capítulo de [configuração](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/lista-com-auto-completar "Configuração do Campo Lista com auto completar") do campo com Múltipla Escolha.

#### Botão Customizado

Caso seja necessário uma ação no formulário que não exista no agilityflow, é possível criar um botão. Esse botão, executa um código *javascript* personalizado, que deve ser criado pelo usuário. Para a configuração desse campo, é necessário conhecimento de javascript, já que qualquer ação com esse botão é 100% customizada.

Para maiores detalhes, leia o capítulo de [configuração](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/bot%C3%A3o-customizado "Configuração do Botão Customizado") do campo Botão Customizado.

#### Tabelas (Formulários Relacionados)

É a inclusão de um formulário dentro de outro. Saiba mais, no capítulo de [Formulários Relacionados](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/tabelas-%28formul%C3%A1rios-relacionados%29 "Tabelas (Formulários Relacionados)") do [Manual de Customização](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o "Manual de Customização") do agilityflow.

# Montar e organizar a tela de cadastro

### Montar tela de cadastro

É necessário montar a estrutura da tela do formulário, com os grupos de informações e os campos.

#### Barra Horizontal

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552308976445.png)

##### Confirmar Alterações

Sai da montagem da tela, salva a tela com as configurações atuais.

##### Fechar e Cancelar

Sai da montagem da tela, descartando as alterações.

##### Simular em Tela em outras Resoluções

Ao clicar em um dos 4 botões, você consegue ver como ficará a tela nas seguintes resoluções:

- Monitor
- Laptop
- Tablet
- Celular

##### Limpar Tela

Remove todos as estruturas da tela.

Na montagem da tela, existem 3 estruturas que podem ser utilizadas:

#### Montagem da Tela

##### Grupo de Informações

Cada [grupo de informação](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/divis%C3%A3o-e-agrupamento-dos-campos "Divisão e agrupamento dos campos") criado no formulário estará disponível para ser usado como estrutura na tela. Esses grupos, quando adicionados na tela, funcionam como uma caixa que ajudam a separar os campos de outros grupos. Além disso, esse grupo pode ser fechado ou aberto pelo usuário, facilitando quando existe uma grande quantidade de campos no formulário.

No exemplo abaixo, é possível ver um formulário simples de cadastro de clientes, onde os grupos de informações estão adicionados como estruturas da tela.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552270781875.png)

Clicando no ícone ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552271261105.png) no canto superior direito do grupo de informações, recolhe o grupo de informações. Clicando no ícone ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552271284429.png) ocorre a expansão.

Entretanto, a inclusão dos grupos de informações como estruturas na tela é opcional. Abaixo, o mesmo formulário do exemplo acima, sem a inclusão dos grupos de informações.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552271612449.png)

Para adicionar um grupo de informações, basta arrastar para a área desejada da tela.

##### Diagramação (Colunas)

A tela do formulário é separada em colunas. Caso não seja adicionada nenhuma coluna, o padrão é ter uma coluna só. A tela é dividida em 12 unidades fictícias de medidas. Quando se adicionam colunas, é possível definir o tamanho de cada uma, de forma que a soma de todas nunca ultrapasse 12. Portanto, é possível adicionar um máximo de 12 colunas, cada uma com o tamanho 1.

O sistema sugere por padrão, as seguintes opções de quantidade de colunas e tamanho:

- 1 col: 12
- 2 col: 6 6
- 2 col: 8 4
- 2 col: 9 3
- 3 col: 4 4 4
- 3 col: 2 6 4
- 3 col: 6 4 2
- 4 col: 3 3 3 3

Ao adicionar qualquer uma das estruturas, é possível movê-la na tela usando o ícone ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552272373066.png). Para apagar, use o. Caso queira duplicar a estrutura com o aspecto idêntico, clique em ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552272558456.png).

Para alterar a quantidade de colunas dessa estrutura, clique em ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552272594146.png). Isso vai abrir uma tela onde é possível distribuir as 12 unidades entre as colunas, assim como adicionar ou remover colunas.

<p class="callout success">É possível incluir um grupo de informação dentro de uma coluna, assim como também é possível dividir um grupo de informação com colunas. Além disso, é possível incluir um grupo de informação dentro de outro, assim como uma coluna dentro de outra.</p>

##### Campos

Os campos estão disponíveis para serem incluídos logo abaixo da diagramação, e estão separados pelos respectivos grupos de informação.

<p class="callout info">Tanto os grupos de informações como as colunas, servem como estruturas de tela, onde os campos vão ser incluídos. Não é possível incluir os campos fora dessas estruturas.</p>

Ao expandir um dos grupos, são exibidos os campos que pertencem a esse grupo. Basta arrastar o campo para o local desejado na tela.

Note que, mesmo incluído na tela, um campo pode não ser exibido devido as [regras de visibilidade](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/regras-de-visibilidade-e-desativa%C3%A7%C3%A3o "Regras de Visibilidade e Desativação").

# Configurar ações e os botões do menu do formulário

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552400731837.png)

#### Configurar botões e algumas ações

Aqui, é possível configurar as opções da barra que é mostrada na tela de cadastro de um formulário (tela para criação ou visualização de um registro):

##### Mostrar botão 'Consultar'

Ligado por padrão, permite mostrar ou ocultar o botão de consulta (![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552309537545.png)). Ao clicar, na prática, a tela de cadastro é fechada e o usuário é enviado de volta ao menu principal, onde podem ser realizados os filtros para fazer a consulta.

##### Mostrar botão 'Salvar'

Ligado por padrão, permite mostrar ou ocultar o botão de Salvar.

##### Mostrar botão 'Salvar em Rascunho'

Ligado por padrão, permite mostrar ou ocultar o botão de Salvar em Rascunho.

##### Mostrar botão 'Excluir'

Ligado por padrão, permite mostrar ou ocultar o botão de Excluir (![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552309659486.png)). Esse botão só é exibido ao visualizar um registro já existente. Fica oculto quando se está criando um novo registro.

##### Mostrar botão 'Aprovar'

Ligado por padrão, permite mostrar ou ocultar o botão de Aprovar etapa (![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552401104030.png)). Esse botão só será exibido em formulários que tenham fluxos por etapa.

##### Mostrar botão 'Retornar etapa'

Ligado por padrão, permite mostrar ou ocultar o botão de Retornar etapa (![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552401161815.png)). Esse botão só será exibido em formulários que tenham fluxos por etapa.

##### Mostrar botão 'Reprovar'

Ligado por padrão, permite mostrar ou ocultar o botão de Reprovar etapa (![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552401208633.png)). Esse botão só será exibido em formulários que tenham fluxos por etapa.

##### Nomenclatura para o botão 'Salvar'

É possível alterar o texto do botão que vai ao lado do ícone ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552309731659.png).

##### Nomenclatura para o botão 'Salvar rascunho':

É possível alterar o texto do botão que vai ao lado do ícone ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552309754274.png).

##### Nomenclatura para o botão 'Aprovar'

É possível alterar o texto do botão que vai ao lado do ícone ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552401397130.png).

##### Nomenclatura para o botão 'Aprovar' na primeira etapa

O botão aprovar pode ter um comportamento diferente na primeira etapa. É possível alterar o texto do botão que vai ao lado do ícone ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552401403315.png).

##### Nomenclatura para o botão 'Retornar etapa'

É possível alterar o texto do botão que vai ao lado do ícone ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552401419212.png).

##### Nomenclatura para o botão 'Reprovar'

É possível alterar o texto do botão que vai ao lado do ícone ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552401435218.png).

### Após salvar ou realizar qualquer ação com sucesso no formulário, o que deve acontecer

Permite definir o comportamento do formulário, quando se clica nos botões Salvar, Salvar em Rascunho ou Excluir. São eles:

- Redirecionar para a lista: é a ação padrão. Leva o usuário à tela padrão do formulário, com a lista dos registros;
- Redirecionar para a tela inicial do sistema: leva o usuário para a tela que é aberta ao fazer a entrada no sistema;
- Redirecionar para a criação de um novo cadastro: abre a tela de cadastro, para a criação de um novo registro;
- Redirecionar para a mesma tela em modo edição: salva as alterações, mas mantém aberta a tela de cadastro;
- Imprimir o relatório de impressão X: abre a tela de impressão do relatório selecionado.

### Bloquear novos registros

> Como bloquear o cadastro de novos registros em um formulário?

Com essa opção, é possível bloquear o cadastro de novos registros, não importando a permissão do usuário. São duas opções:

- Liberado para cadastro de novos registros (padrão);
- Bloqueado para cadastro de novos registros;

### Ações customizadas (Menu interno)

As ações customizadas são formas de abrir um quadro (kanban), um relatório, uma lista de formulário ou um novo formulário, baseados em um registro. Ao clicar no menu ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-05-May/scaled-840-0/image-1557169920932.png) de um registro, as ações customizadas são mostradas.

Um formulário pode ter múltiplas ações customizadas, e elas são mostradas em lista, onde é possível ver o tipo, se está ativa ou não, reordenar, excluir ou configurar.

Essa ações fazem sentido, quando são utilizadas em um formulário que utiliza formulários relacionados. Com isso, é possível acessar um registro, e através de uma ação customizada, abrir um outro formulário que possua registros relacionados ao primeiro.

Para criar uma nova ação, basta clicar no botão "Adicionar Ação" e seguir os seguintes passos:

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-05-May/scaled-840-0/image-1557170292984.png)

#### Ação

##### Nome da ação

Se define o nome da ação. Esse nome será exibido no menu dos registros.

##### Ativo

Se essa ação está disponível para ser utilizada ou não.

##### Tipo

São 4 opções:

- Abrir quadro (kanban): ao selecionar essa opção, é necessário escolher qual o quadro que será aberto. Feito isso, é possível já definir um filtro, onde se escolhe um campo que tenha alguma associação (pelo id do formulário) com o formulário do quadro escolhido
- Abrir relatório
- Abrir lista do formulário
- Abrir um novo formulário

#### Regras de visibilidade

##### Disponível na listagem

Indica se essa ação estará visível no menu ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-05-May/scaled-840-0/image-1557169920932.png) dos registros.

##### Disponível no formulário

Indica se essa ação estará visível como um botão, dentro do registro, quando o mesmo for aberto.

##### Regra condicional de visibilidade

É possível também, vincular a visibilidade de acordo com uma regra. A regra é definida pelo usuário, e sempre que existir uma regra criada, a ação só será exibida quando o resultado da regra for verdadeiro.

# Customização javascript

Todos os campos do agilityflow possuem inúmeras customizações, que flexibilizam seu uso para o usuário. Entretanto, podem haver casos de customizações muito específicas, que o agilityflow não possua. Para esses casos, é possível inserir uma programação javascript no campo. Com isso, o agilityflow disponibiliza toda a flexibilidade do javascript para adequar o comportamento dos campos à sua necessidade.

Além disso, é possível programar que essa ação seja executada, não só para o clique, mas também para outras formas de interação com esse botão. São elas:

- On Page Load: ação é executada assim que a página carregar.
- On Blur
- On Change
- On Click
- On Focus
- On Input
- On KeyUp
- On Keydown
- On Mouseover
- On Mouseout

# Lista e consulta

Nessa aba, é possível configurar as opção de listagem dos formulários, filtros padrão e quadros Kanban;

### Listagem no formato de tabela de dados

A listagem principal dos dados do formulário é como os registros serão mostrados e como será a ordenação desses registros.

Como a tela principal do formulário irá mostrar uma lista de registros, nem sempre será possível mostrar todas as colunas do formulário. Por isso, precisamos selecionar as colunas serem mostradas e escolher uma ordenação. Também é possível definir os filtros que estarão disponíveis.

#### Colunas

Adiciona-se as colunas que se deseja exibir. É necessário ter pelo menos uma coluna adicionada. Para cada coluna adicionada, abrem-se 3 opções:

##### Posicionar Coluna

Ao clicar nesse ícone, basta arrastar a coluna para a ordem desejada. A ordem, que nessa tela é apresentada de cima pra baixo, na listagem do formulário é da esquerda para direita. Ou seja, quanto ainda pra cima está a coluna, mais à esquerda ela será apresentada na listagem.

##### Visível no Mobile

Pela limitação de largura das telas dos celulares, é possível ocultar algumas colunas, quando o formulário for aberto em um dispositivo móvel. Para isso, basta desmarcar a opção 'Visível no Mobile', que ver marcada por padrão.

##### Excluir

Remove a coluna da listagem.

#### Ordenação

É necessário adicionar uma ordenação padrão para cada formulário. Ao adicionar uma coluna nessa lista, a ordenação padrão do formulário é definida.

<p class="callout info">Ao adicionar mais de uma coluna, primeiro se ordena a listagem baseado no primeiro campo, depois no segundo e assim por diante.</p>

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="425" src="https://player.vimeo.com/video/327352795" width="760"></iframe>

Existem ainda, 3 opções de configuração para cada coluna:

##### Decrescente ou Crescente

Define o critério crescente ou decrescente de ordenação para essa coluna.

##### Ordenar Prioridade

Ao clicar nesse ícone, basta arrastar a coluna para a ordem desejada.

##### Excluir

Remove a coluna do critério de ordenação.

### Filtros disponíveis para consulta dos dados

#### Filtros

Essa opção não é obrigatória e por padrão, todos os campos são adicionados no filtro.

Nessa opção, é possível habilitar ou não o filtro pelos campos do formulário. É possível também definir a ordem dos campos dentro da aba de filtro da listagem dos dados do formulário.

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="425" src="https://player.vimeo.com/video/332437532" width="760"></iframe>

#### Definir os valores e regras iniciais

##### Filtro inicial fixo

Quando definido o filtro desse tipo, o filtro inicial será aplicado independente do usuário. São essas as opções a serem definidas

- Só minhas pendências: apenas os fluxos com pendências do usuário logado, serão exibidos;
- Todos: todos os fluxos serão exibidos;
- Apenas os que eu participei: apenas os fluxos cadastrados ou com participação pelo usuário logado, serão mostrados;
- Etapa atual: seleciona qual etapa do fluxo o filtro virá selecionado por padrão;
- Status: caso o formulário seja um formulário com etapas, seleciona o status dos fluxos: 
    - Em andamento
    - Aprovado
    - Reprovado
- Campos: todos os campos do formulário serão exibidos nessa opção, e cada um dos campos permitirá que haja um filtro inicial padrão; 
    - campo desativado para inclusão de novos filtros: quando marcada, essa opção previne o usuário de alterar ou incluir o filtro padrão inicial;

##### Filtro inicial com condicional por perfil e usuário

As definições do filtro em si, são exatamente idênticas à configuração acima. Entretanto, usar essa opção permite padronizar filtros de acordo com o usuário logado, ou o perfil (ou mais de um) do usuário logado;

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-05-May/scaled-840-0/image-1557862132507.png)

Para isso, é necessário definir duas condições no mínimo. Uma inicial e outra para quando a condição inicial não for verdadeira.

#### Só Minhas Pendências

Quando o formulário possuir etapas, a opção "*No filtro inicial, ao abrir a listagem, apresentar o filtro (checkbox) de "Só minhas pendências" marcado ou desmarcado:*" será mostrada. Essa opção é uma definição de padrão de visualização.

Quando marcada, o usuário vai sempre ver por padrão, apenas suas pendências marcadas no filtro, podendo desligar Se assim desejar.

<p class="callout info">Essa opção afeta o comportamento para todos os usuários.</p>

### Quadros (Kanban)

Os detalhes para a criação e configuração podem ser visualizados no capítulo [Quadros (Kanban)](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/quadros-%28kanban%29 "Quadros (Kanban)").

# Relatórios para impressão e PDF

Os relatórios para impressão é uma forma que podemos imprimir (ou gerar um PDF) os dados de um formulário (e de outros) em um formato pré-definido. É possível definir vários relatórios para um mesmo formulário. Isso é útil, quando se precisa das informações que constam em um formulário, mas como foco diferente.

Por exemplo, em um formulário de pedidos, é possível criar um relatório com os detalhes do pedido e um outro com detalhes apenas da entrega.

> Qual a diferença entre o relatório para impressão e o [relatório analítico](http://wiki.agilityflow.io/books/manual-do-usu%C3%A1rio/page/relat%C3%B3rios "Relatórios")?

A principal diferença é que no relatório para impressão é possível formatar a(s) página(s), dando uma apresentação customizada às informações.

Como foi dito, nos relatórios é possível criar um layout com imagens, logotipo da empresa e etc, dando uma outra roupagem aos dados do formulários quando são impressos.

A definição dos relatórios para impressão é feita como em um editor de texto comum. Para criar um formulário, clique no botão 'adicionar impressão'.

### Título

É o nome que aparecerá na tela do formulário ao se clicar no ícone ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552315909927.png).

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552315982808.png)

### Edição do documento

A área para edição do documento, funciona como um editor de texto clássico. É possível adicionar textos fixos, tabelas, imagens, quebra de linha e etc. Todos os recursos de um editor de texto estão disponíveis na barra superior:

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552316855851.png)

Além desses recursos, outros dados estão disponíveis para serem adicionados:

#### Campos

Todos os campos do formulário ficam disponíveis para serem utilizados no relatório, com exceção do [Botão Customizado](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/bot%C3%A3o-customizado "Botão Customizado"). Para adicionar qualquer campo, basta arrastar para o relatório. Ao fazer isso, o nome do campo é adicionado ao lado do conteúdo, que é representado pelo @.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552322152675.png)

Para fazer a formatação do conteúdo, basta selecionar o conteúdo (que fica com um contorno amarelo) e aplicar a formatação normalmente.

##### Formulário Relacionado

Quando o formulário é relacionado, todos os registros desse formulário serão mostrados na listagem. É possível filtrar o conteúdo, clicando com o botão direito e selecionando a opção 'Editar Filtro de Dados'.

Além disso, as colunas que serão mostradas nessa tabela, são as mesmas que estão configuradas na [listagem de dados](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/listagem-principal-de-dados "Listagem principal de dados") desse formulário. Caso não queira a exibição de uma delas, basta remover a coluna da tabela. Para adicionar uma informação, basta criar uma coluna e arrastar o campo do formulário relacionado desejado.

##### Campo Upload

Ao posicionar o campo upload no relatório, e seu conteúdo for uma(s) imagem(ns), a(s) imagem(ns) será(ão) exibida(s) no relatório.

#### Log

Algumas informações internas do sistema estão também disponíveis para serem incluídas no relatório. São elas:

- Alterado por: nome do usuário que fez a última alteração no formulário;
- Criado por: nome do usuário que criou originalmente o formulário;
- Data Alteração: data e hora em que ocorreu a última alteração no formulário, no formato DD/MM/AAAA HH:mm;
- Data Criação: data e hora em que ocorreu a criação no formulário, no formato DD/MM/AAAA HH:mm;

#### Outras Variáveis

É a data atual, em diversos formatos:

- Data (DD/MM/AAAA): por exemplo 11/03/2019;
- Data (DD/MM/AAAA HH:mm): 11/03/2019 13:44;
- Data (DD de mês de AAAA): 11 de Março de 2019;
- Data (Dia da semana, DD de mês de AAAA): Segunda-Feira , 11 de Março de 2019;

#### Outras Fontes de dados

É um recurso que permite adicionar dados de outros registros ou formulários no relatório. A criação dessas outras fontes de dados, depende da composição de queries SQL nas tabelas dos formulários.

O agilityflow usa o SQL Server 2016. Para maiores informações, acesse a página do produto no [site da Microsoft](https://www.microsoft.com/pt-br/sql-server/sql-server-2016).

Na composição da query, é necessário usar os nomes as tabela informado nos [Dados Técnicos](http://wiki.agilityflow.io/link/21#bkmrk-%E2%A0-5) do formulário e o nome informado no campo [Coluna Banco de Dados SQL](http://wiki.agilityflow.io/link/38#bkmrk-%E2%A0-0 "Exemplo no campo Textbox"), na configuração dos campos.

Elas podem ser de dois tipos:

##### Tabela de Dados

A query retorna uma lista com várias colunas e linhas. Para o relatório, o elemento a ser adicionado é uma tabela. Ao clicar com o botão direito, é possível definir o agrupamento por um dos campos da query.

##### Variáveis

A query retorna uma lista com várias colunas mas apenas uma linha. Para o relatório, cada coluna é um elemento que pode ser adicionado ao relatório.

<p class="callout warning">Para esse tipo de fonte de dados, é necessário usar o parâmetro '*top 1*' no *select*.</p>

##### Exemplo de Query

Cenário: um relatório do formulário de clientes onde se obtém os últimos 15 pedidos desse cliente em uma impressão.

```SQL
SELECT TOP 15 pedido.log_data_criacao, 
             desc_ped, 
             valor_ped 
FROM   x_tbl_pedido AS pedido 
       INNER JOIN x_tbl_cliente AS cliente 
               ON pedido.id_cliente = cliente.id 
WHERE  cliente.id = @formularioid 
ORDER  BY pedido.log_data_criacao DESC 
```

Na query acima, vamos exibir os campos *log\_data\_criacao*, *desc\_ped* e *valor\_ped* dos últimos 15 registros (pedidos) ta tabela *x\_tbl\_pedido*, cujo cliente do pedido seja igual ao cliente que o usuário está acessando no formulário de Clientes (*x\_tbl\_cliente*). A ordem dessa lista é decrescente baseada no campo *log\_data\_criacao*.

# Regras de Visibilidade e Desativação

Em todos os campos da plataforma, é possível criar regras para tornar um campo visível, invisível, ativo ou inativo, e definir quando uma dessas ações deve ocorrer. É possível adicionar várias regras para cada campo.

#### Descrição

É um texto que ajuda a identificar a regra que se está criando. Muito útil quando existem múltiplas regras.

#### Ação

##### Ativar

Deixa o campo disponível para inserção de dados. É o estado padrão do campo.

##### Inativar

Deixa o campo indisponível para inserção de dados.

##### Visível

O campo é mostrado na tela, caso esteja inserido para tal, nas configurações de tela.

##### Invisível

O campo é não é mostrado na tela, mesmo que esteja inserido para tal, nas configurações de tela.

#### A partir da etapa / Até a etapa

Em formulários com etapas, é possível estabelecer que uma regra será aplicada em alguma(s) etapa(s). Para isso, basta selecionar as etapas nos campos "a partir da etapa" e "até a etapa", para definir em que momento do fluxo essa regra vai ser aplicada.

#### Quando

Define em que momento a ação deve acontecer.

##### Sempre

É o padrão do formulário.

##### Condicional

- Tipo de condição  
    Para fazer um validação condicional, estão disponíveis as seguintes condições:  
    
    - Se o campo: compara um campo com um valor, ou com outro campo.  
        Abaixo, uma tabela com os operadores disponíveis para as comparações:  
          
        <table border="1" style="border-collapse: collapse; width: 100%;"><tbody><tr><td style="width: 50%;">**Comparação por valor**</td><td style="width: 50%;">**Comparação por outro campo**</td></tr><tr><td style="width: 50%;">For igual a</td><td style="width: 50%;">É igual ao campo</td></tr><tr><td style="width: 50%;">For maior ou igual a</td><td style="width: 50%;">É diferente do campo</td></tr><tr><td style="width: 50%;">For menor ou igual a </td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">For maior que</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">For menor que</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">For diferente de</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">Conter</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">Não conter</td><td style="width: 50%;"> </td></tr></tbody></table>
        
        <p class="callout success">É possível adicionar mais de um condição na mesma regra.</p>
    - Se é um novo formulário: regra será aplicada quando uma nova entrada no formulário estiver sendo criada.
    - Se é edição de formulário: regra será aplicada quando uma entrada no formulário estiver sendo alterada.

# Lista de atributos de configuração por campos

<table border="0" cellpadding="0" cellspacing="0" id="bkmrk-atributos%E2%A0%E2%A0%E2%A0%E2%A0-ca" style="border-collapse: collapse; table-layout: fixed; width: 624pt; height: 3151px;" width="823"><colgroup> <col style="mso-width-source: userset; mso-width-alt: 17737; width: 364pt;" width="485"></col> <col class="xl66" span="13" style="mso-width-source: userset; mso-width-alt: 950; width: 20pt;" width="26"></col> </colgroup><tbody><tr style="height: 173.25pt;"><td class="xl70 align-center" height="231" style="height: 302px; width: 490px;">Atributos dos campos e componentes do formulário</td><td class="xl68 tbl-atributos-af-title" style="border-left: none; width: 27px; height: 330px;"><div>Campo Textbox</div></td><td class="xl68 tbl-atributos-af-title" style="border-left: none; width: 27px; height: 330px;"><div>Label Dinâmica Novo</div></td><td class="xl68 tbl-atributos-af-title" style="border-left: none; width: 26px; height: 330px;"><div>Upload</div></td><td class="xl68 tbl-atributos-af-title" style="border-left: none; width: 26px; height: 330px;"><div>Lista de seleção (Combo)</div></td><td class="xl68 tbl-atributos-af-title" style="border-left: none; width: 26px; height: 330px;"><div>Pesqiusa com auto completar</div></td><td class="xl68 tbl-atributos-af-title" style="border-left: none; width: 26px; height: 330px;"><div>Checkbox (Único)</div></td><td class="xl68 tbl-atributos-af-title" style="border-left: none; width: 26px; height: 330px;"><div>Lista aberta com escolha única (Campo Radio)</div></td><td class="xl68 tbl-atributos-af-title" style="border-left: none; width: 26px; height: 330px;"><div>Fórmula</div></td><td class="xl68 tbl-atributos-af-title" style="border-left: none; width: 26px; height: 330px;"><div>Campo com Múltipla Escolha</div></td><td class="xl68 tbl-atributos-af-title" style="border-left: none; width: 26px; height: 330px;"><div>Botão Customizado</div></td><td class="xl68 tbl-atributos-af-title" style="border-left: none; width: 26px; height: 330px;"><div>Tabelas (Formulários Relacionados)</div></td><td class="xl68 tbl-atributos-af-title" style="border-left: none; width: 26px; height: 330px;"><div>Tabelas Relacionais (N:N)</div></td><td class="xl68 tbl-atributos-af-title" style="border-left: none; width: 26px; height: 330px;"><div>Componentes CsHtml</div></td></tr><tr style="height: 18.75pt;"><td class="xl67" height="25" style="height: 18px; border-top: none; width: 490px;">Grupo de Informação</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl67" height="25" style="height: 18px; border-top: none; width: 490px;">Nome de Apresentação</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl67" height="25" style="height: 18px; border-top: none; width: 490px;">Tipo</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">Campo de Texto Simples</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">Campo de Texto Multi Linha</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="mso-height-source: userset; height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">Campo com criptografia MD5 (Ex: Senha)</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="mso-height-source: userset; height: 18.75pt;"><td class="xl72" height="25" style="height: 18px; border-top: none; width: 490px;">Campo Auto Numérico (Número Sequencial preenchido automaticamente)</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl73" height="25" style="height: 18px; border-top: none; width: 490px;">Texto ao lado do Checkbox</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl72" height="25" style="height: 18px; border-top: none; width: 490px;">Quando marcado</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl72" height="25" style="height: 18px; border-top: none; width: 490px;">Quando desmarcado</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl67" height="25" style="height: 18px; border-top: none; width: 490px;">Coluna Banco de Dados (SQL)</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl67" height="25" style="height: 18px; border-top: none; width: 490px;">Informações de ajuda</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl67" height="25" style="height: 18px; border-top: none; width: 490px;">Preenchimento Padrão</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">Preencher Quando</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">Valor Padrão</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl67" height="25" style="height: 18px; border-top: none; width: 490px;">Máscara</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">Tipo de máscara</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="page-break-before: always; height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">Número</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl75" height="25" style="height: 18px; border-top: none; width: 490px;">Tipo de Número</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl75" height="25" style="height: 18px; border-top: none; width: 490px;">Inteiro</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl75" height="25" style="height: 18px; border-top: none; width: 490px;">Moeda (Real)</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl75" height="25" style="height: 18px; border-top: none; width: 490px;">Decimal (1 casa decimal)</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl75" height="25" style="height: 18px; border-top: none; width: 490px;">Decimal (2 casas decimais)</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl75" height="25" style="height: 18px; border-top: none; width: 490px;">Decimal (3 casas decimais)</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl75" height="25" style="height: 18px; border-top: none; width: 490px;">Decimal (4 casas decimais)</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl75" height="25" style="height: 18px; border-top: none; width: 490px;">Decimal (5 casas decimais)</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">CPF</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">CNPJ</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">CEP</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">Máscara Customizada</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl75" height="25" style="height: 18px; border-top: none; width: 490px;">Tipo de Customização</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl76" height="25" style="height: 18px; border-top: none; width: 490px;">Básica</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl76" height="25" style="height: 18px; border-top: none; width: 490px;">Avançada</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">Máscara com 'Regular Expression'</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">Telefone: País + DDD + Cel/Tel Brasil</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">Telefone: DDD + Cel/Tel Brasil</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">Telefone: Cel/Tel Brasil</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">Data Data e hora no formato dd/mm/yyyy hh:mm</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">Data e hora (Com Segundos) no formato dd/mm/yyyy hh:mm:ss</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">Data sem hora no formato dd/mm/yyyy</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">Hora no formato hh:mm</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">Hora (Com Segundos) no formato hh:mm:ss</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">Tamanho máximo de Preenchimento</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="page-break-before: always; height: 18.75pt;"><td class="xl77" height="25" style="height: 18px; border-top: none; width: 490px;">Preenchimento da Label Dinâmica</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">Preencher a label dinâmica ao alterar o campo</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">Campo de apresentação (Base de dados)</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl77" height="25" style="height: 18px; border-top: none; width: 490px;">Origem dos Dados</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">Origem dos Itens</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">Lista Dinâmica</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">Lista Estática</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">Carregamento de lista</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">No carregamento inicial (On PageLoad)</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">Na alteração do valor de um determinado campo (On Change)</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">Base de dados</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">Campo de apresentação (Base de dados)</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="mso-height-source: userset; height: 18.75pt;"><td class="xl73" height="25" style="height: 18px; border-top: none; width: 490px;">Origem dos Dados e Relacionamento com outros Formulários (Pai X Filho)</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr class="xl65" style="mso-height-source: userset; height: 30.0pt;"><td class="xl72" height="40" style="height: 30px; border-top: none; width: 490px;">Esse campo pode ser Relacionado a um formulario Pai e preenchido automáticamente pelo ID (Primary Key) do formulário pai</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td></tr><tr style="mso-height-source: userset; height: 18.75pt;"><td class="xl72" height="25" style="height: 18px; border-top: none; width: 490px;">Esconder campo quando o formulário for aberto através do formulario pai</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl77" height="25" style="height: 18px; border-top: none; width: 490px;">Definição da Fórmula</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">Tipo de Cálculo</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">Fórmula Numérica</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">Fórmula por data/hora</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">Fórmula</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl77" height="25" style="height: 18px; border-top: none; width: 490px;">Validação</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">Obrigatório</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 30.0pt;"><td class="xl78" height="40" style="height: 30px; border-top: none; width: 490px;">Obrigatório mesmo que por algum motivo o campo esteja marcado como invisível?</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 30px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 27px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl78" height="25" style="height: 18px; border-top: none; width: 490px;">Obrigatório a partir da etapa</td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">Valor do campo deve ser único em relação a todos os registros</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="page-break-before: always; height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">Valor do campo deve ser único em relação ao formulário PAI:</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 30.0pt;"><td class="xl72" height="40" style="height: 30px; border-top: none; width: 490px;">Valor do campo deve ser único em relação APENAS ao CAMPO relacinoado do formulário PAI:</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 30px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">Extensão Permitida</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">Extensão não permitida</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">Validação customizada</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">Tipo de Validação</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl75" height="25" style="height: 18px; border-top: none; width: 490px;">Número igual e diferente</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl76" height="25" style="height: 18px; border-top: none; width: 490px;">Numerica: O valor digitado deve ser igual ao numero</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl76" height="25" style="height: 18px; border-top: none; width: 490px;">Numerica: O valor digitado deve ser diferente do numero</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl76" height="25" style="height: 18px; border-top: none; width: 490px;">Numerica: O valor digitado deve ser igual ao campo</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl76" height="25" style="height: 18px; border-top: none; width: 490px;">Numerica: O valor digitado deve ser diferente do campo</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl75" height="25" style="height: 18px; border-top: none; width: 490px;">Número máximo</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="mso-height-source: userset; height: 18.75pt;"><td class="xl80" height="25" style="height: 18px; border-top: none; width: 490px;">Numerica: O valor digitado nao pode ser maior que o numero</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="mso-height-source: userset; height: 18.75pt;"><td class="xl80" height="25" style="height: 18px; border-top: none; width: 490px;">Numerica: O valor digitado nao pode ser maior nem igual ao numero</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="mso-height-source: userset; height: 18.75pt;"><td class="xl80" height="25" style="height: 18px; border-top: none; width: 490px;">Numerica: O valor digitado nao pode ser maior que o campo</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="mso-height-source: userset; height: 18.75pt;"><td class="xl80" height="25" style="height: 18px; border-top: none; width: 490px;">Numerica: O valor digitado nao pode ser maior nem igual ao campo</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl75" height="25" style="height: 18px; border-top: none; width: 490px;">Número mínimo</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl76" height="25" style="height: 18px; border-top: none; width: 490px;">Numerica: O valor digitado nao pode ser menor que numero</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="mso-height-source: userset; height: 18.75pt;"><td class="xl80" height="25" style="height: 18px; border-top: none; width: 490px;">Numerica: O valor digitado nao pode ser menor nem igual ao numero</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="mso-height-source: userset; height: 18.75pt;"><td class="xl80" height="25" style="height: 18px; border-top: none; width: 490px;">Numerica: O valor digitado nao pode ser menor que o campo</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="mso-height-source: userset; height: 18.75pt;"><td class="xl80" height="25" style="height: 18px; border-top: none; width: 490px;">Numerica: O valor digitado nao pode ser menor nem igual ao campo</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl75" height="25" style="height: 18px; border-top: none; width: 490px;">Range numérico</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="mso-height-source: userset; height: 15.0pt;"><td class="xl80" height="20" style="height: 15px; border-top: none; width: 490px;">Numerica: O valor digitado tem que estar entre os numeros</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 15px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 15px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 15px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 15px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 15px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 15px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 15px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 15px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 15px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 15px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 15px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 15px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 15px; width: 26px;"> </td></tr><tr style="mso-height-source: userset; height: 18.75pt;"><td class="xl80" height="25" style="height: 18px; border-top: none; width: 490px;">Numerica: O valor digitado NAO pode estar entre os numeros</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl75" height="25" style="height: 18px; border-top: none; width: 490px;">Texto igual e diferente</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl80" height="25" style="height: 18px; border-top: none; width: 490px;">Texto: O valor digitado deve ser igual ao texto</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="page-break-before: always; height: 18.75pt;"><td class="xl80" height="25" style="height: 18px; border-top: none; width: 490px;">Texto: O valor digitado deve ser diferente do texto</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl80" height="25" style="height: 18px; border-top: none; width: 490px;">Texto: O valor digitado deve ser igual ao campo</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl80" height="25" style="height: 18px; border-top: none; width: 490px;">Texto: O valor digitado deve ser diferente do campo</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl75" height="25" style="height: 18px; border-top: none; width: 490px;">Texto contém</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl80" height="25" style="height: 18px; border-top: none; width: 490px;">Texto: O valor digitado deve conter no minimo o texto</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl80" height="25" style="height: 18px; border-top: none; width: 490px;">Texto: O valor digitado NAO deve conter o texto</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl75" height="25" style="height: 18px; border-top: none; width: 490px;">Outros</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl80" height="25" style="height: 18px; border-top: none; width: 490px;">CNPJ</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl80" height="25" style="height: 18px; border-top: none; width: 490px;">CPF</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl80" height="25" style="height: 18px; border-top: none; width: 490px;">E-mail</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl81" height="25" style="height: 18px; border-top: none; width: 490px;">Avançado</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl80" height="25" style="height: 18px; border-top: none; width: 490px;">Regex</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl81" height="25" style="height: 18px; border-top: none; width: 490px;">Upload lista</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl80" height="25" style="height: 18px; border-top: none; width: 490px;">Upload: Upload de no máximo X itens</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl80" height="25" style="height: 18px; border-top: none; width: 490px;">Upload: Upload no mínimo X itens</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl80" height="25" style="height: 18px; border-top: none; width: 490px;">Upload: Upload exatamente X itens</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl81" height="25" style="height: 18px; border-top: none; width: 490px;">Seleção Lista</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl80" height="25" style="height: 18px; border-top: none; width: 490px;">Seleção: Selecionar no máximo X itens</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl80" height="25" style="height: 18px; border-top: none; width: 490px;">Seleção: Selecionar no mínimo X itens</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl80" height="25" style="height: 18px; border-top: none; width: 490px;">Seleção: Selecionar exatamente X itens</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl78" height="25" style="height: 18px; border-top: none; width: 490px;">Validar a partir da etapa</td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl73" height="25" style="height: 18px; border-top: none; width: 490px;">Regras de Visibilidade e desativação</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl72" height="25" style="height: 18px; border-top: none; width: 490px;">Ação</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl78" height="25" style="height: 18px; border-top: none; width: 490px;">Ativar</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl78" height="25" style="height: 18px; border-top: none; width: 490px;">Inativar</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl78" height="25" style="height: 18px; border-top: none; width: 490px;">Visível</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="page-break-before: always; height: 18.75pt;"><td class="xl78" height="25" style="height: 18px; border-top: none; width: 490px;">Invisível</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl72" height="25" style="height: 18px; border-top: none; width: 490px;">Quando</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl78" height="25" style="height: 18px; border-top: none; width: 490px;">Sempre</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl78" height="25" style="height: 18px; border-top: none; width: 490px;">Condicional</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl72" height="25" style="height: 18px; border-top: none; width: 490px;">A partir da etapa</td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl72" height="25" style="height: 18px; border-top: none; width: 490px;">Até a etapa</td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl73" height="25" style="height: 18px; border-top: none; width: 490px;">Customização javascript</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">Descrição</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">Evento</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">On Page Load</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">On Blur</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">On Change</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">On Click</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">On Focus</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">On Input</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">On KeyUp</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">On KeyDown</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">On Mouseover</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">On Mouseout</td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">A partir da etapa</td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl79 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl77" height="25" style="height: 18px; border-top: none; width: 490px;">Ordenação manual organizada pelo próprio usuário</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl77" height="25" style="height: 18px; border-top: none; width: 490px;">Customização da Lista</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">Coluna Visível</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">Prefixo</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">Sufixo</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl71" height="25" style="height: 18px; border-top: none; width: 490px;">Informação no Rodapé</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="page-break-before: always; height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">Soma da Coluna</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">Média da Coluna</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl75" height="25" style="height: 18px; border-top: none; width: 490px;">Mascara: Moeda (Real)</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl75" height="25" style="height: 18px; border-top: none; width: 490px;">Máscara: Decimal (1 casa decimal)</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl75" height="25" style="height: 18px; border-top: none; width: 490px;">Máscara: Decimal (2 casas decimais)</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl75" height="25" style="height: 18px; border-top: none; width: 490px;">Máscara: Decimal (3 casas decimais)</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl75" height="25" style="height: 18px; border-top: none; width: 490px;">Máscara: Decimal (4 casas decimais)</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl75" height="25" style="height: 18px; border-top: none; width: 490px;">Máscara: Decimal (5 casas decimais)</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl77" height="25" style="height: 18px; border-top: none; width: 490px;">Lista do formulário que podem ser apresentadas como Sub Lista</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl74" height="25" style="height: 18px; border-top: none; width: 490px;">Já abrir com as Sub Lista expandidas</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 18.75pt;"><td class="xl75" height="25" style="height: 18px; border-top: none; width: 490px;">Sub Lista visível</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 18px; width: 26px;"> </td></tr><tr style="height: 30.0pt;"><td class="xl81" height="40" style="height: 30px; border-top: none; width: 490px;">Apresentar nessa tabela de dados apenas os dados que foram cadastrados através desse campo da tela</td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 27px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl69 icon-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td><td class="xl70 icon-nao-possui" style="border-top: none; border-left: none; height: 30px; width: 26px;"> </td></tr><tr style="display: none;"><td style="width: 485.333px; height: 0px;"> </td><td style="width: 26.6667px; height: 0px;"> </td><td style="width: 26.6667px; height: 0px;"> </td><td style="width: 26.6667px; height: 0px;"> </td><td style="width: 26.6667px; height: 0px;"> </td><td style="width: 26.6667px; height: 0px;"> </td><td style="width: 26.6667px; height: 0px;"> </td><td style="width: 26.6667px; height: 0px;"> </td><td style="width: 26.6667px; height: 0px;"> </td><td style="width: 26.6667px; height: 0px;"> </td><td style="width: 26.6667px; height: 0px;"> </td><td style="width: 26.6667px; height: 0px;"> </td><td style="width: 26.6667px; height: 0px;"> </td><td style="width: 26.6667px; height: 0px;"> </td></tr></tbody></table>

# Regras de negócio (Automação)

As regras de negócio são regras condicionais que podem executar diversas ações. Essas regras de negócio devem ser sempre associadas a um formulário, e sua criação deve ser feita nas configurações do formulário desejado.

### Criando as regras

Antes de mais nada, é necessário definir um nome para a regra. Esse é o nome que será apresentado depois, na construção da linha do tempo. As regras de automação, podem ter 3 partes.

#### Condicional (se)

É onde podemos testar uma ou várias condições. Essas condições referem-se a comparações de um valor com um campo. É possível adicionar as seguintes condições:

- Se: é uma comparação simples;
- Caso Contrário: é o que vai ocorrer, caso a condição "Se" não se satisfaça;
- Se/Caso Contrário: é uma possibilidade de se colocar uma segunda condição;

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1551490277395.png)

No exemplo acima, queremos dar um tratamento quando o campo 'Tipo de Entrega' for igual a 'Correios', outro quando for 'Mensageiro' e outro para todos os demais valores do campo.

#### Criar Formulário

A criação do formulário é o preenchimento do campos do formulário de destino com os valores do formulario de origem (onde a regra está sendo criada) ou com valores pré-definidos.

Esses valores pré-definidos, em casos de campos de textos, podem ser fixados quando se define a regra de criação do formulário. Já os campo de seleção, como lista de seleção, a lista aberta com escolha única (radio), a pesquisa com auto completar, e etc, podem ser atribuídos de outros campos que possuem as mesmas opções, ou selecionados de maneira fixa.

#### Query SQL (Fonte de Dados)

Usando essa opção, é possível fazer uma query sql em qualquer tabela do agilityflow e atribuir o resultado à uma variável, e usar o valor nas comparações e nos mapeamentos de formulários.

Ao criar a query, será preciso definir o nome da variável e da query. O nome da variável, será usado posteriormente para identificar o valor nas condições e mapeamentos.

A query, segue os padrões das queries utilizadas em outros pontos do agilityflow, e os detalhes podem ser vistos [aqui](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/programa%C3%A7%C3%A3o-em-sql-%28query%29 "Programação em SQL (Query)"). Uma diferença, é que o conteúdo da primeira linha e da primeira coluna (resultado da query) é atribuído à uma variável. Outra diferença, é que nessa query é obrigatório o uso do parâmetro "top 1".

No exemplo abaixo, existe um query que verifica a existência do usuário e, dependendo do resultado, toma uma ou outra ação:

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-05-May/scaled-840-0/image-1557843298418.png)

<p class="callout warning">É necessário colocar a execução da query antes do teste da variável na estrutura condicional (se).</p>

#### Programação customizada

Uma forma de se customizar ainda mais o agilityflow é incluir programação em alguns pontos. A programação customizada permite que seja incluído qualquer código em C#, dando uma enorme flexibilidade de ações.

### Momento de execução das regras

As regras precisam ser executadas em um determinado momento. Os momentos são esses:

- No carregamento inicial do formulário (OnPageLoad)
- Ao clicar no botão 'Salvar'
- Ao clicar no botão 'Deletar'
- Ao alterar o campo

### Configuração da timeline

É quando as regras serão executadas. A timeline (linha do tempo) é uma ordem de acontecimentos onde as regras podem ser incluídas. Para o momento de alteração de campo, a timeline só tem um espaço. Para os demais momentos, são 3 espaços para a inclusão de regras:

- Antes de validar se o preenchimento dos campos está correto
- Depois de validar o preenchimento dos campos e Antes de salvar no banco de dados
- Depois de salvar no banco de dados

#### Reordenar as regras

Uma vez posicionada, as regras podem ser reordenadas. Basta clicar no ícone ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552335541995.png) e arrastar para a posição desejada.

#### Inativar uma regra

Para inativar uma regra, clique no menu à direita, e selecione a opção 'inativar nessa timeline'.

[![inativar_regra.gif](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/inativar_regra.gif)](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/inativar_regra.gif)

Feito isso, a regra recebe uma tarja vermelha com a indicação 'inativo'.

# Restrição de acesso a Dados na Lista Principal e Regras de Filtros

Além de restrição do acesso a funcionalidades por Perfil, você pode em restringir o acesso a dados de uma determinada funcionalidade usando Filtros inicias.

Na lista principal por exemplo, você pode restringir acesso aos dados, definindo condicionais nos Valor e Regras Iniciais de Filtros, como na imagem abaixo.

Para isso acesse o seu Formulário ou Fluxo, clica na opção "Construir a tela de lista de Consulta", deois acesse "Filtros: Valor e regras inicias"

![](https://wiki.agilityflow.io/uploads/images/gallery/2020-08-Aug/scaled-840-0/image-1598201005649.png)

Você pode ir além e criar (sub)Queries, dentro das opções de filtro citadas acima. Essa é uma opção mais avançada e requer habilidade com SQL.

Em um fluxo de aprovação existe uma funcionalidade nativa que você consegue restringir o acesso nativamente, mostrando para o usuário apenas os fluxos em que ele participou, como na imagem abaixo

![](https://wiki.agilityflow.io/uploads/images/gallery/2020-08-Aug/scaled-840-0/image-1598202222902.png)

Se achar melhor, você pode entrar em contato com a gente e podemos detalhar como tudo isso funciona :-)

# Devcenter - Customizar o Agilityflow

Área de customização de todos os recursos da plataforma

# Menu

É possível criar menus na [Barra Vertical / Menu Principal](http://wiki.agilityflow.io/books/manual-do-usu%C3%A1rio/page/barra-vertical-menu-principal) do agilityflow.

Para isso, basta clicar no ícone do Devcenter ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/scaled-840-0/image-1549032010112.png) localizado na Barra Vertical, e em seguida em Menu.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/scaled-840-0/image-1549032074974.png)  
Ao clicar em "*Consultar*" ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/scaled-840-0/image-1549032435961.png), é possível ver a lista de menus já existentes.

Clicando em "*Novo Menu*" ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/scaled-840-0/image-1549032455512.png), o usuário irá criar um novo Menu na Barra Vertical.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/scaled-840-0/image-1549033681325.png)

Feito isso, basta escolher um nome e um ícone, e o novo menu está pronto.

<p class="callout warning">O menu só aparecerá na Barra Vertical, quando ele possuir um formulário ou relatório para exibição.</p>

# Relatório analítico / BI

Os relatórios são uma forma de transformar os dados dentro do agilityflow, em informações valiosas. Os relatórios podem trazer uma série de dados de diferentes tabelas, com inúmeros cruzamentos, que possibilitam ao usuário do agilityflow, fazer uma série de análises e auxiliam na tomada de decisões estratégicas no seu negócio.

Para criar o relatório, é necessário dar um nome. Além disso, escolhe-se um ícone e o menu onde o relatório vai ficar, além de informar uma descrição. Existem também uma opção para desativar o relatório.

<p class="callout info">Caso nenhum menu seja selecionado, o relatório será adicionado no menu principal.</p>

Os relatórios são divididos em painéis. Esses painéis, possuem elementos, assim como os [widgets](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/widget "Widget") do [dashboard](http://wiki.agilityflow.io/books/manual-do-usu%C3%A1rio/page/dashboards "Dashboards"). É possível adicionar múltiplos painéis.

### Filtro

<span style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Oxygen, Ubuntu, Roboto, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400;">Todo relatório também possui uma área de filtros. Isso possibilita que os relatórios possam ter seus dados filtrados no momento em que o usuário o acessa. Isso possibilita expor informações e permitir que o usuário interaja com esses dados como lhe convir.</span>

<p class="callout success"><span style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Oxygen, Ubuntu, Roboto, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400;">Apesar de útil, os filtros são opcionais em um relatório.</span></p>

<span style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Oxygen, Ubuntu, Roboto, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400;">Ao adicionar os filtros, você deve criar campos para que o usuário interaja com o filtro. Ao criar um novo campo para o seu filtro, você deve preencher as seguintes informações:</span>

#### Nome de Apresentação

É o nome que será mostrado ao usuário, e é como esse filtro será identificado na configuração do relatório.

#### Id do campo

É como esse valor será levado para as queries que montarão o relatório.

#### Ativo

Por padrão, é marcado como Sim. Habilita ou desabilita um filtro para ser usado no relatório.

#### Tipo

Como esse filtro é um campo, você deve informar de qual tipo é esse campo.

##### Texto Livre

É um campo que o usuário pode colocar qualquer texto

##### Data/Hora

Um campo contendo data e/ou hora. É também necessário definir um formato:

- Data e hora no formato dd/mm/yyyy hh:mm
- Data sem hora no formato dd/mm/yyyy
- Hora no formato hh:mm

##### Número

Campo com um valor numérico.

É também necessário definir um formato:

- Inteiro
- Moeda (Real)
- Decimal (1 casa decimal)
- Decimal (2 casas decimal)
- Decimal (3 casas decimal)
- Decimal (4 casas decimal)
- Decimal (5 casas decimal)

##### Lista para Seleção ou Pesquisa com Auto Completar

Para esses tipos, é necessário escolher a base de dados que será utilizada e o campo de apresentação. Além disso, é possível adicionar uma condição na base de dados.

<p class="callout warning">Após a configuração do filtro, será criada uma variável. Essa variável está indicada com "@" e deverá ser usada na [query](#bkmrk-query) juntamente com a [Função Filter](http://wiki.agilityflow.io/link/72#bkmrk-fun%E3%A7%E3%A3o-filter "Função Filter").</p>

#### Definir os valores e regras iniciais para os campos do filtro

Após adicionar os campos do filtro (descritos acima), é possível definir valores padrões iniciais para os filtros. Além disso, é possível bloquear a alteração desse filtro, e também o fazê-lo dependendo do usuário ou perfil do usuário. Para maiores detalhes, veja o item [definir os valores e regras iniciais dos filtros](http://wiki.agilityflow.io/link/27#bkmrk-filtro-inicial-com-c) do capítulo [lista e consulta](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/lista-e-consulta "Lista e consulta") nas configurações do [formulário](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/chapter/formul%C3%A1rios "Formulários").

### Painel

Todo painel tem um título. Esse título pode ou não ser exibido, clicando no ícone ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552505783654.png).

Outra opção, é a cor do tema. Ela pode ser escolhida na opção tema. As opções de cores são:

- Branco (padrão)
- Cinza
- Azul
- Verde
- Roxo
- Vermelho
- Amarelo

Para alterar o tamanho de um widget, basta clicar em ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552505630931.png) e deixar com o tamanho desejado.

Elementos de um painel:

#### Label

É um texto, que pode ser fixo ou dinâmico. Caso seja dinâmico, o texto deve ser o resultado de uma query SQL. Essa query vai ter seu resultado atribuído à variáveis. Para utilizá-las, basta escrever @ e selecionar a variável. É possível combinar textos com variáveis.

Caso seja fixo, basta digitar o texto normalmente.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552506050722.png)

Além disso, é possível formatar o texto de várias maneiras, como definir o alinhamento vertical e horizontal do texto, tamanho e fonte.

E por fim, é possível que ao clicar no texto, o usuário seja levado a um link. Basta preencher a URL.

<p class="callout info">Ao posicionar qualquer elemento no painel, é possível redimensioná-lo usando o ícone ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552419219771.png).</p>

#### Ícone

É possível adicionar um ícone como elemento de um painel. Basta selecionar um ícone em uma das bibliotecas disponíveis. Ainda é possível editar alinhamento (vertical e horizontal), tamanho, cor e criar um link.

#### Imagem

Para fazer o upload de uma imagem, basta clicar no retângulo ou arrastar um arquivo até ele.

É possível formatar largura, altura e alinhamento (vertical e horizontal) e criar um link.

#### Gráfico

Ao se adicionar um gráfico, é possível escolher entre duas origem dos dados:

##### Criar uma tabela com dados Estáticos

Nessa opção, o usuário define os dados de maneira manual em uma tabela, como uma planilha. É possível adicionar dados em linhas e colunas, usando os botões ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552426025629.png).

Ao clicar na opção 'Editar tipo e propriedades do gráfico' ou no ícone ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552426111935.png), é possível definir o tipo do gráfico.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552426283220.png)

O sistema já sugere o gráfico mais recomendado na guia início. Clicando na aba Gráficos (ou em 'Mais »'), o sistema exibe todos os demais gráficos disponíveis.

Na aba Personalizar é possível editar as características do gráfico selecionado, como título, legenda, fonte, cores, entre outros.

##### Fonte de dados Dinâmica

Nesse caso, é necessário criar uma query para se obter os dados. As demais configurações, seguem o padrão do exemplo acima.

#### Tabela de Dados

Quando o elemento é a tabela de dados, a fonte para essa tabela, só pode ser dinâmica, ou seja, através de uma query.

##### Query

No exemplo abaixo, queremos uma tabela com a lista de autores cadastrados no sistema. A query está obtendo os campos '*id*', '*nome*', 'sexo' e '*nacionalidade*' da tabela 'x\_*tbl\_autor*'.

```SQL
select nome, sexo, nacionalidade from x_tbl_autor
```

Esse é um exemplo de um resultado dessa query:

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552498185480.png)

Uma vez a query montada, é possível formatar a tabela.

**Importante**: caso o relatório que esteja sendo criado possua filtros, é necessário incluir a função Filter com a(s) variável(is) criadas no [filtro](#bkmrk-filtro).

A função filter tem a seguinte sintaxe:

Filter(variável, tabela, campo)

- variável: ao criar um [filtro](#bkmrk-filtro), é criada uma variável. A lista de variáveis está na tela de montagem da query;
- tabela: é a tabela onde esse filtro deve acontecer;
- campo: é o campo da tabela que será usado no [filtro](#bkmrk-filtro);

```SQL
select nome, sexo, nacionalidade from x_tbl_autor
where 
	Filter (@sexo, x_tbl_autor, sexo) and
    Filter (@nome, x_tbl_autor, nome)
```

No exemplo acima, existe dois [filtros](#bkmrk-filtro) e suas variáveis (@sexo e @nome) que serão aplicados nos campos '*nome*' e '*sexo*' da tabela '*x\_tbl\_autor*'.

##### Configuração das colunas da tabela

- Ordem das colunas: clique no ícone [![image-1552335541995.png](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552335541995.png)](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/image-1552335541995.png) e arraste a coluna para a posição desejada;
- Nome de apresentação: edite o nome da coluna;
- Largura em %: deixe 'padrão' para uma divisão igual da largura entre as colunas. Caso contrário, informe em porcentagem a largura de cada coluna;
- Visível: ligador por padrão, é possível ocultar uma coluna sem precisar alterar a query;
- Prefixo: é possível incluir um texto antes dos valores dessa coluna;
- Sufixo: é possível incluir um texto depois dos valores dessa coluna;
- Informação no rodapé: 
    - Cálculo: é possível fazer um cálculo (numérico ou hora) e informar no rodapé da coluna. Os valores nessa coluna precisam ser do tipo inteiro ou decimal (para cálculo numérico) ou estar no formato de hora HH:mm (para cálculo em hora)
    - Máscara: caso o cálculo seja numérico, escolha a máscara apropriada para o resultado. Para cálculo em hora, a máscara HH:mm é preenchida automaticamente.

##### Ordenação

Selecione o campo que será ordenada as informações, e escolha se a ordenação é crescente ou decrescente.

##### Paginação

Escolha a quantidade de registros por página.

##### Header

Permite mostrar ou não o cabeçalho da tabela;

##### Link da Linha

É possível redirecionar o usuário caso haja um click na linha. Esse link pode ser interno no agilityflow ou externo. Caso seja interno, é possível escolher se o link será aberto como:

- Um lightbox;
- Na mesma janela;
- Uma nova janela;

##### Tabelas de dados filha (Master e Detail)

Além de uma tabela, é possível agrupar uma tabela em cada linha dessa primeira tabela, configurada no exemplo acima.

[![tabela_filha_widget.gif](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/tabela_filha_widget.gif)](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/tabela_filha_widget.gif)

Para isso, basta adicionar uma tabela de dados filha. Ao fazer isso, o mesmo processo de configuração de uma tabela de dados comum é iniciado, mas com uma diferença.

Caso essa tabela filha tenha relação com a tabela principal, basta obter a coluna id na query da tabela principal. Esse valor, é passado para a tabela filha, em uma variável chamada @master\_id.

No exemplo acima, ao clicar no nome do autor, é apresentado a lista de livros cadastradas no sistema relacionados com esse autor. A query ficaria assim:

```SQL
select x_tbl_livro.nome as NomeLivro, x_tbl_livro.ano as Ano from x_autor_livro 
inner join x_tbl_livro on id_x_tbl_livro = x_tbl_livro.id
where id_x_tbl_autor = @master_id
```

<p class="callout info">A tabela filha, apesar de recomendado, não precisa ter relação com a tabela principal.</p>

# Dashboard

O dashboard é um painel que traz informações rápidas do sistema. É a tela inicial do agilityflow.

O propósito do dashboard é levar ao usuário informações de rápida visualização para uma tomada imediata de decisões.

Ao criar um Dashboard, é necessário informar um nome e uma descrição. Além disso, é necessário atribuir um ou mais [perfis](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/perfil-de-acesso "Perfil de Acesso"), que irão acessar esse dashboard.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552413429118.png)

Ao clicar em 'Montar Dashboard', basta adicionar os [widgets](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/widget "Widget") que deverão aparecer nesse dashboard e clicar em confirmar.

# Widget

Widget é um elemento gráfico de interação, e fornecem funcionalidades e/ou informações ao usuário.

No agilityflow, são os elementos que compõem um [dashboard](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/dashboard "Dashboard").

Ao se criar um widget, é necessário definir algumas informações básicas.

- Tipo: existem dois tipos de widgets: 
    - Nativo: o tipo Nativo é reservado para futuras implementações de widgets nativos do sistema, como o de [rascunhos](http://wiki.agilityflow.io/link/64#bkmrk-rascunhos) e o de [pendências](http://wiki.agilityflow.io/link/64#bkmrk-pend%E3%AAncias). Essa opção não deve ser utilizada.
    - Customizado: é a opção que permite criar um widget sob-medida. Essa é a opção que deve ser utilizada.
- Nome: um nome para identificar o widget na montagem do [dashboard](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/dashboard "Dashboard").
- Descrição: um nome para ajudar na identificação do widget na montagem do [dashboard](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/dashboard "Dashboard").
- Categoria: escolha ou crie uma categoria, para organizar os widgets.
- Subcategoria: escolhe ou crie uma subcategoria, para organizar os widgets.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552425461177.png)  
Ao adicionar o widget no dashboard, como no exemplo acima, é possível identificar o widget pelo nome (Pendências para aprovação), pela categoria (Fluxo de Aprovação), pela subcategoria (Aprovação) e pela descrição no quadro maior (em cinza).

- Ativo: é possível deixar um widget ativo ou inativo. Isso permite ao usuário não mais permitir o uso de um widget, sem a necessidade de removê-lo e posteriormente, caso necessário, ter que criá-lo novamente.
- Url (Mvc Action), altura e largura do Widget: essas opção estão disponíveis para widgets do tipo nativo. Não devem ser utilizadas.

## Montar o Widget

Quando se seleciona o tipo customizado, o botão 'Montar o Widget' fica disponível. Ao clicar, é possível configurar as características do widget.

Todo widget tem um título. Esse título pode ou não ser exibido, usando a opção 'Mostrar Título do Box'.

Outra opção, é a cor do tema. Ela pode ser escolhida na opção tema. As opções de cores são:

- Branco (padrão)
- Cinza
- Azul
- Verde
- Roxo
- Vermelho
- Amarelo

Para alterar o tamanho de um widget

### Adicionar elemento

Em um widget, é possível adicionar vários elementos, e de vários tipos.

#### Label

É um texto, que pode ser fixo ou dinâmico. Caso seja dinâmico, o texto deve ser o resultado de uma query SQL. Essa query vai ter seu resultado atribuído à variáveis. Para utilizá-las, basta escrever @ e selecionar a variável. É possível combinar textos com variáveis.

Caso seja fixo, basta digitar o texto normalmente.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552418764456.png)

Além disso, é possível formatar o texto de várias maneiras, como definir o alinhamento vertical e horizontal do texto, tamanho e fonte.

E por fim, é possível que ao clicar no texto, o usuário seja levado a um link. Basta preencher a URL.

<p class="callout info">Ao posicionar qualquer elemento no widget, é possível redimensioná-lo usando o ícone ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552419219771.png).</p>

#### Ícone

É possível adicionar um ícone como elemento de um widget. Basta selecionar um ícone em uma das bibliotecas disponíveis. Ainda é possível editar alinhamento (vertical e horizontal), tamanho, cor e criar um link.

#### Imagem

Para fazer o upload de uma imagem, basta clicar no retângulo ou arrastar um arquivo até ele.

É possível formatar largura, altura e alinhamento (vertical e horizontal) e criar um link.

#### Gráfico

Ao se adicionar um gráfico, é possível escolher entre duas origem dos dados:

##### Criar uma tabela com dados Estáticos

Nessa opção, o usuário define os dados de maneira manual em uma tabela, como uma planilha. É possível adicionar dados em linhas e colunas, usando os botões ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552426025629.png).

Ao clicar na opção 'Editar tipo e propriedades do gráfico' ou no ícone ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552426111935.png), é possível definir o tipo do gráfico.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552426283220.png)

O sistema já sugere o gráfico mais recomendado na guia início. Clicando na aba Gráficos (ou em 'Mais »'), o sistema exibe todos os demais gráficos disponíveis.

Na aba Personalizar é possível editar as características do gráfico selecionado, como título, legenda, fonte, cores, entre outros.

##### Fonte de dados Dinâmica

Nesse caso, é necessário criar uma query para se obter os dados. As demais configurações, seguem o padrão do exemplo acima.

#### Tabela de Dados

Quando o elemento é a tabela de dados, a fonte para essa tabela, só pode ser dinâmica, ou seja, através de uma query.

##### Query

No exemplo abaixo, queremos uma tabela com a lista de autores cadastrados no sistema. A query está obtendo os campos '*id*', '*nome*', 'sexo' e '*nacionalidade*' da tabela 'x\_*tbl\_autor*'.

```SQL
select nome, sexo, nacionalidade from x_tbl_autor
```

Esse é um exemplo de um resultado dessa query:

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552498185480.png)

Uma vez a query montada, é possível formatar a tabela.

##### Configuração das colunas da tabela

- Ordem das colunas: clique no ícone [![image-1552335541995.png](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552335541995.png)](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/image-1552335541995.png) e arraste a coluna para a posição desejada;
- Nome de apresentação: edite o nome da coluna;
- Largura em %: deixe 'padrão' para uma divisão igual da largura entre as colunas. Caso contrário, informe em porcentagem a largura de cada coluna;
- Visível: ligador por padrão, é possível ocultar uma coluna sem precisar alterar a query;
- Prefixo: é possível incluir um texto antes dos valores dessa coluna;
- Sufixo: é possível incluir um texto depois dos valores dessa coluna;
- Informação no rodapé: 
    - Cálculo: é possível fazer um cálculo (numérico ou hora) e informar no rodapé da coluna. Os valores nessa coluna precisam ser do tipo inteiro ou decimal (para cálculo numérico) ou estar no formato de hora HH:mm (para cálculo em hora)
    - Máscara: caso o cálculo seja numérico, escolha a máscara apropriada para o resultado. Para cálculo em hora, a máscara HH:mm é preenchida automaticamente.

##### Ordenação

Selecione o campo que será ordenada as informações, e escolha se a ordenação é crescente ou decrescente.

##### Paginação

Escolha a quantidade de registros por página.

##### Header

Permite mostrar ou não o cabeçalho da tabela;

##### Link da Linha

É possível redirecionar o usuário caso haja um click na linha. Esse link pode ser interno no agilityflow ou externo. Caso seja interno, é possível escolher se o link será aberto como:

- Um lightbox;
- Na mesma janela;
- Uma nova janela;

##### Tabelas de dados filha (Master e Detail)

Além de uma tabela, é possível agrupar uma tabela em cada linha dessa primeira tabela, configurada no exemplo acima.

[![tabela_filha_widget.gif](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/tabela_filha_widget.gif)](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/tabela_filha_widget.gif)

Para isso, basta adicionar uma tabela de dados filha. Ao fazer isso, o mesmo processo de configuração de uma tabela de dados comum é iniciado, mas com uma diferença.

Caso essa tabela filha tenha relação com a tabela principal, basta obter a coluna id na query da tabela principal. Esse valor, é passado para a tabela filha, em uma variável chamada @master\_id.

No exemplo acima, ao clicar no nome do autor, é apresentado a lista de livros cadastradas no sistema relacionados com esse autor. A query ficaria assim:

```SQL
select x_tbl_livro.nome as NomeLivro, x_tbl_livro.ano as Ano from x_autor_livro 
inner join x_tbl_livro on id_x_tbl_livro = x_tbl_livro.id
where id_x_tbl_autor = @master_id
```

<p class="callout info">A tabela filha, apesar de recomendado, não precisa ter relação com a tabela principal.</p>

# Tabela Relacional (N:N)

#### O Conceito N:N

A tabela relacional N:N, trás um conceito importante e fundamental em banco de dados.

Diferente do relacionamento 1:N, que no agilityflow é utilizado nos [formulários relacionados](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/formul%C3%A1rios-relacionados "Formulários Relacionados"), onde uma entidade pode se relacionar com várias ocorrências de outra entidade, o relacionamento N:N ocorre quando vários registros de uma tabela (formulário) se relacionam com vários registros de uma outra tabela.

<p class="callout info">No relacionamento N:N, não há uma hierarquia de relacionamento.</p>

#### Exemplo

Por exemplo, um autor pode escrever vários livros. Um livro pode ter vários autores.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552339079109.png)

Quando existe esse relacionamento, surge uma terceira tabela. A essa tabela, damos o nome de Tabela Relacional (N:N).

#### Criando uma tabela relacional (n:n)

Para criar uma tabela relacional (n:n) no agilityflow, primeiro crie ambos formulários comuns. Depois, no Devcenter, clique em Tabela Relacional (N:N) e em seguida em 'Novo'.

##### Dados

Descrição

Nome da Tabela Banco de dados SQL (Adicionar prefixo x)

##### Formulário relacionado 1 (FK1)

Formulário 1: escolha o primeiro formulário do relacionamento (a ordem não importa)  
Título da tabela que será apresentado no formulário para o usuário: esse é o texto que será apresentado como título, quando o formulário 1 aparecer dentro do formulário 2.  
Campo principal para o usuário buscar e associar ao formulário: o campo que será usado para o usuário fazer a associação  
Tipo do campo principal: selecione sempre Lista de seleção (Combo)

##### Formulário relacionado 2 (FK2)

Formulário 2: escolha o segundo formulário do relacionamento (a ordem não importa)  
Título da tabela que será apresentado no formulário para o usuário: esse é o texto que será apresentado como título, quando o formulário 2 aparecer dentro do formulário 1.  
Campo principal para o usuário buscar e associar ao formulário: o campo que será usado para o usuário fazer a associação  
Tipo do campo principal: selecione sempre Lista de seleção (Combo)

Clique em Salvar e pronto, a tabela está criada.

<p class="callout danger">Não esqueça de adicionar a tabela relacional (N:N) criada agora, em ambos os formulários.</p>

# Cache

Para aumentar a performance da plataforma, o agilityflow gera cache de alguns dados no servidor. O cache é formado por dados que não mudam com frequência. Caso esses dados mudem, o cache é apagado e re-criado no próximo carregamento.

> O que é armazenado em cache?

São esses dados:

- Formulários
- Relatórios
- Cofiguração das API's
- Dashboard e widgets

Para ilustrar, imagine a estrutura de um formulário, como seus campos, relatórios de impressão, listagem de dados e tela. Essas configurações não mudam com frequência, mas a sua leitura é custosa para o servidor. Por isso, no primeiro acesso, os dados de um formulário são armazenados em cache, para que na próxima leitura, não precise ser feito todo o acesso à base de dados para mostrar o formulário corretamente.

Posteriormente, ao fazer uma modificação no formulário, no salvamento, o servidor apaga os dados do cache, e os reescreve no primeiro acesso. Isso explica um tempo mais logo para o primeiro carregamento de um formulário após a criação ou modificação.

> Como posso atualizar o cache do servidor?

De duas formas: a primeira é alterar qualquer um dos dados listados acima. Quando isso ocorre, apenas o cache relacionado ao dado alterado é atualizado.

A segunda forma, basta acessar a opção de Cache no devcenter, selecionar os dados que deseja apagar e clicar em "Atualizar Cache".

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552945906617.png)

> Existe uma periodicidade de alteração do cache?

Não. O cache somente é atualizado em umas das duas formas citadas acima.

# API de Integração GET e POST

<p class="callout info">Para a documentação de programação em C# nas APIs de POST, [clique aqui](https://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/programa%C3%A7%C3%A3o-em-c---na-api-de-integra%C3%A7%C3%A3o "Programação em C# - Na API de integração")</p>

<p class="callout warning">Para Informações sobre o Timezone das Apis (fuso horário), [clique aqui](https://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/timezone-%28fuso-horario-do-sistema%29 "Timezone (Fuso Horario do sistema)")</p>

O termo API vem da abreviação do termo em inglês Application Programming Interface ou Interface de Programação de Aplicativos, o que resumidamente, significa uma forma de dois sistemas se conectarem entre si.

O agilityflow possui API Rest para que outros sistemas e aplicativos se conectem e interajam com o agilityflow. Essa interação ocorre usando dois métodos:

- **GET**: para outros sistema consumirem os dados do Agilityflow (Buscar informações)
- **POST**: para inserir e atualizar dados de outros sistemas no Agilityflow (Input de informações)

> Como posso configurar uma API no agilityflow?

Um pré-requisito para configurar uma API no agilityflow, é criar um usuário que tenha permissão para executar essa API remotamente.

### Usuário da API

Para criar um usuário da API, basta acessar o devcenter, e no quadro da API, criar em '**Usuários da Api**':

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1617204839548.png)

Ao clicar nessa tela, é apresentada a lista de usuários, onde é possível filtrar e interagir como em qualquer formulário. No topo, clique em 'Novo' e informe os seguintes dados:

- Nome: um nome para identificar o usuário. **Sugestão**: caso seja um sistema legado que irá chamar essa api, crie esse usuário com o nome do sistema legado.
- Login: nome do usuário;
- Chave de segurança: chave de acesso do usuário. Essa chave, ficará visível para que possa ser consultada e informada ao outro sistema que irá fazer uso da API;
- API: caso já exista uma API configurada, pode ser adicionada permissão a ela nesse momento;

### Configurar uma API

Acesse API de integração no devcenter e clique em [![image-1549032455512.png](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/scaled-840-0/image-1549032455512.png)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/image-1549032455512.png) e em seguida clique em "Novo". Preencha os dados que seguem:

- Nome: identifica a configuração da API;
- Método: Post ou Get. Mais informações no próximo capítulo;
- Tipo de execução: selecione síncrona. A opção assíncrona ainda não está implementada;
- Ativo: marque para deixar habilitada, ou desmarque para desabilitar a API;
- Usuário API: selecione os usuários de API com acesso à essa configuração, e clique em [![image-1549032455512.png](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/scaled-840-0/image-1549032455512.png)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/image-1549032455512.png).

### Listar (Get) - Buscar de um formulário (versão sem uso de código)

Com esse método, você pode buscar qualquer tipo de informação de um determinado formulário.

No cadastro de API, marque o método como "Get" e clique na opção "Configurar API para Listagem"

![](https://wiki.agilityflow.io/uploads/images/gallery/2020-03-Mar/scaled-840-0/image-1583944075313.png)

Agora associe o usuário que você criou no passo anterior, para que ele tenha acesso de execução nessa API.

Na opção configurar API para listagem, selecione o formulário que você deseja recuperar os dados.

**<span style="color: #808080;">Filtros da API de GET pelo Id do formulário</span>**

<span style="color: #808080;">Além da lista completa e paginada, v</span><span style="color: #808080;">ocê pode filtrar por ID ou por IDs.</span>

<span style="color: #808080;">Todos os Ids do agilityflow são no formato de GUID, exemplo de um id: "43837013-be24-4bc9-81c1-b4cdcb6eb3dc"</span>

<span style="color: #808080;">Você pode filtrar por um ou mais ids em uma mesma chamada de API, para isso, basta</span><span style="color: #808080;"> enviar o parâmetro **id ou ids** colocando os ids, divididos por virgula, exemplo: </span>

`<span style="color: #000000;">id=43837013-be24-4bc9-81c1-b4cdcb6eb3dc,59a26b8b-6c32-4756-acb7-c1539baf65de,b9199893-7021-1446-f407-942c97d70b74</span>`

<span style="color: #808080;">ou apenas 1 id</span>

`<span style="color: #000000;">id = b9199893-7021-1446-f407-942c97d70b74</span>`

**<span style="color: #808080;">Filtros por campos do formulario</span>**

<span style="color: #808080;">Você pode filtrar por qualquer campo do formulário, os comandos de filtro são similares aos comandos de consulta do sql server e devem estar entre chaves { }</span>

`<span style="color: #000000;">filter={campo_de_numero>2 and campo_de_numero<20 and ( campo_texto='jose' or campo_texto like '%sei%' ) }</span>`

**Lembre-se: que a url da API deve estar com os caracteres especiais com enconded, exemplo da query acima na url:**

`filter={(campo_de_numero%3E2%20and%20campo_de_numero%3C20)%20and%20(%20campo_texto=%27jose%27%20or%20campo_texto%20like%20%27%sei%%27%20)%20}`

**<span style="color: #808080;">Paginação da API de GET</span>**

<span style="color: #808080;">A paginação da API é feita a cada 10 registros, para buscar a próxima página é só enviar o parâmetro **nextPage** colocando o número da página que você deseja buscar, exemplo: </span>

`<span style="color: #000000;">nextPage=2</span>`

**<span style="color: #808080;">Ordenação da API de GET</span>**

<span style="color: #808080;">É possível ordernar os dados de retorno da API usando os 2 parâmetros abaixo, exemplo: </span>

`<span style="color: #000000;"><strong>sortBy</strong>=id_do_campo</span>`

`<span style="color: #000000;"><strong>sortDirection</strong>=ASC </span>` ou <span style="color: #000000;">`<strong>sortDirection</strong>=DESC`</span>

**<span style="color: #808080;">Estrutura de retorno da API de GET</span>**

*<span style="color: #808080;">\* por uma questão de performance da API. O campo TotalRecords não será mais retornado desde Jan/2024</span>*

```JSON
{
    "paging": {
        "pageSize": 10,    	//tamanho da paginação, considere sempre 10
        "pageNumber": 1    	//página atual
        "nextPage": 2    	//próxima página a ser chamada
    },
    "result": [
        {
            "formId": "43837013-be24-4bc9-81c1-b4cdcb6eb3dc",  		//Campo Padrão: Id do formulário          
          	"createdDate": "2020-03-10 22:41:28",					//Campo Padrão: Data de criação do formulário
            "createdBy": "59a26b8b-6c32-4756-acb7-c1539baf65de",	//Campo Padrão: Id do Usuário responsável pela criação do formulário
            "modifiedDate": "2020-03-10 22:47:58",					//Campo Padrão: Data da última alteração do formulário
            "modifiedBy": "59a26b8b-6c32-4756-acb7-c1539baf65de",	//Campo Padrão: Id do Usuário responsável pela última alteração do formulário
            "workflow": {
                "currentSteps": [
                    {
                        "id": "ede6740b-b4b8-21f7-e9c3-4f765620a213",  //Campo Padrão: Id da Etapa atual do fluxo
                        "name": "Tax Payment "                              //Campo Padrão: Nome da Etapa atual do fluxo
                    },
                    {
                        "id": "9c334289-47e8-49da-93a9-c2e4871e4c3d",  //Campo Padrão: Id da Etapa atual do fluxo
                        "name": "Payment deal"                              //Campo Padrão: Nome da Etapa atual do fluxo
                    }
                  ],
                  "status": "P",									//Campo Padrão: Status do fluxo, será "A", "X" ou "P"
                  "statusName": "In progress",						//Campo Padrão: Status Name será, "Approved", "Rejected", "In progress"
             },                      
            "data": {												//Dados e campos do formulário: Muda de acordo com os campos do formulário
                "name": "john",
                "email": "john@example.com",
              	"age": "35",
              
            }
        }
    ]
}
```

Pronto! Agora é só executar.

### Cadastrar (Post)

Com esse método, você pode inserir e atualizar dados nos formulários do seu Agilityflow, aqui você deve definir o mapeamento dos dados (DE - PARA) em C#, explicitando como será feito o cadastro dos dados, quando essa API for acionada.

No cadastro de API, marque o método como "Post" e clique na opção "Configurar API para Cadastro (Post)"

![](https://wiki.agilityflow.io/uploads/images/gallery/2020-03-Mar/scaled-840-0/image-1583944329464.png)

Agora associe o usuário que você criou no passo anterior, para que ele tenha acesso de execução nessa API.

Na opção configurar API, selecione o formulário que você deseja recuperar os dados.

O código abaixo exemplifica como configurar uma API de Cadastro

<p class="callout info">Para a documentação de programação em C# nas APIs de POST, [clique aqui](https://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/programa%C3%A7%C3%A3o-em-c---na-api-de-integra%C3%A7%C3%A3o "Programação em C# - Na API de integração")</p>

```C#
    public async Task RunAsync(){
        
            //converte o conteúdo enviado no body da API para JSON
            var json = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(content);
      
            //guarda em uma variável o ID da estrutura do formulário Cliente
            var idEstruturaFormulario_CLIENTE = Guid.Parse("0b56b66a-4f6f-4ded-ad04-016d7c0724e1");
    
      		await ApiContext.LogAsync("Log Message", "logtype");   
    
            if (json != null)
            {
    
                    //verifica se o JSON recebido contém a propriedade "nome", "email" e "cel" que são necessários p cadastro
                    if (JsonHelper.HasProperty(json, "nome") && JsonHelper.HasProperty(json, "email") && JsonHelper.HasProperty(json, "cel")){
           
                        var values = new DataDictionary();
                        values.Add("nome", json["nome"].ToString());
                        values.Add("email", json["email"].ToString());
                        values.Add("cel", json["cel"].ToString());
                      
                        //salva a informação no banco de dados
                        var id = await ApiContext.SaveEntityAsync(idEstruturaFormulario_CLIENTE, values);
                        
                    }
                
            }

    		await ApiContext.LogAsync("Log Message", "logtype");
    
    }
```

### Status Header de retorno de uma API

<table border="1" id="bkmrk-cod.-mensagem-descri" style="border-collapse: collapse; width: 99.9999%; height: 318px;"><tbody><tr style="height: 31px;"><td style="width: 12.2222%; height: 31px;">**Cod.**</td><td style="width: 19.1358%; height: 31px;">**Mensagem**</td><td style="width: 68.6419%; height: 31px;">**Descrição**</td></tr><tr style="height: 37px;"><td style="width: 12.2222%; height: 37px;">400</td><td style="width: 19.1358%; height: 37px;">BadRequest</td><td style="width: 68.6419%; height: 37px;">Houve algum erro inesperado pela API, verifica se em alguma programação existe um erro de sintaxe ou algo parecido.

</td></tr><tr style="height: 176px;"><td style="width: 12.2222%; height: 176px;">401</td><td style="width: 19.1358%; height: 176px;">Unauthorized</td><td style="width: 68.6419%; height: 176px;">Possíveis causas:

- Provavelmente o usuário API que você está tentando executar não tem permissão para essa execução.
- O Accesstoken que você está usando para executar a API está vencido. O AccessToken tem uma duração máxima de 1 hora, após esse período é necessário cria-lo novamente.
- Ou você estar tentando executar uma API que não está configurada

</td></tr><tr style="height: 37px;"><td style="width: 12.2222%; height: 37px;">404</td><td style="width: 19.1358%; height: 37px;">Not Found</td><td style="width: 68.6419%; height: 37px;">Api não encontrada

</td></tr><tr><td style="width: 12.2222%;">405</td><td style="width: 19.1358%;">Method Not Allowed</td><td style="width: 68.6419%;">Possíveis causas:

- Provavelmente o usuário API que você está tentando executar não tem permissão para essa execução.
- O Accesstoken que você está usando para executar a API está vencido. O AccessToken tem uma duração máxima de 1 hora, após esse período é necessário cria-lo novamente.
- Ou você estar tentando executar uma API que não está configurada

</td></tr><tr style="height: 37px;"><td style="width: 12.2222%; height: 37px;">200</td><td style="width: 19.1358%; height: 37px;">Ok</td><td style="width: 68.6419%; height: 37px;">Deu tudo certo.

</td></tr></tbody></table>

## Exemplos de execução da API

### Exemplo GET via o software "POSTMAN"

Importe o JSON abaixo no seu Postman para executar os exemplos abaixo.

```JSON
{
	"info": {
		"_postman_id": "bd36812d-37c9-4e08-9bc0-bdc28a073fcc",
		"name": "Agilityflow API GET",
		"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
	},
	"item": [
		{
			"name": "1. Obter AccessToken",
			"request": {
				"method": "POST",
				"header": [
					{
						"key": "Content-Type",
						"value": "application/json"
					}
				],
				"body": {
					"mode": "raw",
					"raw": "{\"username\": \"NOME_DO_USUARIO_API__COM_PERMISSAO_NESSA_API\",\"key\": \"CHAVE_DE_SEGURANÇA_DO_USUARIO_API__COM_PERMISSAO_NESSA_API\"}"
				},
				"url": {
					"raw": "https://XXXXXXXXXXXXXXXXX.agilityflow.io/api/accesstoken?",
					"protocol": "https",
					"host": [
						"XXXXXXXXXXXXXXXXX",
						"agilityflow",
						"io"
					],
					"path": [
						"api",
						"accesstoken"
					],
					"query": [
						{
							"key": "",
							"value": "",
							"disabled": true
						},
						{
							"key": "",
							"value": "",
							"disabled": true
						}
					]
				}
			},
			"response": []
		},
		{
			"name": "2. Get API",
			"protocolProfileBehavior": {
				"disableBodyPruning": true
			},
			"request": {
				"method": "GET",
				"header": [
					{
						"key": "Authorization",
						"value": "Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3VzZXJkYXRhIjoiOTdmZTM1NmItMDA5OC00ZTlhLTkwNTUtODMwMTA3YzM5NjA1IiwibmFtZWlkIjoibG9jYWxob3N0IiwibmJmIjoxNTY0NDI4NTk5LCJleHAiOjE1NjQ0Mjg2NTksImlhdCI6MTU2NDQyODU5OX0.ul7Emi7KDepfmRwWO91RQcTZQrc8r3xlMKJnLYcduEKeNRDGC7F15_-YojHfm1ogM32LjUV76MWxNXTLeJTrLw"
					},
					{
						"key": "Content-Type",
						"name": "Content-Type",
						"type": "text",
						"value": "application/json"
					}
				],
				"body": {
					"mode": "raw",
					"raw": "{\n\n}"
				},
				"url": {
					"raw": "https://XXXXXXXXXXXXXXXXX.agilityflow.io/api/data/g5e262bd-912a-4b1f-91cb-58815cfc5556?nextPage=1",
					"protocol": "https",
					"host": [
						"XXXXXXXXXXXXXXXXX",
						"agilityflow",
						"io"
					],
					"path": [
						"api",
						"data",
						"g5e262bd-912a-4b1f-91cb-58815cfc5556"
					],
					"query": [
						{
							"key": "nextPage",
							"value": "1"
						}
					]
				}
			},
			"response": []
		}
	]
}
```

Após a importação no Postman você precisará seguir alguns passos:

**Passo 1**

No Postman, abra o exemplo **"1. Obter Accesstoken"**

**Passo 2**

Você precisará fazer algumas mudanças.

**(1)** Troque o **XXXXXX**.agilityflow.io pelo seu subdomínio no agilityflow;

**(2)** Na aba "body", Troque o usuário e a chave de segurança da API que você criou. como na imagem abaixo:

![](https://wiki.agilityflow.io/uploads/images/gallery/2020-03-Mar/scaled-840-0/image-1584384862168.png)

**Passo 3 - Obter Access token para execução da API**

Por segurança, antes de cada execução de API é necessário que você gere um token para validação do usuário.

Então, agora execute essa API.

Copie o código retornado no JSON na propriedade "accessToken", usaremos esse código a seguir.

**Passo 4**

No Postman, abra o exemplo **"2. Get API"**

**Passo 5**

Você precisará fazer algumas mudanças.

**(1)** Troque o **XXXXXX**.agilityflow.io pelo seu subdomínio no agilityflow;

**(2)** Na aba "headers", clique no VALUE da Key "Authorization" e cole o código "accessToken" que geramos nos passos acima, após a palavra "Bearer ". Então o valor deverá ficar "**Bearer Accesstoken\_que\_você\_colou**".

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-07-Jul/scaled-840-0/image-1564430466896.png)

**(3)** Troque o Id da API "/data/**g5e262bd-912a-4b1f-91cb-58815cfc5556"** de exemplo pelo id da API que você acabou de criar no Agilityflow.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-07-Jul/scaled-840-0/image-1564430513461.png)

Então, agora execute a API para visualizar os dados retornados, você pode também consultar o Log de API do agilityflow para acompanhar todas as requisições

### Exemplo em NODE de POST

Suponhamos que temos uma API no agilityflow que cadastra um cliente, as informações que a API espera é "NOME", "EMAIL" e "CEL" (celular).

O código abaixo demonstra como é feita a chamada da API através do NODE.

Para executar, é necessário ter o NODE instalado. O pacote utilizado é o "https".

Para rodar o script basta copia-lo, salvar em um arquivo com extensão .JS (exemplo: script.js) abrir o prompt de comando e executar o script da seguinte forma:

```MarkDown
node "C:\teste\script.js"
```

Abaixo o script NODE:

Para configura só troque as 4 variáveis de configuração com as seguintes informações:

<div id="bkmrk-hostname%3A%E2%A0substitua">- ****hostname:**** substitua pela sua URL do seu agilityflow
- ****accessToken\_Credential:**** aqui você coloca as credenciais (usuário da API) para execução
- ****apiID:**** id da api
- ****apiParameterBODY:**** json com as informações que você deseja enviar para API

</div>```JavaScript
var http = require("https");



//config
var hostname = 'demo123.agilityflow.io'; //substitua pela sua URL do seu agilityflow
var accessToken_Credential = { username: 'teste', key: 'teste' }; //aqui você coloca as credenciais (usuário da API) para execução 
var apiID = 'e8b5b751-774d-4283-855c-fafb8e11236d'; //id da api
var apiParameterBODY = { nome: 'JOSE DA SILVA', email: 'josedasilva@email.com.br', cel: '1199887766' } //body json com as informações que você deseja enviar para API



//recuperar o access token
function ExecuteRecuperarAccessToken(){

    var options = {
        hostname: hostname,
        // port: 443,
        path: '/api/accesstoken',
        method: 'POST',
        headers: {
            "Content-Type": "application/json",
            "cache-control": "no-cache"
           }
      };
      
    var req = http.request(options, function (res) {
      var chunks = [];
    
      res.on("data", function (chunk) {
        chunks.push(chunk);
      });
    
      res.on("end", function () {
        var body = Buffer.concat(chunks);
        var obj = JSON.parse(body);      
        if(obj.success){    
            console.log("Recuperou o Access Token",obj.accessToken);   
            ExecuteAPI(obj.accessToken) 
        }else
            LogErro("execução do access token", body.toString());            
    
      });
    });
    
    req.write(JSON.stringify(accessToken_Credential));
    req.end();
    

}




//execute a API
function ExecuteAPI(accessToken){


    var options = {
        hostname: hostname,
        // port: 443,
        path: '/api/data/'+apiID,
        method: 'POST',
        headers: {
          "Authorization": "Bearer " + accessToken,
          "Content-Type": "application/json",
            "cache-control": "no-cache"
        }
      };


      
      var req_api = http.request(options, function (res_api) {
        var chunks_api = [];
      
        res_api.on("data", function (chunk) {
          chunks_api.push(chunk);
        });
      
        res_api.on("end", function () {
          var body = Buffer.concat(chunks_api);
          var obj = JSON.parse(body);      
          if(obj.success){    
              console.log("Execução realizada com sucesso:" + body.toString());   
          }else
              LogErro("execução da api", body.toString());  
        });
      });
      
      req_api.write(JSON.stringify(apiParameterBODY));
      req_api.end();

}


function LogErro(local,log){

    console.log('==================================================================================')
    console.log('E R R O - ' + local)
    console.log('----------------------')
    console.log(log);
    console.log('==================================================================================')

}

ExecuteRecuperarAccessToken();
```

### Exemplo em PHP de POST

Suponhamos que temos uma API no agilityflow que cadastra um cliente, as informações que a API espera é "NOME", "EMAIL" e "CEL" (celular).

O código abaixo demonstra como é feita a chamada da API através do PHP.

```PHP
<?php
// header('Content-Type: application/json');


if( !isset($_POST['nome']) ||  !isset($_POST['email']) ||  $_POST['nome'] == '' ||  $_POST['email'] == '')
{
  echo '{"success": "false", "msg": "Informe o nome e o e-mail"}';
  exit(0);
}


$nome = $_POST['nome'];
$email = $_POST['email'];

$novoLead = new StdClass();
$novoLead->nome = $nome ;
$novoLead->email = $email ;
$novoLead->cel = $_POST['cel'];

$novoLead_string = json_encode($novoLead);






                  //////////////////////////////////// 01. BUSCAR O ACCESS TOKEN


                  $curl = curl_init();
        

                  curl_setopt_array($curl, array(
                    CURLOPT_URL => "https://XXXXXXXXXXXXXXX.agilityflow.io/api/accesstoken",
                    CURLOPT_RETURNTRANSFER => true,
                    CURLOPT_ENCODING => "",
                    CURLOPT_MAXREDIRS => 10,
                    CURLOPT_TIMEOUT => 30,
                    //------------- SLL 
                    CURLOPT_SSL_VERIFYPEER => 0,
                    CURLOPT_SSL_VERIFYHOST => 0,
                    //--------------------------
                    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
                    CURLOPT_CUSTOMREQUEST => "POST",
                    CURLOPT_POSTFIELDS => "{\"username\": \"cadastrar_teste_1\",\"key\": \"cadastrar_teste_1\"}",
                    CURLOPT_HTTPHEADER => array(
                      "Content-Type: application/json",
                      "cache-control: no-cache"
                    ),
                  ));


                  $response = curl_exec($curl);
                  $err = curl_error($curl);

                  curl_close($curl);


                  if ($err) {
                    echo '{"success": "false", "msg": "Não conseguimos finalizar seu cadastro. Por favor tente novamente. (0)" }';
                    exit(0);
                  }

                  $json_RESPONSE_ACCESS_TOKEN = json_decode($response);

                  if (!isset($json_RESPONSE_ACCESS_TOKEN->accessToken)){
                      echo '{"success": "false", "msg": "Não conseguimos finalizar seu cadastro. Por favor tente novamente. (1)" }';
                      exit(0);
                    }



                //////////////////////////////////// 02. EXECUTA O POST


                $curl = curl_init();

                curl_setopt_array($curl, array(
                  CURLOPT_URL => "https://XXXXXXXXXXXXXXX.agilityflow.io/api/data/b3bf7ce3-f226-4500-83cd-2873b050c742",
                  CURLOPT_RETURNTRANSFER => true,
                  CURLOPT_ENCODING => "",
                  CURLOPT_MAXREDIRS => 10,
                  CURLOPT_TIMEOUT => 30,
                  //------------- SLL 
                  CURLOPT_SSL_VERIFYPEER => 0,
                  CURLOPT_SSL_VERIFYHOST => 0,
                  //--------------------------
                  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
                  CURLOPT_CUSTOMREQUEST => "POST",
                  CURLOPT_POSTFIELDS => $novoLead_string,
                  CURLOPT_HTTPHEADER => array(
                    "Authorization: bearer ".$json_RESPONSE_ACCESS_TOKEN->accessToken,
                    "Cache-Control: no-cache",
                    "Content-Type: application/json"
                  ),
                ));

                $response = curl_exec($curl);
                $err = curl_error($curl);

                curl_close($curl);

                if ($err) {
                  echo '{"success": "false", "msg": "Não conseguimos finalizar seu cadastro. Por favor tente novamente. (2)" }';
                  exit(0);
                }



                $json_RESPONSE_SUCCESS = json_decode($response);

                if (!isset($json_RESPONSE_SUCCESS->success)){
                  echo '{"success": "false", "msg": "Não conseguimos finalizar seu cadastro. Por favor tente novamente. (3)" }';
                  exit(0);
                }


                if ($json_RESPONSE_SUCCESS->success == false){
                  echo '{"success": "false", "msg": "Não conseguimos finalizar seu cadastro. Por favor tente novamente. (4)" }';
                  exit(0);
                }


                echo '{"success": "true", "msg": "Obrigado, recebemos seus dados aqui e já já nos falamos..." }';


                  

```

### Exemplo POST via o software "POSTMAN"

Importe o JSON abaixo no seu Postman para executar os exemplos abaixo.

```JSON
{
	"info": {
		"_postman_id": "39445fe2-1bea-46b2-9045-b32337b10030",
		"name": "Agilityflow API",
		"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
	},
	"item": [
		{
			"name": "1. Obter Accesstoken",
			"request": {
				"method": "POST",
				"header": [
					{
						"key": "Content-Type",
						"value": "application/json"
					}
				],
				"body": {
					"mode": "raw",
					"raw": "{\"username\": \"NOME_DO_USUARIO_API__COM_PERMISSAO_NESSA_API\",\"key\": \"CHAVE_DE_SEGURANÇA_DO_USUARIO_API__COM_PERMISSAO_NESSA_API\"}"
				},
				"url": {
					"raw": "https://XXXXXXXXXXXXXXXXX.agilityflow.io/api/accesstoken?",
					"protocol": "https",
					"host": [
						"XXXXXXXXXXXXXXXXX",
						"agilityflow",
						"io"
					],
					"path": [
						"api",
						"accesstoken"
					],
					"query": [
						{
							"key": "",
							"value": "",
							"disabled": true
						},
						{
							"key": "",
							"value": "",
							"disabled": true
						}
					]
				}
			},
			"response": []
		},
		{
			"name": "2. Post API",
			"request": {
				"method": "POST",
				"header": [
					{
						"key": "Authorization",
						"value": "Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3VzZXJkYXRhIjoiOTdmZTM1NmItMDA5OC00ZTlhLTkwNTUtODMwMTA3YzM5NjA1IiwibmFtZWlkIjoibG9jYWxob3N0IiwibmJmIjoxNTY0NDI4NTk5LCJleHAiOjE1NjQ0Mjg2NTksImlhdCI6MTU2NDQyODU5OX0.ul7Emi7KDepfmRwWO91RQcTZQrc8r3xlMKJnLYcduEKeNRDGC7F15_-YojHfm1ogM32LjUV76MWxNXTLeJTrLw"
					},
					{
						"key": "Content-Type",
						"name": "Content-Type",
						"value": "application/json",
						"type": "text"
					}
				],
				"body": {
					"mode": "raw",
					"raw": "{\n\n\t\t\t\"id\": \"345b65d7-4c99-426c-95fc-1dd8de76cc9d\",\n\t\t\t\"nome\": \"_123458910Cargo LEGALLLLL \"\n\t\n}"
				},
				"url": {
					"raw": "https://XXXXXXXXXXXXXXXXX.agilityflow.io/api/data/b3bf7ce3-f226-4500-83cd-2873b050c742",
					"protocol": "https",
					"host": [
						"XXXXXXXXXXXXXXXXX",
						"agilityflow",
						"io"
					],
					"path": [
						"api",
						"data",
						"b3bf7ce3-f226-4500-83cd-2873b050c742"
					]
				}
			},
			"response": []
		}
	]
}
```

Após a importação no Postman você precisará seguir alguns passos:

**Passo 1**

No Postman, abra o exemplo **"1. Obter Accesstoken"**

**Passo 2**

Você precisará fazer algumas mudanças.

**(1)** Troque o **XXXXXX**.agilityflow.io pelo seu subdomínio no agilityflow;

**(2)** Na aba "body", Troque o usuário e chave de segurança da API que você criou. como na imagem abaixo:

![](https://wiki.agilityflow.io/uploads/images/gallery/2020-03-Mar/scaled-840-0/image-1584384862168.png)

**Passo 3 - Obter Access token para execução da API**

Por segurança, antes de cada execução de API é necessário que você gere um token para validação do usuário.

Então, agora execute essa API.

Copie o código retornado no JSON na propriedade "accessToken", usaremos esse código a seguir.

**Passo 4**

No Postman, abra o exemplo **"2. Post API"**

**Passo 5**

Você precisará fazer algumas mudanças.

**(1)** Troque o **XXXXXX**.agilityflow.io pelo seu subdomínio no agilityflow;

**(2)** Na aba "headers", clique no VALUE da Key "Authorization" e cole o código "accessToken" que geramos nos passos acima, após a palavra "Bearer ". Então o valor deverá ficar "**Bearer Accesstoken\_que\_você\_colou**".

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-07-Jul/scaled-840-0/image-1564430466896.png)

**(3)** Troque o Id da API "/data/**b3bf7ce3-f226-4500-83cd-2873b050c742"** de exemplo pelo id da API que você acabou de criar no Agilityflow.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-07-Jul/scaled-840-0/image-1564430513461.png)

**(4)** Na aba "body" você pode trocar os valores que você deseja inserir ou atualizar:

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-07-Jul/scaled-840-0/image-1564430624189.png)

Então, agora execute essa API e entre no seu log de API do agilityflow para acompanhar e verificar se deu certo

# Variáveis de ambiente

Nessa tela de variáveis de ambiente você definirá informações (variáveis globais) que ficarão disponíveis em diversas partes do seu sistema.

Suponha que você queira que a Data de Nascimento do usuário logado esteja disponível para acesso via Javascript nos seus formulários ou você quer usar essa informação em algum parâmetro de entrada de uma Query, em relatórios ou dashboards.

Para isso basta criar uma variável do tipo "SQL Simples (Valor único)"; defina o nome para a variável, nesse caso, utilize "**var\_dataNascimento";** marque como **SIM** a opção "Essa é uma Informação relacionada ao usuário logado e o valor pode variar de acordo com cada usuário".

No **botão "Query Sql**", defina a query Sql para buscar a **Data de Nascimento** do usuário logado. Exemplo da query:

```SQL
select top 1 usu_dt_nasc as Value from tbl_usuario where id = @var_usuarioLogadoId and deletado = false
```

Salve e pronto. A partir de agora essa variável estará disponível em todo o seu ambiente. Para recuperar os valores da variável veja os itens mais abaixo.

<p class="callout warning">**Importante:** os valores das variáveis de ambiente, ficam em **cache,** esse cache é renovado a cada 1 hora. Assim melhora a performance e evita excessos de consultas ao banco de dados. O cache é automaticamente renovado quando o usuário faz login e quando no formulário de criação da Variável de Ambiente você clica em "salvar".</p>

<p class="callout danger">**Atenção**: Nunca coloque dados sensíveis ou sigilosos em uma variável de ambiente.</p>

#### Para recuperar os valores da variável de ambiente

Seguindo o exemplo acima, suponhamos que você queira agora recuperar o valor via Javascript.

<p class="callout info">Caso queira utilizar a variável em alguma situação específica ou em alguma parte do sistema que ela <span style="text-decoration: underline;">ainda não esteja disponível</span>, fale com nossa equipe que estaremos prontos para te ajudar.</p>

A forma correta seria via:

### Em Javascript

Suponhamos que a variável criada tem o nome "var\_dataNascimento". Utilize a função abaixo, ela retornará o valor da variável.

Recuperar o Valor:

```JavaScript
var var_dataNascimento = GetEnvironmentVariable("var_dataNascimento")
```

Recuperar a Descrição (texto), no caso de variáveis do Tipo "Query com Id + Descrição":

```JavaScript
var var_dataNascimento = GetEnvironmentVariable_Text("var_dataNascimento")
```

### Em uma Query SQL

Suponhamos que a variável criada tem o nome "var\_dataNascimento". Utilize o nome da variável como parâmetro de sua Query, como no exemplo abaixo.

```SQL
select usu_nome  from tbl_usuario where usu_dt_nasc = @var_dataNascimento and deletado = false
```

### Em C# (na área de Regras de Negócio do Formulario)

Suponhamos que a variável criada tem o nome "var\_dataNascimento". Utilize a função abaixo, ela retornará o valor da variável.

Recuperar o Valor:

```JavaScript
FormContext.GetEnvironmentVariable("var_dataNascimento")
```

Recuperar a Descrição (texto), no caso de variáveis do Tipo "Query com Id + Descrição":

```JavaScript
FormContext.GetEnvironmentVariable_Text("var_dataNascimento")
```

### Em C# (nos componentes em cshtml)

Suponhamos que a variável criada tem o nome "var\_dataNascimento". Utilize a função abaixo, ela retornará o valor da variável.

Recuperar o Valor:

```JavaScript
PageContext.GetEnvironmentVariable("var_dataNascimento")
```

Recuperar a Descrição (texto), no caso de variáveis do Tipo "Query com Id + Descrição":

```JavaScript
PageContext.GetEnvironmentVariable_Text("var_dataNascimento")
```

### Em C# (nas API)

Suponhamos que a variável criada tem o nome "var\_dataNascimento". Utilize a função abaixo, ela retornará o valor da variável.

Recuperar o Valor:

```JavaScript
ApiContext.GetEnvironmentVariable("var_dataNascimento")
```

Recuperar a Descrição (texto), no caso de variáveis do Tipo "Query com Id + Descrição":

```JavaScript
ApiContext.GetEnvironmentVariable_Text("var_dataNascimento")
```

# Change Request

Permite enviar algumas funcionalidades de um ambiente para outro. Essa função é utilizada quando se tem mais de um ambiente, e usa-se o conceito de ambiente de desenvolvimento e outro como ambiente de produção.

É possível selecionar os formulários e tabelas associativas ([Tabela Relacional N:N](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/tabela-relacional-%28nn%29 "Tabela Relacional (N:N)")) que devem ser enviados a outros ambientes.

Além disso, é possível incluir scripts customizados para serem executados antes e depois da transferência dos objetos.

<p class="callout info">Ao transferir os formulários, apenas a estrutura é transferida e não o conteúdo.</p>

# Visual Code Editor

O agilityflow permite editar os formulários muito mais do que as configurações pré-definidas do formulário estabelecidas pelo sistema. Para fazer isso, é necessário utilizar o Visual Code Editor.

Nele, é possível modificar o formulário de 4 maneiras:

### Style (CSS)

É possível utilizar todos os recursos do CSS para fazer as modificações do formulário.

### Javascript

O javascript também está disponível para ser modificado. Além disso, já existem algumas facilidades criadas pelo agilityflow, que ficam disponíveis para uso.

### C# (Server Side)

Inclua aqui, C# que atuarão no formulário.

### Componentes CsHtml

Qualquer conteúdo Html pode ser criado atráves desses componentes. Entretanto, esses componentes precisam ser posicionados na [tela de cadastro](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/montar-e-organizar-a-tela-de-cadastro "Montar e organizar a tela de cadastro") do formulário.

# Formulário - customizar com HTML, C#, CSS e Javascript

O agilityflow também pode ser customizado através da Linguagem Html, CSS, Javascript e C# (csharp).

O html do agilityflow é baseado no Razor do framework .Net, isso é, você pode além de customizar com HTML, utilizar código C# (razor) para dar mais flexibilidade e poder ao seu componente Html.

#### O que e onde customizar?

Acesse a parte de Desenvolvimento do Formulário que você deseja customizar, para isso, entre na área de customização de um formulário e clique na opção Visual Code Editor, como na imagem abaixo:

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616509257635.png)

No Visual Code editor, no menu esquerdo, serão apresentados as seguintes opções:

- **Style (CSS):**  opção para customizar o CSS de todo o formulário.
- **Javascript:**  opção para customizar o Javascript de todo o formulário.
- **Componente CsHtml:** opção para criar novos componentes em HTML

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616592273241.png)

### Style (CSS)

Nessa área, você pode criar customizações via linguagem CSS para todo o formulário, o seu uso é livre.

<p class="callout warning">Levar em consideração o tratamento em CSS para a responsividade da plataforma em outros device, Mobile, Computador Desktop, Tablet, etc.</p>

### Javascript: 

Nessa área, você pode criar customizações via linguagem Javascript para todo o formulário, o seu uso é livre.

Você pode utilizar jquery e outras bibliotecas já declaradas no código-fonte por padrão (veja lista mais abaixo).

<span style="text-decoration: underline;">Exemplo de utilização:</span>

No código javascript abaixo, a regra impede que um formulário de projetos que esteja com o status "inativo", seja salvo:

```JavaScript
var projeto = {
    init: function () {
        projeto._setEvents(); //registrar os eventos que são inerentes a esse bloco de código
    },
    _setEvents: function () {

      	//ao fazer o submit do formulário executa a função de validação de status
        $('#formulario').on('submit', function (e) {
            projeto.validarStatus();
        })

    },
    validarStatus: function () {

      	//recupera através de jquery o valor do campo "Status do Projeto"
        var status_projeto = $("#status_projeto").val();
      
      	//verifica se o tipo de envio que o formulário está requisitando no submit 
        //é do tipo "SALVAR" e se o status é "inativo"
        //caso seja, inválida o submit e apresenta uma aviso para o usuário
        if (Form.getFormActionOnSubmit() == ACTION_SALVAR && status_projeto == "inativo") {

            //inválida o submit e apresenta uma aviso para o usuário
            Form.invalidateForm({
                msg: 'Um projeto inativo não pode ser salvo.'
            });

        }
 
    }
}
projeto.init(); //iniciando e configurando
```

Abaixo estão listadas algumas funções nativas do agility**Flow** para javascript:

#### **Como utilizar funções Javascript dentro de um CSHTML**

<p class="callout info">Caso você utilize Javascript dentro de um componente HTML (CSHTML), é necessário que o código esteja dentro da função **DOM.ready (como no exemplo abaixo)** para garantir que o seu código só execute após todo o carregamento de todos as funções Javascript</p>

<p class="callout danger">Recomendamos que dentro do arquivo CSHTML só tenha a "chamadas" para as funções que estejam programadas dentro do arquivo específico para o código Javascript.</p>

```JavaScript
<script>
    DOM.ready(function () {
  
  		//seu código javascript aqui
  
    });
</script>
```

#### **Funções Javascript Nativas**

##### Recuperar data do servidor:

```JavaScript
GetDateNow()
```

<p class="callout warning">A data e hora são obtidas dos servidores do Agilityflow, para assim garantir a confiabilidade da data e hora</p>

<p class="callout info">**Atenção:** Lembre-se que no Javascript o retorno do método ".getMonth()" de um objeto **Date**, não refere-se ao mês e sim a Índice daquele mês no array de meses, sendo assim, o retorno desse método sempre será entre os valores **0 até 11** e não de 1 a 12</p>

Exemplo de como configurar o valor inicial de um campo com a data atual.

Para esse exemplo, encare que o ID do campo que estamos preenchendo com a data atual é "data".

```JavaScript
var exemplo1 = {
    init: function () {
        exemplo1.setToday();
    },
    //coloca a data atual no campo de data
    setToday: function () {

        if ($('#data').val() != "") return;

        //data do servidor para garantir que seja uma data válida
        var date = GetDateNow();

        var day = date.getDate().toString().padLeft(2, '0');
        var year = date.getFullYear();
        var monthIndex = date.getMonth()
        monthIndex++;
        if (monthIndex > 12)
            monthIndex = 1;


        $('#data').val(day.toString().padLeft(2, '0') + '/' + monthIndex.toString().padLeft(2, '0') + '/' + year);

    }
}
exemplo1.init();
```

##### Comparar uma data com a data atual (Hoje):

<p class="callout info">Essa comparação desconsidera a HORA</p>

A função é: **formContext.datetime.validation.compareToday(comparador, data)**

Os possíveis comparadores são:

<table border="1" id="bkmrk-greater-greater-or-e" style="border-collapse: collapse; width: 100%; height: 186px;"><tbody><tr style="height: 31px;"><td style="width: 25%; height: 31px;">**Tipo**</td><td style="width: 32.9012%; height: 31px;"><div><div>Opção 1 (qualquer uma das opções)</div></div></td><td style="width: 42.0988%; height: 31px;"><div><div>Opção 2 (qualquer uma das opções)</div></div></td></tr><tr style="height: 31px;"><td style="width: 25%; height: 31px;"><div><div>**maior que**</div></div></td><td style="width: 32.9012%; height: 31px;"><div><div>&gt;</div></div></td><td style="width: 42.0988%; height: 31px;"><div><div>greater </div></div></td></tr><tr style="height: 31px;"><td style="width: 25%; height: 31px;"><div><div>**maior ou igual** </div></div></td><td style="width: 32.9012%; height: 31px;"><div><div>&gt;=</div></div></td><td style="width: 42.0988%; height: 31px;"><div><div>greater-or-equal</div></div></td></tr><tr style="height: 31px;"><td style="width: 25%; height: 31px;"><div><div>**menor**</div></div></td><td style="width: 32.9012%; height: 31px;"><div><div>&lt;</div></div></td><td style="width: 42.0988%; height: 31px;"><div><div>less</div></div></td></tr><tr style="height: 31px;"><td style="width: 25%; height: 31px;"><div><div>**menor ou igual**</div></div></td><td style="width: 32.9012%; height: 31px;"><div><div>&lt;=</div></div></td><td style="width: 42.0988%; height: 31px;"><div><div>less-or-equal</div></div></td></tr><tr style="height: 31px;"><td style="width: 25%; height: 31px;"><div><div>**igual**</div></div></td><td style="width: 32.9012%; height: 31px;"><div><div>==</div></div></td><td style="width: 42.0988%; height: 31px;"><div><div>equal</div></div></td></tr></tbody></table>

```JavaScript
var greater = formContext.datetime.validation.compareToday('greater', '31/12/2000');
console.log('greater',greater);

var greater_or_equal = formContext.datetime.validation.compareToday('greater-or-equal', '31/12/2000');
console.log('greater-or-equal', greater_or_equal);

var less = formContext.datetime.validation.compareToday('less', '31/12/2000');
console.log('less',less);

var less_or_equal = formContext.datetime.validation.compareToday('less-or-equal', '31/12/2000');
console.log('less-or-equal', less_or_equal);

var equal = formContext.datetime.validation.compareToday('equal', '31/12/2000');
console.log('equal', equal);

```

##### Comparação entre datas. Comparar 2 datas:

<p class="callout info">Essa comparação desconsidera a HORA</p>

A função é: **formContext.datetime.validation.compare(data1, comparador, data2)**

Os possíveis comparadores são:

<table border="1" id="bkmrk-tipo-op%E3%A7%E3%A3o-1-%28qual" style="border-collapse: collapse; width: 100%; height: 186px;"><tbody><tr style="height: 31px;"><td style="width: 25%; height: 31px;">**Tipo**</td><td style="width: 32.9012%; height: 31px;"><div><div>Opção 1 (qualquer uma das opções)</div></div></td><td style="width: 42.0988%; height: 31px;"><div><div>Opção 2 (qualquer uma das opções)</div></div></td></tr><tr style="height: 31px;"><td style="width: 25%; height: 31px;"><div><div>**maior que**</div></div></td><td style="width: 32.9012%; height: 31px;"><div><div>&gt;</div></div></td><td style="width: 42.0988%; height: 31px;"><div><div>greater </div></div></td></tr><tr style="height: 31px;"><td style="width: 25%; height: 31px;"><div><div>**maior ou igual** </div></div></td><td style="width: 32.9012%; height: 31px;"><div><div>&gt;=</div></div></td><td style="width: 42.0988%; height: 31px;"><div><div>greater-or-equal</div></div></td></tr><tr style="height: 31px;"><td style="width: 25%; height: 31px;"><div><div>**menor**</div></div></td><td style="width: 32.9012%; height: 31px;"><div><div>&lt;</div></div></td><td style="width: 42.0988%; height: 31px;"><div><div>less</div></div></td></tr><tr style="height: 31px;"><td style="width: 25%; height: 31px;"><div><div>**menor ou igual**</div></div></td><td style="width: 32.9012%; height: 31px;"><div><div>&lt;=</div></div></td><td style="width: 42.0988%; height: 31px;"><div><div>less-or-equal</div></div></td></tr><tr style="height: 31px;"><td style="width: 25%; height: 31px;"><div><div>**igual**</div></div></td><td style="width: 32.9012%; height: 31px;"><div><div>==</div></div></td><td style="width: 42.0988%; height: 31px;"><div><div>equal</div></div></td></tr></tbody></table>

```JavaScript
var greater = formContext.datetime.validation.compare('31/01/2001','greater', '31/12/2000');
console.log('greater',greater);

var greater_or_equal = formContext.datetime.validation.compare('31/01/2001','greater-or-equal', '31/12/2000');
console.log('greater-or-equal', greater_or_equal);

var less = formContext.datetime.validation.compare('31/01/2001','less', '31/12/2000');
console.log('less',less);

var less_or_equal = formContext.datetime.validation.compare('31/01/2001','less-or-equal', '31/12/2000');
console.log('less-or-equal', less_or_equal);

var equal = formContext.datetime.validation.compare('31/01/2001','equal', '31/12/2000');
console.log('equal', equal);


```

##### Recuperar o ID do usuário logado: 

```JavaScript
GetUserId()
```

##### Recuperar o nome do usuário logado: 

```JavaScript
var nome = pageNavigation.getUserName();
var nomeCompleto = pageNavigation.getUserNameCompleto()
```


##### Recuperar os Perfis do usuário logado: 

```JavaScript
GetUserProfileId() //retorna um array com os Ids dos perfis ['xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx','xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx']
```

##### Função para identificar se o usuário logado tem um determinado perfil: 

```JavaScript
UserHasProfileId('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx') //retorna true ou false
```

<span style="font-size: 1.4em; font-weight: 500; color: #555555;">Expandir e Recolher um determinado painel de campos</span>

```JavaScript
var panelId = 'f175132d-5e85-778f-1354-cb2d339e6146';

//para alternar entre expandido e recolhido
formContext.panel.collapse.toggle(panelId)

//para recolher o painel
formContext.panel.collapse.hide(panelId)

//para expandir o painel
formContext.panel.collapse.show(panelId)

//para testar se o painel está recolhido ou não
formContext.panel.collapse.isCollapsed(panelId) 
```

##### Recuperar os valores das "Variáveis de Ambiente"

Para saber mais sobre variáveis de ambiente entre em [Variáveis de ambiente](https://wiki.agilityflow.io/link/88#bkmrk-page-title)

```JavaScript
var valor = GetEnvironmentVariable("nomeDaVariavel")
```

Recuperar a Descrição (texto), no caso de variáveis do Tipo "Query com Id + Descrição":

```JavaScript
var text = GetEnvironmentVariable_Text("nomeDaVariavel")
```

##### Recuperar o VALOR preenchido de um campo no Formulário

```JavaScript
var value = Form.getValueField("idDoCampo");
```

<span style="font-size: 1.4em; font-weight: 500; color: #555555;">Recuperar o VALOR preenchido de um campo no Formulário PAI (formulário que abriu o formulário atual)</span>

```JavaScript
var value = Form.getValueField_parentIFrame("idDoCampo");
```

##### Recuperar o TEXTO preenchido de um campo no Formulário (Para os campos: <span style="text-decoration: underline;">Lista de Seleção</span> e <span style="text-decoration: underline;">Pesquisa com Auto Completar</span>)

```JavaScript
var value = Form.getTextField("idDoCampo");
```

##### Recuperar o TEXTO preenchido de um campo no Formulário PAI (formulário que abriu o formulário atual) (Para os campos: <span style="text-decoration: underline;">Lista de Seleção</span> e <span style="text-decoration: underline;">Pesquisa com Auto Completar</span>)

```JavaScript
var value = Form.getTextField_parentIFrame("idDoCampo");
```

##### Preencher um valor em um campo do Formulário

Parâmetros opcionais da função javascript

<table border="1" id="bkmrk-par%E3%A2metro%E2%A0opcional" style="border-collapse: collapse; width: 100%; height: 116px;"><tbody><tr style="height: 31px;"><td style="width: 25%; height: 31px;">**Parâmetro opcional**</td><td style="width: 15.0926%; height: 31px;">**Valor padrão**</td><td style="width: 20.7716%;">**Opções de valores**</td><td style="width: 39.1358%; height: 31px;">**Descrição**</td></tr><tr style="height: 85px;"><td style="width: 25%; height: 85px;">setOnlyIfFieldValueIsEmpty</td><td style="width: 15.0926%; height: 85px;">false</td><td style="width: 20.7716%;">true ou false</td><td style="width: 39.1358%; height: 85px;">Caso seja "**true**" a função só preencherá o valor do campo se o campo ainda **NÃO** estiver preenchido.

Caso seja "**false**" a função preenche ou substitui o valor do campode qualquer maneira.

</td></tr></tbody></table>

```JavaScript
//EXEMPLO 1: preenchendo o valor
Form.setValueField("idDoCampo", "value");



//EXEMPLO 2: preenchendo o valor e enviando os parametros opcionais para a função:
var options = { setOnlyIfFieldValueIsEmpty: true  }
Form.setValueField("idDoCampo", "value", options);

```

##### Preencher um valor em um campo do Formulário PAI (formulário que abriu o formulário atual)

Parâmetros opcionais da função javascript

<table border="1" id="bkmrk-par%E3%A2metro%E2%A0opcional-0" style="border-collapse: collapse; width: 100%; height: 116px;"><tbody><tr style="height: 31px;"><td style="width: 25%; height: 31px;">**Parâmetro opcional**</td><td style="width: 15.0926%; height: 31px;">**Valor padrão**</td><td style="width: 20.7716%;">**Opções de valores**</td><td style="width: 39.1358%; height: 31px;">**Descrição**</td></tr><tr style="height: 85px;"><td style="width: 25%; height: 85px;">setOnlyIfFieldValueIsEmpty</td><td style="width: 15.0926%; height: 85px;">false</td><td style="width: 20.7716%;">true ou false</td><td style="width: 39.1358%; height: 85px;">Caso seja "**true**" a função só preencherá o valor do campo se o campo ainda **NÃO** estiver preenchido.

Caso seja "**false**" a função preenche ou substitui o valor do campode qualquer maneira.

</td></tr></tbody></table>

```JavaScript
//EXEMPLO 1: preenchendo o valor
Form.setValueField_parentIFrame("idDoCampo", "value");


//EXEMPLO 2: preenchendo o valor e enviando os parametros opcionais para a função:
var options = { setOnlyIfFieldValueIsEmpty: true }
Form.setValueField_parentIFrame("idDoCampo", "value", options);


```

##### Customizar evento de submit do formulário (Antes do post):

```JavaScript
$('#formulario').on('submit', function (e) { 
		/*
          função js para executar antes do 
          post e após a validação padrão do agilityflow
          
        */  
})

```

No [exemplo de javascript](http://wiki.agilityflow.io/link/78#bkmrk-exemplo-de-customiza), nas linhas de 5 a 12 usamos o código para interceptar o submit e validar o status do projeto.

##### Forçar o Salvar do formulário:

[Clique aqui para visualizar detalhes de Como forçar o salvamento de um Form](https://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/for%C3%A7ar-o-salvamento-de-um-form "Forçar o salvamento de um Form")

##### Escutar o evento de retorno de um submit no form:

[Clique aqui para visualizar detalhes de Como escutar o evento de retorno de um submit no form](https://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/evento-javascript-ap%C3%B3s-o-subsmit-post-do-formulario-%28onafterpostevent%29 "Evento javascript após o subsmit post do formulario (onAfterPostEvent)")

##### Invalidar o post/submit do formulário:

Para evitar que o formulário seja postado, você pode utilizar a seguinte função no evento de submit

```JavaScript
$('#formulario').on('submit', function (e) {
  
    //invalidar submit
    Form.invalidateForm({
      msg: 'Mensagem para o usuário.'
    });
  
})
```

No [exemplo de javascript](http://wiki.agilityflow.io/link/78#bkmrk-exemplo-de-customiza), nas linhas de 23 a 26 usamos o código para bloquear o submit caso o status do projeto seja inválido.

##### Verificar qual foi o botão clicado pelo usuário no submit do formulário. Se foi o salvar, salvar rascunho, descartar, deletar, aprovar, retornar, reprovar e assim por diante...

Os tipos de ações que o usuário pode realizar em um formulário são:

- Salvar (**ACTION\_SALVAR**)
- Salvar rascunho (**ACTION\_SALVAR\_RASCUNHO**)
- Descartar rascunho (**ACTION\_DESCARTAR\_RASCUNHO**)
- Aprovar (**ACTION\_APROVAR**)
- Reprovar (**ACTION\_REPROVAR**)
- Retornar (**ACTION\_RETORNAR**)
- Deletar (**ACTION\_DELETAR**)
- Salvar formulário filho (**ACTION\_SALVAR\_FORMULARIO\_FILHO**)
- Deletar formulário filho (**ACTION\_DELETAR\_FORMULARIO\_FILHO**)
- Descartar alterações formulário filho (**ACTION\_DESCARTAR\_ALTERACOES\_FORMULARIO\_FILHO**)
- Solicitar troca de aprovador na etapa (**ACTION\_SOLICITAR\_TROCA\_APROVADOR\_ETAPA\_DINAMICA**)
- Salvar o novo aprovador definido para a etapa (**ACTION\_SALVAR\_DEFINICAO\_APROVADOR\_ETAPA\_DINAMICA**)

Abaixo o exemplo para recuperar a ação:

```JavaScript
$('#formulario').on('submit', function (e) {
  
  		var tipoAcao = Form.getFormActionOnSubmit();
  		if(tipoAcao == ACTION_SALVAR){
          
            //ação para "Salvar"
          
        }else if(tipoAcao == ACTION_SALVAR_RASCUNHO){
          
            //ação para "Salvar rascunho"
          
        }else if(tipoAcao == ACTION_DESCARTAR_RASCUNHO){
          
            //ação para "Descartar rascunho"
          
        }else if(tipoAcao == ACTION_APROVAR){
          
            //ação para "Aprovar"
          
        }else if(tipoAcao == ACTION_REPROVAR){
          
            //ação para "Reprovar"
          
        }else if(tipoAcao == ACTION_RETORNAR){
          
            //ação para "Retornar"
          
        }else if(tipoAcao == ACTION_DELETAR){
          
            //ação para "Deletar"
          
        }else if(tipoAcao == ACTION_SALVAR_FORMULARIO_FILHO){
          
            //ação para "Salvar formulário filho"
          
        }else if(tipoAcao == ACTION_DELETAR_FORMULARIO_FILHO){
          
            //ação para "Deletar formulário filho"
          
        }else if(tipoAcao == ACTION_DESCARTAR_ALTERACOES_FORMULARIO_FILHO){
          
            //ação para "Descartar alterações formulário filho"
          
        }else if(tipoAcao == ACTION_SOLICITAR_TROCA_APROVADOR_ETAPA_DINAMICA){
          
            //ação para "Solicitar troca aprovador etapa dinâmica"
          
        }else if(tipoAcao == ACTION_SALVAR_DEFINICAO_APROVADOR_ETAPA_DINAMICA){
          
            //ação para "Salvar definicão de  aprovador etapa dinâmica"
          
        }
  
})
```

No [exemplo de javascript](http://wiki.agilityflow.io/link/78#bkmrk-exemplo-de-customiza), nas linha 21 usamos o código no IF para testar se o submit era do tipo "Salvar".

##### Mensagem e alerta para o usuário

No código abaixo mostra exemplo de como apresentar alertas na tela para o usuário.

```JavaScript
//mensagem de sucesso
pageMsg.showMsgSuccess(msg, title);

//mensagem de aviso
pageMsg.showMsgWarning(msg, title);

//mensagem de erro
pageMsg.showMsgError(msg, title);

//esconder a mensagem 
pageMsg.hideMsgs(true);
```

##### Recuperar um valor de uma QueryString

```JavaScript
var value = getQuerystring('paramQuerystring1');
```

**Você também pode usar o javascript nativo, detalhado nesse exemplo: [Como Obter Parâmetros da Query String com JavaScript](https://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/como-obter-parametros-da-query-string-com-javascript "Como Obter Parâmetros da Query String com JavaScript")**

#####   


#### Javascript - Formulário Filho

##### Javascript - Buscar o Json com o resultado e todos os campos de uma tabela filha

```JavaScript
//o parametro 'f43330be-0467-7fee-1168-28c9e6d185f0' é o Id da Tabela
var json = formContext.childForm.datatable.getResultJson('f43330be-0467-7fee-1168-28c9e6d185f0');
```

##### Javascript - Atualizar uma Tabela Filha

```JavaScript
//o parametro 'f43330be-0467-7fee-1168-28c9e6d185f0' é o Id da Tabela
formContext.childForm.datatable.refresh('f43330be-0467-7fee-1168-28c9e6d185f0');
```

##### Javascript - Buscar o total de itens em uma tabela filha

```JavaScript
//o parametro 'f43330be-0467-7fee-1168-28c9e6d185f0' é o Id da Tabela
var total = formContext.childForm.datatable.totalRows('f43330be-0467-7fee-1168-28c9e6d185f0');
```

##### Javascript - Refazer a ordenação dos itens quando a tabela filha estiver liberada a ordenação manual via "Drag and Drop" (Arrastar e soltar)

```JavaScript
//reordena os itens da tabela filha de acordo com a ordem dos ids passados no parametro @items_sorted
//o primeiro parametro, 'f43330be-0467-7fee-1168-28c9e6d185f0' é o Id da Tabela
// o segundo parametro "items_sorted" é a lista ordenada com os ids dos elementos que pertencem a tabela:
//[
//    { formid: '', draftid: '' },
//    { formid: '', draftid: '' },
//    { formid: '', draftid: '' },
//]
formContext.childForm.datatable.setOrder('f43330be-0467-7fee-1168-28c9e6d185f0', items_sorted);
```

##### Javascript - Buscar todos os ids: "Id do Formulário" e "Id do Rascunho" dos itens listados em uma tabela filha

```JavaScript
//o parametro 'f43330be-0467-7fee-1168-28c9e6d185f0' é o Id da Tabela
var ids = formContext.childForm.datatable.getAllChildIds('f43330be-0467-7fee-1168-28c9e6d185f0');


o restorno será nesse formato:
 [
    {
        "formid": "5451ae4e-290a-4887-8099-6e9a026c0283",
        "draftid": ""
    },
    {
        "formid": "6c55eeef-427b-40ce-b415-dab11b4aa039",
        "draftid": ""
    },
    {
        "formid": "304cc8e2-47af-44d4-ba83-c0e4939e21fb",
        "draftid": ""
    }
]
```

##### Javascript - Disparo de Eventos na tabela Filha


<table border="1" id="bkmrk-objeto%E2%A0-nome-%2F-even" style="border-collapse: collapse; width: 100%; height: 150px;"><tbody><tr style="height: 30px;"><td style="width: 33.3333%; height: 30px;">**Objeto** </td><td style="width: 33.3333%; height: 30px;">**Nome / evento**</td><td style="width: 33.3333%; height: 30px;">**Exemplo de uso**</td></tr><tr style="height: 30px;"><td style="width: 33.3333%; height: 30px;">Tabela de Dados do Formulário Filho. Que fica no Formulário Pai.</td><td style="width: 33.3333%; height: 30px;">before-data-load

/

**Dispara antes de carregar os dados na tabela**

</td><td style="width: 33.3333%; height: 30px;">//id = id da tabela filha  
$('#id').on('before-data-load', function (e) {  
console.log('evento disparado antes de carregar os dados')  
});  
  
</td></tr><tr style="height: 30px;"><td style="width: 33.3333%; height: 30px;">Tabela de Dados do Formulário Filho. Que fica no Formulário Pai.</td><td style="width: 33.3333%; height: 30px;">data-loaded

/

**Dispara depois de carregar os dados na tabela**

</td><td style="width: 33.3333%; height: 30px;">//id = id da tabela filha  
$('#id').on('data-loaded', function (e, result\_json) {  
console.log('evento disparado depois de carregar os dados')  
console.log('result\_json',result\_json)  
});</td></tr><tr style="height: 30px;"><td style="width: 33.3333%; height: 30px;"> </td><td style="width: 33.3333%; height: 30px;"> </td><td style="width: 33.3333%; height: 30px;"> </td></tr><tr style="height: 30px;"><td style="width: 33.3333%; height: 30px;"> </td><td style="width: 33.3333%; height: 30px;"> </td><td style="width: 33.3333%; height: 30px;"> </td></tr></tbody></table>

##### **<span style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Oxygen, Ubuntu, Roboto, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal;">Javascript - </span><span style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Oxygen, Ubuntu, Roboto, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal;">Biblioteca</span>**

<span style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Oxygen, Ubuntu, Roboto, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400;">Abaixo estão listadas as biblioteca javascript que já estão importadas na página do formulário:</span>

<table border="1" cellpadding="0" cellspacing="0" dir="ltr" id="bkmrk-asrange%2Fjquery-asran" style="height: 545px;"><colgroup><col width="341"></col></colgroup><tbody><tr style="height: 31px;"><td data-sheets-numberformat="{"1":2,"2":"#,##0.00","3":1}" data-sheets-value="{"1":2,"2":"bootstrap-daterangepicker/daterangepicker.js"}" style="height: 31px; width: 341px;">bootstrap-daterangepicker/daterangepicker.js</td></tr><tr style="height: 31px;"><td data-sheets-numberformat="{"1":2,"2":"#,##0.00","3":1}" data-sheets-value="{"1":2,"2":"bootstrap-daterangepicker/moment.min.js"}" style="height: 31px; width: 341px;">bootstrap-daterangepicker/moment.min.js</td></tr><tr style="height: 31px;"><td data-sheets-numberformat="{"1":2,"2":"#,##0.00","3":1}" data-sheets-value="{"1":2,"2":"bootstrap-select/bootstrap-select.js"}" style="height: 31px; width: 341px;">bootstrap-select/bootstrap-select.js</td></tr><tr style="height: 31px;"><td data-sheets-numberformat="{"1":2,"2":"#,##0.00","3":1}" data-sheets-value="{"1":2,"2":"bootstrap/bootstrap.js"}" style="height: 31px; width: 341px;">bootstrap/bootstrap.js</td></tr><tr style="height: 31px;"><td data-sheets-numberformat="{"1":2,"2":"#,##0.00","3":1}" data-sheets-value="{"1":2,"2":"guid.js"}" style="height: 31px; width: 341px;">guid.js</td></tr><tr style="height: 49px;"><td data-sheets-numberformat="{"1":2,"2":"#,##0.00","3":1}" data-sheets-value="{"1":2,"2":"jquery.inputmask/4.0.0-beta.19/jquery.inputmask.bundle.js"}" style="height: 49px; width: 341px;">jquery.inputmask/4.0.0-beta.19/jquery.inputmask.bundle.js</td></tr><tr style="height: 31px;"><td data-sheets-numberformat="{"1":2,"2":"#,##0.00","3":1}" data-sheets-value="{"1":2,"2":"jquery.mask.js"}" style="height: 31px; width: 341px;">jquery.mask.js</td></tr><tr style="height: 31px;"><td data-sheets-numberformat="{"1":2,"2":"#,##0.00","3":1}" data-sheets-value="{"1":2,"2":"jquery.maskMoney.js"}" style="height: 31px; width: 341px;">jquery.maskMoney.js</td></tr><tr style="height: 31px;"><td data-sheets-numberformat="{"1":2,"2":"#,##0.00","3":1}" data-sheets-value="{"1":2,"2":"jquery.validate.js"}" style="height: 31px; width: 341px;">jquery.validate.js</td></tr><tr style="height: 31px;"><td data-sheets-numberformat="{"1":2,"2":"#,##0.00","3":1}" data-sheets-value="{"1":2,"2":"jquery.webui-popover.js"}" style="height: 31px; width: 341px;">jquery.webui-popover.js</td></tr><tr style="height: 31px;"><td data-sheets-numberformat="{"1":2,"2":"#,##0.00","3":1}" data-sheets-value="{"1":2,"2":"jquery/jquery.js"}" style="height: 31px; width: 341px;">jquery/jquery.js</td></tr></tbody></table>

### Criar Html (Componente Cshtml): 

Abra o formulário que deseja customizar. Na barra superior desse formulário clique em **"Visual Code Editor"** como mostra figura abaixo:

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1553004288897.png)

Para criar um html, clique no botão "**Novo Cshtml**", como na figura abaixo:

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1553004348942.png)

Ao clicar, digite o nome do Html

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1553009985544.png)

Agora o novo html está criado, e será mostrado para edição no menu do lado esquerdo, como na imagem abaixo.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1553010026218.png)

Clique no nome do Html para edita-lo.

No arquivo Html, é possível utilizar qualquer tag Html que você precisar. Para embelezar o seu html utilize a linguagem css na área "[Style (CSS)](http://wiki.agilityflow.io/link/78#bkmrk-style-%28css%29)", e para customizar com javascript, faça as customizações na área "<a>Javascript</a>".

Faça as edições necessárias, salve e posicione esse novo componente no seu formulário. (O passo a passo para posicionar o componente no formulário está descrito mais abaixo)

##### Posicionando o componente Html no formulário

Depois de [criado](http://wiki.agilityflow.io/link/78#bkmrk-html-%28componente-csh) o componente cshtml, salve todas as configurações e customizações realizadas no Visual Code Editor, através do botão ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1553010407195.png).

Agora volte para a edição do formulário e clique no botão ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1553010476873.png)

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1553010465419.png)

No box de opções de campos, o seu componente "ExemploHtml" já deverá estar listado, como mostra a imagem abaixo:

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1553010542585.png)

Clique no nome do componente, e logo em seguida em salvar ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1553010646477.png)

Agora você deve posiciona-lo na tela, para isso basta clicar na opção ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1553010738286.png) como mostra imagem abaixo.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1553010465419.png)

Ao abrir a opção de montagem de tela, posicione e arraste o seu componente onde você preferir.

Agora salve e publique esse novo formulário! Pronto, o seu componente está criado.

### Exemplo prático de customização html

No exemplo a seguir vamos apresentar uma mensagem em azul de bom dia ou boa tarde ou boa noite dependendo do horário atual.

Para descobrir qual a data e qual a mensagem a ser apresentada, usamos C# no cshtml.

Para deixar a mensagem azul, usamos CSS.

Nesse exemplo não utilizamos javascript para nenhuma ação, mas poderia ser utilizado caso fosse necessário.

##### Passo 1 - Definir o html

Crie o cshtml como descrito [aqui.](http://wiki.agilityflow.io/link/78#bkmrk-html-%28componente-csh)

Agora cole o código abaixo nesse novo html:

```C++
@{
    string parteDoDia;
    var hours = DateTime.Now.Hour;
    if (hours > 16)
    {
        parteDoDia = "Boa noite";
    }
    else if (hours > 11)
    {
        parteDoDia = "Boa tarde";
    }
    else
    {
        parteDoDia = "Bom dia";
    }
}

<div class="painel-msg-customizada">        
    <span>@parteDoDia,</span>
</div>
```

##### Passo 2 - Definir o CSS

Entre na área de CSS e cole o código abaixo:

```CSS
.painel-msg-customizada{
    display: block;
    text-align: left;
    padding-top: 10px;
}

.painel-msg-customizada span{

    color: #0281ff;
    display: block;
    font-size: 17px;
    font-weight: 500;
    border-bottom: solid 2px #a4d2ff;
    margin-bottom: 15px;
}
```

##### Passo 3 - Posicionar o html no formulário

Salve tudo no Visual Code Editor e posicione esse componente html, como descrito [aqui](http://wiki.agilityflow.io/link/78#bkmrk-depois-de-criado-o-c).

##### Passo 4 - Salvar e publicar o formulário

Salve e publico o novo formulário.

Agora acesse esse formulário, o resultado deve ser igual ao print abaixo:

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1553014672823.png)

#### C# no componente CSHTML 

Se você precisar de alguma informação do formulário, utilize a opção abaixo

##### C# - Propriedades

<table border="1" id="bkmrk-bool-israscunho-%7Bget"><tbody><tr><td>string FormId</td><td>Id do registro, pode ser em branco ou nulo qdo for um rascunho</td></tr><tr><td>bool IsRascunho {get;}</td><td>Retorna true caso a linha seja um Rascunho</td></tr><tr><td>string DraftId</td><td>Id do rascunho</td></tr></tbody></table>


##### C# - Recuperar (Get) valor dos campos

<table border="1" id="bkmrk-string-getvalue%28stri" style="height: 281px;"><tbody><tr style="height: 37px;"><td style="width: 340px; height: 37px;">string GetValue(string idColuna)</td><td style="width: 469px; height: 37px;">retorna o valor do campo

</td></tr><tr style="height: 109px;"><td style="width: 340px; height: 109px;">int? GetInt(string idColuna)</td><td style="width: 469px; height: 109px;">Retorna o valor do campo no tipo INT (inteiro), caso esse campo no formulário seja um número, se o valor for 10.000,99

Será retornado: 10000

</td></tr><tr style="height: 73px;"><td style="width: 340px; height: 73px;">decimal? GetDecimal(string idColuna)</td><td style="width: 469px; height: 73px;">Retorna o valor do campo no tipo Decimal, caso esse campo no formulário seja um número, se o valor for 10.000,99 Será retornado: 10000.99

</td></tr><tr style="height: 31px;"><td style="width: 340px; height: 31px;">DateTime? GetDateTime(string idColuna)</td><td style="width: 469px; height: 31px;">Retorna o valor do campo no tipo DateTime </td></tr><tr style="height: 31px;"><td style="width: 340px; height: 31px;"><div><div>Guid? GetGuid(string idColuna)</div></div></td><td style="width: 469px; height: 31px;">Retorna o valor do campo no tipo Guid </td></tr><tr><td style="width: 340px;"><div><div>string GetText(string idColuna)</div></div></td><td style="width: 469px;"><div><div>No caso de campos que são Lista Dinanica, exemplo Combo, Auto completo, radio etc.</div><div>  
</div><div>No Json de Campos Preenchidos no Formulario, só terá o Value dos campos</div><div>  
</div><div>Esse método retornará o Texto desse campo.</div><div>  
</div><div>Exemplo:</div><div>  
</div><div>Existe no formulário um campo chamado 'Produto', com o id definido como 'produto'.</div><div>  
</div><div>Esse campo é do tipo 'AutoComplete' e listará os 'Produtos' por 'Nome'.</div><div>  
</div><div>Quando o usuário salvar o formulário, no Json de envio não retornará o Nome do Produto, apenas o Id do produto selecionado (Esse id estará no formato de um GUID).</div><div>  
</div><div>Para recuperar o Nome do produto, vc precisará executar esse método da seguinte forma:</div>  
<div>var nomeProduto = PageContext.GetText("produto")</div></div></td></tr></tbody></table>

<table border="1" id="bkmrk-vari%E3%A1vel-tipo-%E2%A0-fo" style="width: 966px; height: 2248px;"><tbody><tr style="height: 31px;"><td style="width: 279px; height: 31px;">**Variável**</td><td style="width: 111px; height: 31px;">**Tipo**</td><td style="width: 576px; height: 31px;"> </td></tr><tr style="height: 613px;"><td style="width: 279px; height: 613px;"><span style="color: #ff00ff;">(**deprecated)**</span>

<span style="text-decoration: line-through;">Model.FormularioCamposPreenchidos</span>

</td><td style="width: 111px; height: 613px;"><span style="text-decoration: line-through;"><span style="color: #ff00ff;">(**deprecated)**</span></span>

<span style="text-decoration: line-through;">dynamic (Json)</span>

</td><td style="width: 576px; height: 613px;"><span style="color: #ff00ff;">(**deprecated**: utilizar o método PageContext.GetValue descrito mais acima)</span>

<span style="text-decoration: line-through;">Retorna um json com os campos preenchidos no formulário, exemplo:</span>

<span style="text-decoration: line-through;">{</span>

<span style="text-decoration: line-through;"> "campo1": "xxxxx",</span>

<span style="text-decoration: line-through;"> "campo2": "yyyyy",</span>

<span style="text-decoration: line-through;"> "campo3": "zzzzz",</span>

<span style="text-decoration: line-through;">}</span>

<span style="text-decoration: line-through;">Para resgatar a informação do campo1, utilize:</span>

```C#
@{
   var campo1 = Model.FormularioCamposPreenchidos["campo1"];
}
<div>
   @campo1
</div>
```

<span style="text-decoration: line-through;">Para resgatar o id do formulário, utilize:</span>

```C#
@{	
    var idFormulario_Forma1 = Model.Id;
    var idFormulario_Forma2 = Model.FormularioCamposPreenchidos["id"];
}

<div>@idFormulario_Forma1</div>
<div>@idFormulario_Forma2</div>
```

</td></tr><tr style="height: 200px;"><td style="width: 279px; height: 200px;"><span style="color: #ff00ff;">(**deprecated)**</span>

<span style="text-decoration: line-through;">Model.Id</span>

<span style="text-decoration: line-through;">OU </span>

<span style="text-decoration: line-through;">Model.FormularioCamposPreenchidos\["id"\];</span>

</td><td style="width: 111px; height: 200px;"><span style="color: #ff00ff;">(**deprecated)**</span>

<span style="text-decoration: line-through;">Guid</span>

<span style="text-decoration: line-through;">OU</span>

<span style="text-decoration: line-through;">string</span>

</td><td style="width: 576px; height: 200px;"><span style="color: #ff00ff;">(**deprecated)**</span>

<span style="text-decoration: line-through;">Para resgatar o id do formulário, utilize:</span>

```C#
@{	
    var idFormulario_Forma1 = Model.Id;
    var idFormulario_Forma2 = Model.FormularioCamposPreenchidos["id"];
}

<div>@idFormulario_Forma1</div>
<div>@idFormulario_Forma2</div>

```

</td></tr><tr style="height: 200px;"><td style="width: 279px; height: 200px;">Model.FormularioTemporarioId

</td><td style="width: 111px; height: 200px;">Guid

</td><td style="width: 576px; height: 200px;">Para resgatar o id temporario do formulário, utilize:

```C#
@{	
    var formularioTemporarioId = Model.FormularioTemporarioId;
}

<div>@formularioTemporarioId </div>

```

</td></tr><tr style="height: 37px;"><td style="width: 279px; height: 37px;"><span style="color: #ff00ff;">(**deprecated)**</span>

<span style="text-decoration: line-through;">Model.RascunhoId</span>

</td><td style="width: 111px; height: 37px;"><span style="color: #ff00ff;">(**deprecated)**</span>

<span style="text-decoration: line-through;">Guid</span>

</td><td style="width: 576px; height: 37px;"><span style="color: #ff00ff;">(**deprecated)**</span>

<span style="text-decoration: line-through;">Para resgatar o id do rascunho, caso seja um</span>

</td></tr><tr style="height: 37px;"><td style="width: 279px; height: 37px;">Model.EstruturaFormularioId

</td><td style="width: 111px; height: 37px;">Guid

</td><td style="width: 576px; height: 37px;">Para resgatar o id da ESTRUTURA do formulário

</td></tr><tr style="height: 200px;"><td style="width: 279px; height: 200px;">**Quando estiver dentro do Formulário Filho:**

Model.FormularioIdPai

</td><td style="width: 111px; height: 200px;">Guid

</td><td style="width: 576px; height: 200px;">Para resgatar o id do formulário pai, quando estiver dentro de um formulário filho, utilize:

```C#
@{	
    var formularioIdPai= Model.FormularioIdPai;
}

<div>@formularioIdPai</div>
```

</td></tr><tr style="height: 200px;"><td style="width: 279px; height: 200px;">**Quando estiver dentro do Formulário Filho:**

Model.FormularioTemporarioIdPai

</td><td style="width: 111px; height: 200px;">Guid

</td><td style="width: 576px; height: 200px;">Para resgatar o id temporário do formulário pai, quando estiver dentro de um formulário filho, utilize:

```C#
@{	
    var formularioTemporarioIdPai= Model.FormularioTemporarioIdPai;
}

<div>@formularioTemporarioIdPai</div>

```

</td></tr><tr style="height: 200px;"><td style="width: 279px; height: 200px;">**Quando estiver dentro do Formulário Filho:**

Model.EstruturaFormularioIdPai

</td><td style="width: 111px; height: 200px;">Guid

</td><td style="width: 576px; height: 200px;">Para resgatar o id temporário do formulário pai, quando estiver dentro de um formulário filho, utilize:

```C#
@{	
    var estruturaFormularioIdPai= Model.EstruturaFormularioIdPai;
}

<div>@estruturaFormularioIdPai</div>
```

</td></tr><tr style="height: 241px;"><td style="width: 279px; height: 241px;"><div><div>WFS.Common.AppSettings.StaticFilePath</div></div></td><td style="width: 111px; height: 241px;">string</td><td style="width: 576px; height: 241px;">Retorna a url dos arquivos estaticos do agilityflow, exemplo, .js, .css, etc..

caso queira importar um arquivo JS que já exista na biblioteca de arquivos estaticos do agilityflow

<div><div>&lt;script src="**@WFS.Common.AppSettings.StaticFilePath**/js/xxxxx/yyyyyy.js?**@WFS.Common.AppSettings.StaticFileVersion**"&gt;&lt;/script&gt;</div></div></td></tr><tr style="height: 289px;"><td style="width: 279px; height: 289px;"><div><div>WFS.Common.AppSettings.StaticFileVersion</div></div></td><td style="width: 111px; height: 289px;">string</td><td style="width: 576px; height: 289px;">Utilize essa variável para limpar o cache do seu arquivo estático, sendo assim coloque ela como parametro de querystring do seu arquivo, exemplo:

caso queira importar um arquivo JS que já exista na biblioteca de arquivos estaticos do agilityflow

<div><div>&lt;script src="@WFS.Common.AppSettings.StaticFilePath/js/xxxxx/yyyyyy.js?**@WFS.Common.AppSettings.StaticFileVersion**"&gt;&lt;/script&gt;</div></div></td></tr></tbody></table>


#### C# no Componente CSHTML - Testar se é umnovo formulário ou se é uma edição 

Para saber se o formulário é um novo ou está para edição, apenas teste a variável de ID, como no exemplo abaixo:

Forma 1

```C#
@{
  var isNovoFormulario = GuidHelper.IsNullOrEmpty(Model.Id);
}
```

Forma 2

```C#
@{
var isNovoFormulario = Model.Id.IsNullOrEmpty();
}
```

Exemplo

```C#
@{
  	var msg = "";
  	var formularioId = Model.Id;

    if(formularioId.IsNullOrEmpty()){
      msg = "é um novo formulario";
    }else{
      msg = "NÃO é um novo formulario";
    }    
  
}
<div>@msg</div>
```

#### C# no componente CSHTML - Testar se é um rascunho

```C#
@{
  	var msg = "";
  	var rascunhoId = Model.RascunhoId;

    if(rascunhoId.IsNullOrEmpty()){
      msg = "é um Rascunho";
    }else{
      msg = "NÃO é um Rascunho";
    }    
  
}
<div>@msg</div>
```

### Criar uma Tabela de dados customizada através de programação: Query SQL, C#, HTML e CSS: 

Abaixo está um exemplo de criação de uma tabela de dados buscando as informações através de uma Query SQL e apresentando no Html:

Para customizar o CSS e Javascript da tabela de dados, utilize áreas de customização já citadas nos itens acima

```C#
<h5 id="datatableTitle">Tasks</h5> 
<a id="btnAdd" href="javascript:pageNavigation.openSimpleLightBox({  islookup: true, url:'@Model.GetBaseUrl()/fluxo/index/7f786f15-d644-4351-8763-46bc2923fd21' })"><i class="mdi mdi-plus"></i> Add task</a>
<table id="tasksTable" border="1">

                <tr>
                    <th width="140px">Status</th>
                    <th>Team</th>
                    <th>Description</th>
                    <th>CreatedDate</th>
                    <th>ModifiedDate</th>
                </tr>

@{
    var applicationId = PageContext.FormId;
    
    /* concatenando o parametro */
    var dt = await PageContext.GetDataTableAsync(@"select 
                                        isnull(task.id,'') TaskId,
                                        isnull(task.description,'') TaskDescription,
                                        isnull(team.name,'') Team,
                                        task.log_data_criacao CreatedDate,
                                        task.log_data_alteracao ModifiedDate,
                                        isnull(etp.etp_nome,'') CurrentStep,
                                        frm_status_fluxo StatusFlow
                                        from 
                                            x_tbl_application_task2 task
                                        inner join tbl_formulario form
                                            on task.id = form.frm_id
                                        left join tbl_formulario_etapa etp
                                            on form.etp_id_atual = etp.etp_id and etp.frm_id = form.frm_id
                                        left join x_tbl_team team 
                                            on task.team = team.id

                                        where 
                                        task.deletado = 0
                                        and task.id_application = '"+applicationId+"' order by  task.log_data_alteracao desc, task.log_data_criacao desc ");
    
    
    /* passando como parametro */
    /*var paramsQuery = new List<NpgsqlParameter>();
    paramsQuery.Add(new NpgsqlParameter("@applicationId", applicationId){ NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Uuid });
    var dt = await PageContext.GetDataTableAsync(@"select 
                                        isnull(task.id,'') TaskId,
                                        isnull(task.description,'') TaskDescription,
                                        isnull(team.name,'') Team,
                                        task.log_data_criacao CreatedDate,
                                        task.log_data_alteracao ModifiedDate,
                                        isnull(etp.etp_nome,'') CurrentStep,
                                        frm_status_fluxo StatusFlow
                                        from 
                                            x_tbl_application_task2 task
                                        inner join tbl_formulario form
                                            on task.id = form.frm_id
                                        left join tbl_formulario_etapa etp
                                            on form.etp_id_atual = etp.etp_id and etp.frm_id = form.frm_id
                                        left join x_tbl_team team 
                                            on task.team = team.id

                                        where 
                                        task.deletado = 0
                                        and task.id_application = @applicationId order by  task.log_data_alteracao desc, task.log_data_criacao desc ", paramsQuery.ToArray());*/



    foreach (DataRow dr in dt.Rows)
    {

            var ModifiedDate = dr["ModifiedDate"] == DBNull.Value ? "" : dr["ModifiedDate"].ToString();
            var currentStep = dr["CurrentStep"].ToString();
            var statusFlow = dr["StatusFlow"].ToString();

            if(statusFlow == "A"){
                currentStep = "APPROVED";
            }else if(statusFlow == "X"){
                currentStep = "REJECTED";
            }

            <text>
                <tr class="task-row status-@currentStep" data-taskid='@dr["TaskId"].ToString()'>
                    <td><span class="st">@currentStep</span></td>
                    <td>@dr["Team"].ToString()</td>
                    <td>@dr["TaskDescription"].ToString()</td>
                    <td>@dr["CreatedDate"].ToString()</td>
                    <td>@dr["ModifiedDate"].ToString()</td>
                </tr>
            </text>

    }

}
</table>
```

### [![ezgif.com-video-to-gif.gif](https://wiki.agilityflow.io/uploads/images/gallery/2020-05-May/ezgif.com-video-to-gif.gif)](https://wiki.agilityflow.io/uploads/images/gallery/2020-05-May/ezgif.com-video-to-gif.gif)

### Recarregar no servidor um componente Html ao alterar uma determinada informação do formulário:

Você pode determinar alguns momentos para que as informações de um componente html sejam recarregadas do servidor.

Essa é uma opção vantajosa em situações em que você tenha consultas (queries) de banco de dados no dentro do componente Html e deseja que essa consulta seja atualizada em alguns momentos.

<p class="callout info">Apenas campos do tipo "Lista de seleção (Combo)" e "Pesquisa com auto completar" poderão disparar o recarregamento do Componente Cshtml</p>

##### Exemplo para recarregar o componente cshtml

Suponhamos que você crie um formulário que contenha 2 campos, o **primeiro** é um combo de **Perfil de Acesso** no sistema e o **segundo** campo é um componente CsHtml que contenha uma **tabela que mostre todos os usuários** que possuam o perfil selecionado no **primeiro** campo de **Perfil de Acesso**. Então, todas vez que o campo **Perfil de acesso** for alterado, a tabela de usuários deve ser recarregada para mostrar só os usuários relacionados ao novo perfil alterado.

Para esse exemplo, crie um novo formulário. Nesse novo formulário, crie um combo chamado **Perfil** e abaixo crie um componente CShtml que apresente uma tabela com todos os usuários do perfil selecionado (copiar e colar código abaixo no novo componente).

Código para o Componente Cshtml que listará os usuários

```C#
<h5 id="datatableTitle">Usuários com esse perfil:</h5> 
<table id="usuTable" border="1">

                <tr>
                    <th width="140px">Nome</th>
                    <th>E-mail</th>
                </tr>

@{
    var perfilId = Model.FormularioCamposPreenchidos["perfil"];

    if(perfilId != null && perfilId.ToString() != string.Empty){

        //na query será utilizado no WHERE o id do perfil selecionado no combo
        var query = @"select id, isnull(usu_nome,'') Nome, isnull(usu_email,'') Email  from tbl_usuario u inner join tbl_perfil_usuario pu on u.id = pu.id_tbl_usuario and pu.deletado = 0 where u.deletado = 0 and pu.id_tbl_perfil = '"+perfilId+"' ";
        var dt = await PageContext.GetDataTableAsync(query);

        foreach (DataRow dr in dt.Rows)
        {

                <text>
                    <tr class="task-row" data-taskid='@dr["id"].ToString()'>
                        <td>@dr["Nome"].ToString()</td>
                        <td>@dr["Email"].ToString()</td>
                    </tr>
                </text>

        }

    }

}
</table>
```

Agora adicione esse componente na tela abaixo do campo Perfil.

Clique para editar o componente e marque o checkbox "Ao alterar o campo Perfil", como na imagem abaixo.

![](https://wiki.agilityflow.io/uploads/images/gallery/2020-05-May/scaled-840-0/image-1588955959793.png)

Pronto, agora salve e acesse esse novo formulário criado.

Tente alterar o valor do combo Perfil, se tudo correr bem a tabela de usuários deverá ser recarregada toda vez que o campo perfil for alterado.

[![ezgif.com-video-to-gif.gif](https://wiki.agilityflow.io/uploads/images/gallery/2020-05-May/ezgif.com-video-to-gif.gif)](https://wiki.agilityflow.io/uploads/images/gallery/2020-05-May/ezgif.com-video-to-gif.gif)

#### C# - Adicionar e Atualizar os itens a uma tabela de formulário filho:

Para esse exemplo, será necessário Associar um Formulário Filho a um Formulário Pai, considere que nesse exemplo o Formulário Filho tenha um campo de texto chamado "nome\_filho".

O exemplo abaixo foi colocado dentro de um cshtml do formulário pai e ao criar um novo formulário adicionará um item ao formulário filho e logo em seguida atualizará o item apenas para a demonstração das funções

<p class="callout info">Caso a informação a ser adicionada ou atualizada seja um número, enviar sem separador de milhar e o separador de decimal deve ser "." (ponto), exemplo: para o valor de nove mil e quinhentos, deve ser enviado 9500.00. Para facilitar utilize a função **PageContext.FormatNumberToString\_EnglishFormat(999999.99, 2);**</p>

```C#
@{	

	//id da tabela
    var tableid_relacaoFormularioPaiFilhoId = Guid.Parse("0dd874a9-9c39-4e4f-acc3-02015a60f6bb"); //table id DO FORMULÁRIO FILHO
  
    //info do formulario filho
    var campos_e_valores = new DataDictionary();
    campos_e_valores["nome_filho"] = "Exemplo 01 - " + DateTime.Now;
    campos_e_valores["valor_numerico"] = PageContext.FormatNumberToString_EnglishFormat(999999.99, 2);
  
  
	//testa se é um form NOVO e se NÂO é RASCUNHO pois nesse exemplo quero inserir apenas para formulário NOVOS que não sejam RASCUNHOs
    var isNovo = Model.Id.IsNullOrEmpty();
    var isRascunho = !Model.RascunhoId.IsNullOrEmpty();
  
  
    if(isNovo && !isRascunho){
      
      	//adiciona na tabela filha
       //retorna o id do rascunho desse formlario filho, pois o ID final só será gerado ao Salvar o Formulario PAi
       var formRascunhoId = PageContext.AddChildForm( tableid_relacaoFormularioPaiFilhoId, campos_e_valores);
      
      
      
        //atualiza o item que acabamos de adicionar, apenas para demonstração
		Guid? idFormularioFilho = null;        
        campos_e_valores["nome_filho"] = "Exemplo Atualizado 0123456789 - " + DateTime.Now;            
        PageContext.UpdateChildForm(         	         
            //se ainda não foi salvo pela primeira vez, o item só terá o Id do Rascunho
            rascunhoId, 

            //se já foi salvo pela primeira vez, o item já terá o Id
            //então passa aqui o id (nesse exemplo estamos passando null para atualizar apenas o
            idFormularioFilho, 

            tableid_relacaoFormularioPaiFilhoId,
            campos_e_valores);
     
	}
}


```

#### C# - Obter o total de itens em uma tabela de formulário filho:

```C#
@{	
	//relacaoFormularioPaiFilhoId não é o id do formulario filho e sim o id do campo que gera ao adicionar o formulario filho ao formulario pai
    var relacaoFormularioPaiFilhoId = Guid.Parse("f43330be-0467-7fee-1168-28c9e6d185f0"); //trocar esse id 
  
    var total = await PageContext.CountChildFormsAsync(relacaoFormularioPaiFilhoId);
}
```

#### C# - Enviar e Recuperar parâmetros extras na requisição ajax no partial view (cshtml)

Enviando um parâmetro extra via javascript

```JavaScript
var idsItensPrecosCompostos = formContext.childForm.datatable.getAllChildIds('251c66c9-cb26-f3a8-d014-8a1dd4a6b6aa')
formContext.loadViewComponent("calcular_valor_custo_preco_composto", {
  extraData: { idsItensPrecosCompostos: JSON.stringify(idsItensPrecosCompostos) } ,
  onSuccess: function (response) {
	console.log(response)
  }
})
```

Recuperando um parâmetro extra via C# no CShtml.

Nesse exemplo, dentro do partial view "**calcular\_valor\_custo\_preco\_composto**", colocaremos esse código

```C#
@{
    
    var json_idsItensPrecosCompostos = Request["idsItensPrecosCompostos"];
    

}
<div>@json_idsItensPrecosCompostos</div>
```

#### C# e Javascript - Trabalhando com Json 

1\. Enviando um parâmetro no formato JSON via Javascript. Para isso no código abaixo transformamos um Array em JSON usando o JSON.stringify(...)

```JavaScript
var idsItensPrecosCompostos = formContext.childForm.datatable.getAllChildIds('251c66c9-cb26-f3a8-d014-8a1dd4a6b6aa')
formContext.loadViewComponent("calcular_valor_custo_preco_composto", {
  extraData: { idsItensPrecosCompostos: JSON.stringify(idsItensPrecosCompostos) } ,
  onSuccess: function (response) {
	console.log(response)
  }
})
```

2\. Recuperando um parâmetro JSON via C# e convertendo em Objeto Json

Você poderá utilizar qualquer função que faça parte das Bibliotecas

<table border="1" id="bkmrk-newtonsoft.json-newt" style="border-collapse: collapse; width: 100%;"><tbody><tr><td style="width: 100%;">Newtonsoft.Json</td></tr><tr><td style="width: 100%;">Newtonsoft.Json.Linq</td></tr></tbody></table>

Nesse exemplo, dentro do partial view "**calcular\_valor\_custo\_preco\_composto**", colocaremos esse código para transformar o parametro que era string em um objeto dinamico do tipo JSON:

```C#
@{
    
    var json_idsItensPrecosCompostos = Request["idsItensPrecosCompostos"];    
    dynamic idsItensPrecosCompostos = Newtonsoft.Json.JsonConvert.DeserializeObject(json_idsItensPrecosCompostos);
}

```

3\. Count no JSON

\* o count vai existir em caso do JSON estar no formato de uma lista ( array ).

```C#
@{
    
    var json_idsItensPrecosCompostos = Request["idsItensPrecosCompostos"];    
    dynamic idsItensPrecosCompostos = Newtonsoft.Json.JsonConvert.DeserializeObject(json_idsItensPrecosCompostos);
  	var total = idsItensPrecosCompostos.Count;
}

```

4\. Looping no JSON

\* o foreach vai existir em caso do JSON estar no formato de uma lista ( array ).

```C#
@{
    
    var json_idsItensPrecosCompostos = Request["idsItensPrecosCompostos"];    
    dynamic idsItensPrecosCompostos = Newtonsoft.Json.JsonConvert.DeserializeObject(json_idsItensPrecosCompostos);

    var draftids = new List<string>();
    var formids = new List<string>();
    foreach (var idItem in idsItensPrecosCompostos)
    {
        draftids.Add(idItem.draftid.ToString());
        formids.Add(idItem.formid.ToString());
    }
}

```

#### C# - Transformar Array List em uma string separada por virgula

```C#
@{	
    var itens = new List<string>() { "abacaxi", "mamão", "melão", "banana"};
    var msg = String.Join(",",itens.ToArray());
}
@msg
```

#### C# - Criar um Json dinamicamente

```C#
@{	
    var list_InfoNomeEmail = new JArray() as dynamic; 
    
  	var query = @"select nome, email from x_tbl_xxxxxxxxxxxxx where deletado = 0";
    var dt = await PageContext.GetDataTableAsync(query);
    foreach (DataRow dr in dt.Rows)
    {
      var nome = dr["nome"].ToString();
      var email = dr["email"].ToString();

      //cria o objeto e inclua na lista para depois ser transformado em json
      dynamic infoNomeEmail = new JObject();
      infoNomeEmail.nome = nome;
      infoNomeEmail.email = email;
      list_InfoNomeEmail.Add(infoNomeEmail);
    }
  
  
  //devolve os items em formato json
  if(list_InfoNomeEmail.Count > 0){
    
     //serializa para JSON
     var formata_para_json = JsonConvert.SerializeObject(list_InfoNomeEmail);
    
     //usa o Html.Raw para garantir a integridade dos caracteres no retorno
     @Html.Raw(formata_para_json)
  }

    
    
}

```

# Quadros (Kanban)

No agilityflow, a visualização padrão é por listas. Cada linha da lista corresponde a um registro do formulário. As colunas exibidas são as que foram definidas na configuração do formulário, na [listagem principal de dados](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/listagem-principal-de-dados "Listagem principal de dados").

Entretanto, dependendo da natureza das informações armazenadas no formulário, um outro tipo de visualização seja mais adequado. A visualização em quadros do agilityflow, visa melhorar a maneira de interação do usuário com os registros. Para isso, usamos o método Kanban, que é um método consagrado de mercado, e que é conhecido por ser um método de gestão visual para o controle de tarefas, processos e demandas.

### Usando Um Quadro

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="425" src="https://player.vimeo.com/video/334540317" width="760"></iframe>

#### Opções

Ao abrir um quadro, as opções principais estão no menu do canto superior direito:

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-05-May/scaled-840-0/image-1557164415147.png)

##### Listagem Padrão

Alterna a visualização do formulário para o modo padrão.

##### Visualização Favorita

Ao clicar no ícone ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-05-May/scaled-840-0/image-1557165098840.png) ao lado de uma visualização, ela se torna a padrão do formulário. Com isso, sempre que o formulário for acessado, a primeira visualização será a que for definida como favorita.

##### Criar Outro Quadro

Abre a opção para se criar um novo quadro como explicado no capítulo [criando um quadro](#bkmrk-criando-um-quadro "Criando um Quadro") abaixo.

#### Reordenar as colunas

É possível reordenar as colunas de um quadro. Basta clicar na coluna e arrastar para a posição desejada. O salvamento é feito de forma automática, e a ordem das colunas será sempre o último configurado.

#### Arrastando os Cards

Ao arrastar um card, o valor do campo que é usado para definir as colunas é alterado no registro também. Na prática, arrastar um card para outra coluna é o mesmo que abrir o registro e alterar o campo.

<p class="callout success">É possível também re-ordenar os cards dentro de uma mesma coluna, mudando assim a ordem em que os cards são exibidos.</p>

#### Rascunhos

Os rascunhos podem ser exibidos em dois locais:

##### Na coluna a qual o registro pertence

Caso o registro já possua o campo da coluna preenchido, ele será exibido na coluna respectiva, com uma marcação de rascunho, como mostra a figura abaixo:

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-05-May/scaled-840-0/image-1557165566319.png)

##### Na coluna Rascunhos Não Salvos

Caso não seja possível definir a coluna, o registro será mostrado em uma coluna chamada "Rascunhos Não Salvos".

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-05-May/scaled-840-0/image-1557165725836.png)

#### Coluna "Não Definido"

Os registros que já foram salvos, mas o campo usado para definir as colunas do quadro não tenha sido preenchido, serão colocados em uma coluna chamada "Não Definido".

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-05-May/scaled-840-0/image-1557165857121.png)

#### Adicionar Lista

Essa opção cria novas colunas na visualização. Na prática, é adicionado um registro na tabela dinâmica que o campo usado como base para colunas utiliza.

#### Configurar Ações

É possível criar ações pré-definidas, como explicadas [aqui](http://wiki.agilityflow.io/link/69#bkmrk-%E2%A0-0 "Ações Customizadas (Menu Interno)").

#### Filtro

Os filtros funcionam da mesma [forma](http://wiki.agilityflow.io/link/55#bkmrk-consultar-os-registr "Consultar os Registros") que na visualização padrão.

### Criando um quadro

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="425" src="https://player.vimeo.com/video/334540254" width="760"></iframe>

A criação do quadro pode ser através do [devcenter](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/chapter/devcenter---customizar-o-agilityflow "Devcenter - Customizar o Agilityflow"), na opção Quadros (kanban), ou dentro do próprio formulário (caso o usuário tenha permissão) clicando no canto superior esquerdo onde é mostrada o tipo de listagem, e em seguida em "Criar Quadro":

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-05-May/scaled-840-0/image-1557158748754.png)

Em seguida, é necessário informar qual o formulário será usado como origem dos dados.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-05-May/scaled-840-0/image-1557158733819.png)

Ao selecionar o formulário, outras opções serão apresentadas para configurar o novo quadro:

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-05-May/scaled-840-0/image-1557161744881.png)

#### Campos de apresentação do card

Devido ao espaço limitado desse método, não é possível exibir todos os campos como na forma de listagem padrão. A exibição é limitada a dois campos, que serão apresentados como título e descrição. Abaixo, um exemplo de um cartão com os dois campos

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-05-May/scaled-840-0/image-1557161278164.png)

##### Título do card

É o campo que será usado como título do card. Esse campo é mostrado em negrito, no topo.

##### Descrição do card

É o campo que virá abaixo do título.

### Divisão das colunas/listas do quadro

O método Kanban utiliza colunas para separar e exibir os registros. Nessa opção, é possível definir o critério em que as colunas serão baseadas.

##### As colunas serão baseadas nas etapas do fluxo do formulário?

Quando o formulário informado na origem dos dados for um fluxo com etapas, essa opção estará disponível e as colunas serão as etapas do fluxo. Caso queira outro campo, é possível selecionar a opção "Não". Outros campos aparecerão para definir as colunas.

##### As colunas serão baseadas em um campo existente no formulário?

Deixar como sim padrão.

##### As colunas serão baseadas em qual campo

Selecione o campo do formulário utilizado para a definição das colunas. Nessa opção, apenas os campos com origem em uma lista dinâmica são permitidos, tais como [Lista de Seleção](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/lista-de-sele%C3%A7%C3%A3o-%28combo%29 "Lista de seleção (Combo)"), [Lista com Autocompletar](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/pesquisa-com-auto-completar "Pesquisa com auto completar") e [Radio](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/lista-aberta-com-escolha-%C3%BAnica-%28radio%29 "Lista aberta com escolha única (Radio)").

#### Outras configurações

##### Nome do quadro

Defina um nome para o quadro.

<p class="callout info">Como é possível ter vários quadros pro mesmo formulário, é importante a definição de um nome que explique o propósito do quadro</p>

##### Ao clicar no card deverá abrir inicialmente a aba

São duas opções: formulário e [acompanhamento](http://wiki.agilityflow.io/books/manual-do-usu%C3%A1rio/page/acompanhamento "Acompanhamento").

##### Permitir o usuário criar outras listas/colunas (mostrar botão: "adicionar lista")

O botão adicionar lista fica na extrema direita, no final do quadro, e permite que o usuário crie novas colunas no Kanban. Ao clicar em adicionar lista, na prática, abre o formulário para a criação de um novo registro no formulário usado como fonte pelo campo informado na definição das colunas do quadro.

<p class="callout danger">Seja cuidadoso na criação de um quadro kanban. Após a configuração inicial, não é possível alterá-lo. Caso seja necessário, será preciso criar um novo quadro.</p>

# Listagem do Formulário - customizar com HTML, C#,  CSS e Javascript

O agilityflow permite customização através da Linguagem Html, CSS, Javascript e C# (csharp).

O html do agilityflow é baseado no Razor do framework .Net, isso é, você pode além de customizar com HTML, utilizar código C# (razor) para dar mais flexibilidade e poder ao seu componente Html.

### Customizar a Listagem

Acesse a parte de Desenvolvimento do Formulário que você deseja customizar, para isso, entre na área de customização de um formulário e clique na opção Visual Code Editor, como na imagem abaixo:

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616509257635.png)

Nessa área você poderá customizar a parte de Cadastro e de Listagem utilizando, Javascript, CSS e CSHTML (Razor C# + Html):

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616509450981.png)

Para essa documentação vamos nos preocupar com a área de "List Page".

Nessa área podemos customizar toda página de Listagem Principal de dados, como no exemplo abaixo.

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616510048949.png)

Voltando a área de desenvolvimento, no menu de customização da List Page, teremos sempre 2 arquivos padrões: **CSS** e **Javascript**.

O **CSS** é sempre colocado no topo da página, dentro da tag &lt;HEAD&gt; do Html

O **Javascript** é sempre colocado no final da página, antes do fechamento do &lt;/Body&gt;

### Customizar com CSS

Todo código CSS da página de Listagem Principal do Formulário, deve ficar no arquivo CSS da List Page.

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616533471870.png)

Nessa área, você pode criar customizações via linguagem CSS para toda a listagem e o seu uso é livre.

<p class="callout warning">Levar em consideração o tratamento em CSS para a responsividade da plataforma em outros device, Mobile, Computador Desktop, Tablet, etc.</p>

##### **CSS no Formulário Filho**

O CSS feito para a página de Listagem Principal está colocado apenas no **List Page** do próprio formulário filho, dessa forma ele não será adicionado ao Formulário Pai, então para usar CSS nas tabelas que estão dentro de um formulário Pai, você deve entrar dentro da área de desenvolvimento do Formulário Pai abrir o arquivo **CSS** e ao invés de colocar no CSS da aba **List Page**, coloque **o código** na aba **Form Page** do formulário pai.

### Customizar com Javascript

Todo código Javascript da página de Listagem Principal do Formulário, deve ficar no arquivo Javascript da List Page.

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616527835085.png)

O agilityflow possui uma extensa biblioteca de funções prontas para customização em Javascript que você pode utilizar para diminuir o seu tempo de desenvolvimento.

Além disso nessa parte você está livre para criar funções e regras da forma que for mais conveniente.

O agilityflow disponibiliza uma biblioteca principal em Javascript para a tela de Listagem Princpal. Essa biblioteca está disponível no objeto "**<span style="color: #000000;">listContext</span>**" e abaixo estão descritos as propriedades e métodos pré-programados para facilitar na utilização:

<p class="callout info">Para utilizar qualquer método ou propriedade listadas abaixo, sempre utilizar antes a nomenclatura "listContext.". Exemplo: **listContext.Metodo()** ou **listContext.Propriedade**</p>

##### **Javascript - Bloquear e Desbloquear a abertura do lightbox do Formularío ao clicar na linha do grid**

<table border="1" id="bkmrk-void-setcelcolor%28str" style="border-collapse: collapse; width: 100.881%; height: 296px;"><tbody><tr style="height: 31px;"><td style="width: 26.9134%; height: 31px;"><div><div>void blockLinkOpening()</div></div></td><td style="width: 54.6915%; height: 31px;"><div><div>para bloquear a abertura do link ao clicar na linha do grid</div></div></td></tr><tr style="height: 31px;"><td style="width: 26.9134%; height: 31px;">void unlockLinkOpening()</td><td style="width: 54.6915%; height: 31px;"> para desbloquear o bloqueio a abertura do link ao clicar na linha do grid

</td></tr></tbody></table>

Exemplo de uso

```JavaScript
$(document).on('click', '.btn-exemplo-botao', function (e) {

    //bloqueia a abertura da tela de visualização do formulário
    listcontext.blockLinkOpening();

    //aqui você pode colocar seu código
    //apresenta uma mensagem
    alert('Mensagem de Exemplo')
    
    //desbloqueia a abertura da tela de visualização do formulário
    listcontext.unlockLinkOpening(false);
})
```

##### **Javascript - Idioma, Linguagem / Internationalization (i18n)**

<table border="1" id="bkmrk-currentlanguage.get%28" style="border-collapse: collapse; width: 100.881%; height: 296px;"><tbody><tr><td style="width: 57.901%;"><div><div>currentLanguage.isEnglish()</div></div></td><td style="width: 23.7039%;">retorna true se for inglês</td></tr><tr><td style="width: 57.901%;"><div><div>currentLanguage.isPortuguese()</div></div></td><td style="width: 23.7039%;">retorna true se for português</td></tr><tr><td style="width: 57.901%;"><div><div>currentLanguage.isSpanish()</div></div></td><td style="width: 23.7039%;">returna true se for espanhol</td></tr><tr><td style="width: 57.901%;"><div><div>currentLanguage.getIIF_TextFromCurrentLanguage(text_ptBR, text_ENG ,text_ESP)</div></div></td><td style="width: 23.7039%;">dependendo do idioma, retorna o texto passado em 1 dos 3 parâmetros</td></tr><tr><td style="width: 57.901%;"><div><div>currentLanguage.getNumberDecimalSeparator()</div></div></td><td style="width: 23.7039%;"><div><div>Se NAO for Brasil, retorna ".", pois o formato do número é assim: 999,999,999.999</div><div> </div><div>Se for Brasil, retorna ",", pois o formato do número é assim: 999.999.999,999</div></div></td></tr></tbody></table>

##### **Javascript - Conversão e Formatação de Números**

<table border="1" id="bkmrk-%E2%A0-%E2%A0-number.convert" style="border-collapse: collapse; width: 100.881%; height: 142px;"><tbody><tr style="height: 31px;"><td style="width: 33.9503%; height: 31px;"> </td><td style="width: 47.6546%; height: 31px;"> </td></tr><tr style="height: 31px;"><td style="width: 33.9503%; height: 31px;">number.convertString\_toNumber(strValueToConvert, \[optional\]qtdCasasDecimais)</td><td style="width: 47.6546%; height: 31px;">```JavaScript
//Converte número formatado no idioma atual para um formato numérico javascript, limpo sempre com ponto como separador decimal<br></br><br></br>//se for ingles substitui virgula por nada e mantem o ponto como separador decimal<br></br>var z = listContext.number.convertString_toNumber("100,999.53");<br></br>console.log(z);<br></br>//result: 100999.53<br></br><br></br>//se for portugues substitui ponto por nada e virgula por ponto como separador decimal<br></br>var z = listContext.number.convertString_toNumber("100.999,53");<br></br>console.log(z);<br></br>//result: 100999.53
```

</td></tr><tr style="height: 49px;"><td style="width: 33.9503%; height: 49px;">number.convertNumber\_toStringFormatted(numberToConvert,qtdCasasDecimais)</td><td style="width: 47.6546%; height: 49px;">```JavaScript
//formata o numero, dependendo do idioma<br></br>var z = listContext.number.convertNumber_toStringFormatted(100999.50);<br></br>console.log(z);<br></br>//result: 100,999.50 ou 100.999,50 dependendo do idioma<br></br>
```

</td></tr><tr style="height: 31px;"><td style="width: 33.9503%; height: 31px;">number.getNumberDecimalSeparator()</td><td style="width: 47.6546%; height: 31px;"><div>Se NAO for Brasil, retorna ".", pois o formato do número é assim: 999,999,999.999</div><div> </div><div>Se for Brasil, retorna ",", pois o formato do número é assim: 999.999.999,999</div></td></tr></tbody></table>

##### **Javascript - Data**

<table border="1" id="bkmrk-datetime.getdatenow%28" style="border-collapse: collapse; width: 100.881%; height: 186px;"><tbody><tr><td style="width: 39.5059%;">datetime.getDateNow()</td><td style="width: 42.099%;">data atual, retorna objeto Date do Javascript</td></tr><tr><td style="width: 39.5059%;">datetime.getFormattedDateTime()</td><td style="width: 42.099%;">retorna data no formato 'DD/MM/YYYY'</td></tr><tr style="height: 31px;"><td style="width: 39.5059%; height: 31px;">datetime.getFormattedDate()</td><td style="width: 42.099%; height: 31px;"><div><div>retorna 'DD/MM/YYYY HH:mm'</div></div></td></tr><tr style="height: 31px;"><td style="width: 39.5059%; height: 31px;">datetime.getLastDayOfCurrentMonth()</td><td style="width: 42.099%; height: 31px;"><div><div>último dia do mês atual, <div><div>retorno será 'DD/MM/YYYY'</div></div></div></div></td></tr><tr style="height: 31px;"><td style="width: 39.5059%; height: 31px;">datetime.getLastDayOfMonth(data)</td><td style="width: 42.099%; height: 31px;"><div><div>último dia do mês da data passada como parâmetro</div><div>passar a data ano formato 'DD/MM/YYYY'</div><div>retorno será 'DD/MM/YYYY'</div></div></td></tr></tbody></table>

##### **Javascript -Validação e Comparação entre Datas**

<table border="1" id="bkmrk-datetime.validation." style="border-collapse: collapse; width: 101.017%; height: 827px;"><tbody><tr style="height: 31px;"><td style="width: 35.8022%; height: 31px;">datetime.validation.isCurrentMonthAndYear(data)</td><td style="width: 45.8027%; height: 31px;"><div><div>verifica se a data é do mês e ano corrente</div><div>passar data no formato 'DD/MM/YYYY'</div></div></td></tr><tr style="height: 387px;"><td style="width: 35.8022%; height: 387px;">datetime.validation.compare(date1,compare,date2)</td><td style="width: 45.8027%; height: 387px;"><div>Comparação entre 2 datas</div><div>Passar as datas (date1 e date2) no formato 'DD/MM/YYYY'</div><div></div><div>O parâmetro **compare** pode ser:</div><div></div><div><table border="1" style="border-collapse: collapse; width: 0%; height: 204px;"><tbody><tr style="height: 31px;"><td style="width: 31.3839%; height: 31px;"> </td><td style="width: 39.551%; height: 31px;"><div><div>**Usar assim**</div></div></td><td style="width: 29.0651%; height: 31px;"><div><div>**Ou usar assim**</div></div></td></tr><tr style="height: 31px;"><td style="width: 31.3839%; height: 31px;">Maior que</td><td style="width: 39.551%; height: 31px;"><div><div>'greater'</div></div></td><td style="width: 29.0651%; height: 31px;"><div><div><div><div>'&gt;'</div></div></div></div></td></tr><tr style="height: 31px;"><td style="width: 31.3839%; height: 31px;">Maior ou igual</td><td style="width: 39.551%; height: 31px;"><div><div><div><div>'greater-or-equal'</div></div></div></div></td><td style="width: 29.0651%; height: 31px;"><div><div><div><div>'&gt;='</div></div></div></div></td></tr><tr style="height: 31px;"><td style="width: 31.3839%; height: 31px;">Menor que</td><td style="width: 39.551%; height: 31px;"><div><div>'less'</div></div></td><td style="width: 29.0651%; height: 31px;"><div><div>'&lt;'</div></div></td></tr><tr style="height: 49px;"><td style="width: 31.3839%; height: 49px;">Menor ou igual</td><td style="width: 39.551%; height: 49px;"><div><div>'less-or-equal'</div></div></td><td style="width: 29.0651%; height: 49px;"><div><div>'&lt;='</div></div></td></tr><tr style="height: 31px;"><td style="width: 31.3839%; height: 31px;">Igual</td><td style="width: 39.551%; height: 31px;"><div><div>'equal'</div></div></td><td style="width: 29.0651%; height: 31px;"><div><div>'=='</div></div></td></tr></tbody></table>

</div></td></tr><tr style="height: 253px;"><td style="width: 35.8022%; height: 253px;">datetime.validation.compareToday(compare,date2)</td><td style="width: 45.8027%; height: 253px;"><div>Comparação entre a data passado por parametro com a data atual</div><div>Passar as data (date2) no formato 'DD/MM/YYYY'</div><div></div><div></div><div>O parâmetro **compare** pode ser:</div><div></div><div></div><div><table border="1" style="border-collapse: collapse; width: 100%;"><tbody><tr><td style="width: 34.5089%;"> </td><td style="width: 27.6192%;"><div><div>**Usar assim**</div></div></td><td style="width: 37.8719%;"><div><div>**Ou usar Assim**</div></div></td></tr><tr><td style="width: 34.5089%;">Maior que</td><td style="width: 27.6192%;"><div><div>'greater'</div></div></td><td style="width: 37.8719%;"><div><div>'&gt;'</div></div></td></tr><tr><td style="width: 34.5089%;">Maior ou igual</td><td style="width: 27.6192%;"><div><div>'greater-or-equal'</div></div></td><td style="width: 37.8719%;"><div><div>'&gt;='</div></div></td></tr><tr><td style="width: 34.5089%;">Menor que</td><td style="width: 27.6192%;"><div><div>'less'</div></div></td><td style="width: 37.8719%;"><div><div>'&lt;'</div></div></td></tr><tr><td style="width: 34.5089%;">Menor ou igual</td><td style="width: 27.6192%;"><div><div>'less-or-equal'</div></div></td><td style="width: 37.8719%;"><div><div>'&lt;='</div></div></td></tr><tr><td style="width: 34.5089%;">Igual</td><td style="width: 27.6192%;"><div><div>'equal'</div></div></td><td style="width: 37.8719%;"><div><div>'=='</div></div></td></tr></tbody></table>

</div></td></tr></tbody></table>

##### **Javascript - Manipular Datas** 

<table border="1" id="bkmrk-datetime.add.day%28dat" style="border-collapse: collapse; width: 100.881%; height: 155px;"><tbody><tr style="height: 31px;"><td style="width: 30.617%; height: 31px;">datetime.add.day(data, days)</td><td style="width: 50.9879%; height: 31px;"><div><div>Adicionar **dias** a uma data</div><div>passar data no formato 'DD/MM/YYYY'</div><div>retorno será 'DD/MM/YYYY'</div></div></td></tr><tr style="height: 31px;"><td style="width: 30.617%; height: 31px;">datetime.add.month(data, months)</td><td style="width: 50.9879%; height: 31px;"><div>Adicionar **meses** a uma data</div><div>passar data no formato 'DD/MM/YYYY'</div><div>retorno será 'DD/MM/YYYY'</div></td></tr><tr style="height: 31px;"><td style="width: 30.617%; height: 31px;">datetime.add.year(data, years)</td><td style="width: 50.9879%; height: 31px;"><div>Adicionar **anos** a uma data</div><div>passar data no formato 'DD/MM/YYYY'</div><div>retorno será 'DD/MM/YYYY'</div></td></tr><tr style="height: 31px;"><td style="width: 30.617%; height: 31px;">datetime.add.hour(data, hours)</td><td style="width: 50.9879%; height: 31px;"><div>Adicionar **horas** a uma data</div><div>passar data no formato 'DD/MM/YYYY HH:mm'</div><div>retorno será 'DD/MM/YYYY HH:mm'</div></td></tr><tr style="height: 31px;"><td style="width: 30.617%; height: 31px;">datetime.add.minute(data, minutes)</td><td style="width: 50.9879%; height: 31px;"><div>Adicionar **minutos** a uma data</div><div>passar data no formato 'DD/MM/YYYY HH:mm'</div><div>retorno será 'DD/MM/YYYY HH:mm'</div></td></tr></tbody></table>

##### **Javascript - Outros**

<table border="1" id="bkmrk-ismobile-retorna-tru" style="border-collapse: collapse; width: 100.881%; height: 155px;"><tbody><tr style="height: 31px;"><td style="width: 30.617%; height: 31px;"><div><div>isMobile</div></div></td><td style="width: 50.9879%; height: 31px;"><div><div>retorna true caso seja mobile</div></div></td></tr></tbody></table>

##### **Javascript no Formulário Filho**: Customizar com Javascript a tabela que está dentro de um Formulário Pai

O Javascript feito para a página de Listagem Principal está colocado apenas no **List Page** do próprio formulário filho, dessa forma ele não será adicionado ao Formulário Pai, então para usar Javascript nas tabelas que estão dentro de um formulário Pai, você deve entrar dentro da área de desenvolvimento do Formulário Pai abrir o arquivo **Javascript** e ao invés de colocar no Javascript da aba **List Page**, coloque o código na aba **Form Page** do formulário pai.

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616527791095.png)

<p class="callout danger">Atenção: o objeto **listContext** não está presente no Formulário Pai, ver detalhes mais abaixo para o uso das funções semelhantes</p>

As funções e biblioteca citadas acima não estão presentes da mesma forma no caso de tabelas/listagens filhas e que estarão dentro de um formulário Pai.

A mudança mais impactante é que o listContext não está presente, sendo assim você deve utilizar as funções Javascript descritas nesse [link na documentação](https://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/formul%C3%A1rio---desenvolver-um-html-e-customizar-o-c-css-e-javascript "Formulário - Desenvolver um HTML e customizar o C#,  CSS e Javascript") do `formContext` e `formcontext.childform` que são funçoes da tela de Formulário

##### **Javascript - Bibliotecas de terceiros**

Abaixo estão listadas as biblioteca javascript que já estão importadas na página do formulário:

<table border="1" cellpadding="0" cellspacing="0" dir="ltr" id="bkmrk-asrange%2Fjquery-asran"><colgroup><col width="341"></col></colgroup><tbody><tr><td data-sheets-numberformat="{"1":2,"2":"#,##0.00","3":1}" data-sheets-value="{"1":2,"2":"asrange/jquery-asrange.min.js"}">jquery v1.11.3</td></tr><tr><td data-sheets-numberformat="{"1":2,"2":"#,##0.00","3":1}" data-sheets-value="{"1":2,"2":"asscrollable/jquery.asScrollable.all.js"}">bootstrap</td></tr><tr><td data-sheets-numberformat="{"1":2,"2":"#,##0.00","3":1}" data-sheets-value="{"1":2,"2":"bootstrap-daterangepicker/daterangepicker.js"}">moment</td></tr><tr><td data-sheets-numberformat="{"1":2,"2":"#,##0.00","3":1}" data-sheets-value="{"1":2,"2":"bootstrap-daterangepicker/moment.min.js"}">guid</td></tr><tr><td data-sheets-numberformat="{"1":2,"2":"#,##0.00","3":1}" data-sheets-value="{"1":2,"2":"bootstrap-select/bootstrap-select.js"}">jquery.inputmask/4.0.0-beta.19</td></tr><tr><td data-sheets-numberformat="{"1":2,"2":"#,##0.00","3":1}" data-sheets-value="{"1":2,"2":"bootstrap-tokenfield.js"}">bootstrap-daterangepicker</td></tr></tbody></table>

### Customizar as Colunas da Listagem

No Dev, no menu "Customizar Colunas (Cshtml)" você pode adicionar para cada coluna um arquivo de customização, o arquivo sempre deve ter o mesmo nome do ID do campo/coluna no formulário.

<p class="callout warning">**O arquivo de customização sempre deve ter o mesmo nome do ID do campo/coluna no formulário**</p>

Para esse exemplo, considere um Formulário chamado "**Exemplo de Listagem Customizada**" com o seguintes campos:

<table border="1" id="bkmrk-nome-id-do-campo-tip" style="border-collapse: collapse; width: 100%; height: 155px;"><tbody><tr style="height: 31px;"><td style="width: 33.3333%; height: 31px;">**Nome**</td><td style="width: 22.0987%; height: 31px;">**Id do campo**</td><td style="width: 44.5679%; height: 31px;">**Tipo de Campo**</td></tr><tr style="height: 31px;"><td style="width: 33.3333%; height: 31px;">Data e Hora</td><td style="width: 22.0987%; height: 31px;">data\_e\_hora</td><td style="width: 44.5679%; height: 31px;">Campo com máscara Data e Hora</td></tr><tr style="height: 31px;"><td style="width: 33.3333%; height: 31px;">Decimal com 2 Casas</td><td style="width: 22.0987%; height: 31px;">decimal\_2casas</td><td style="width: 44.5679%; height: 31px;">Campo Número - Decimal com 2 casas</td></tr><tr style="height: 31px;"><td style="width: 33.3333%; height: 31px;">Decimal com 3 Casas</td><td style="width: 22.0987%; height: 31px;">decimal\_3casas</td><td style="width: 44.5679%; height: 31px;">Campo Número - Número Decimal com 3 casas</td></tr><tr style="height: 31px;"><td style="width: 33.3333%; height: 31px;">E-mail</td><td style="width: 22.0987%; height: 31px;">email</td><td style="width: 44.5679%; height: 31px;">Campo de Texto</td></tr><tr><td style="width: 33.3333%;">Nome</td><td style="width: 22.0987%;">nome</td><td style="width: 44.5679%;">Campo de Texto</td></tr><tr><td style="width: 33.3333%;">Idade</td><td style="width: 22.0987%;">idade</td><td style="width: 44.5679%;">Campo Número - Inteiro</td></tr></tbody></table>

<p class="callout warning">Foram adicionados campos **NUMÉRICOS e de DATA** para mostrar como você pode utilizar esse tipo de informação para fazer condicionais com essas informações.</p>

Agora entra na área de listagem e coloque os seguintes campos:

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616510978999.png)

Repare que na listagem eu adicionei os campos de Log, "Data criação" e "Criado Por". Esses são campos gerados automaticamente pelo Agilityflow, e você também pode utilizar essas informações na customização das colunas.

Agora volte para a área de customização:

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616511308170.png)

Agora precisamos criar os arquivos de customização para cada coluna.

Crie através do botão NOVO CSHTML um arquivo para cada coluna que incluímos na listagem. Para isso, utilize o id da coluna como o nome do arquivo. Suas configurações devem estar como na imagem abaixo:

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616511278351.png)

Antes de mostrar cada exemplo, abaixo descrevemos alguns métodos e propriedades disponíveis no contexto de cada customização de coluna, para que você consiga entender o que podemos fazer.

#### Propriedade e Métodos C# disponíveis no contexto do CSHTML da Coluna

O agilityflow disponibiliza uma biblioteca **C#** de contexto para a customização das colunas. Essa biblioteca está disponível no objeto "<span style="color: #000000;">**ColumnContext**</span>" e abaixo estão descritos as propriedades e métodos pré-programados para facilitar na utilização:

<p class="callout info">Para utilizar qualquer método ou propriedade listadas abaixo, sempre utilizar antes a nomenclatura "ColumnContext.". Exemplo: **ColumnContext.Metodo()** ou **ColumnContext.Propriedade**</p>

##### C# - Propriedades

<table border="1" id="bkmrk-bool-israscunho-%7Bget" style="border-collapse: collapse; width: 100.711%; height: 62px;"><tbody><tr><td style="width: 30.4938%;">string FormId</td><td style="width: 36.1728%;">Id do registro, pode ser em branco ou nulo qdo for um rascunho</td></tr><tr style="height: 31px;"><td style="width: 30.4938%; height: 31px;">bool IsRascunho {get;}</td><td style="width: 36.1728%; height: 31px;">Retorna true caso a linha seja um Rascunho</td></tr><tr><td style="width: 30.4938%;">string DraftId</td><td style="width: 36.1728%;">Id do rascunho</td></tr><tr style="height: 31px;"><td style="width: 30.4938%; height: 31px;">int RowIndex {get;}</td><td style="width: 36.1728%; height: 31px;">Retorna a posição da Linha na tabela, começando do 0</td></tr></tbody></table>

##### C# - Recuperar (Get) valor das colunas

<table border="1" id="bkmrk-string-getvalue%28stri" style="border-collapse: collapse; width: 100.881%; height: 235px;"><tbody><tr style="height: 31px;"><td style="width: 35.3085%; height: 31px;">string GetText(string idColuna)</td><td style="width: 46.2964%; height: 31px;">Retorna uma string com o **texto** da coluna passada no parâmetro

*Essa função já traz o campo formatado com a máscara que está definida no Formulário. Por exemplo, caso seja um campo decimal, ele já trará o valor formatado de acordo com o idioma 10.000,00 ou 10.000,00 (caso você precise utilizar esse valor em alguma soma ou condicional ,utilize o método GetDecimal ao invés de GetText)*

</td></tr><tr style="height: 37px;"><td style="width: 35.3085%; height: 37px;">string GetValue(string idColuna)</td><td style="width: 46.2964%; height: 37px;">retorna o **ID** ao invés do Texto.

\* Apenas para campos que sejam uma Lista Dinâmica, Lista Estática, Checkbox ou um campo que tenha como apresentação um Texto de outra Base de Dados mas por trás esse campo é um ID.

\* caso não encontre ou o valor seja nulo retorna em branco ao invés de null

</td></tr><tr style="height: 31px;"><td style="width: 35.3085%; height: 31px;">int? GetInt(string idColuna)</td><td style="width: 46.2964%; height: 31px;">Retorna o valor da coluna no tipo INT (inteiro), caso esse campo no formulário seja um número, se o valor for 10.000,99

Será retornado: 10000

</td></tr><tr style="height: 31px;"><td style="width: 35.3085%; height: 31px;">decimal? GetDecimal(string idColuna)</td><td style="width: 46.2964%; height: 31px;">Retorna o valor da coluna no tipo Decimal, caso esse campo no formulário seja um número, se o valor for 10.000,99 Será retornado: 10000.99

</td></tr><tr style="height: 31px;"><td style="width: 35.3085%; height: 31px;">DateTime? GetDateTime(string idColuna)</td><td style="width: 46.2964%; height: 31px;">Retorna o valor da coluna no tipo DateTime para valores que estão no formato de data dd/MM/yyyy ou dd/MM/yyyy hh:mm</td></tr></tbody></table>

<p class="callout warning">**DICA: Nos métodos acima só estarão disponíveis informações dos campos que foram marcados para aparecer na listagem. Caso você precise usar uma informação mas não quer que ela se torne uma coluna da lista, adicione ela como disponível na listagem e marque ela como invisível. Veja mais [detalhes aqui](https://wiki.agilityflow.io/link/98#bkmrk-como-utilizar-a-info)**</p>

##### C# - Customização visual da coluna ou linha

<table border="1" id="bkmrk-void-setcelcolor%28str-0" style="border-collapse: collapse; width: 100.881%; height: 62px;"><tbody><tr style="height: 31px;"><td style="width: 26.9134%; height: 31px;">void SetCelColor(string color)</td><td style="width: 54.6915%; height: 31px;">**Pinta o fundo da célula da coluna**

Algumas cores já estão predefinidas seguindo padrão de tonalidade do agilityflow. Essas cores são: "red", "green", "yellow", "blue". Caso você julgue necessário você também pode utilizar cores no formato hexadecimal

if(dt\_data\_e\_hora &lt; DateTime.Now){   
@ColumnContext.SetRowColor("red")

  
//se em até 5 dias for ficar atrasado, coloca em amarelo a célula  
}else if(dt\_data\_e\_hora &lt; DateTime.Now.AddDays(5)){   
@ColumnContext.SetCelColor("yellow")  
}

**importante usar o @ na frente**

</td></tr><tr style="height: 31px;"><td style="width: 26.9134%; height: 31px;">void SetRowColor(string color)</td><td style="width: 54.6915%; height: 31px;">**Pinta o fundo da linha da linha**

Algumas cores já estão predefinidas seguindo padrão de tonalidade do agilityflow. Essas cores são: "red", "green", "yellow", "blue". Caso você julgue necessário você também pode utilizar cores no formato hexadecimal

if(dt\_data\_e\_hora &lt; DateTime.Now){   
@ColumnContext.SetRowColor("red")

  
//se em até 5 dias for ficar atrasado, coloca em amarelo a célula  
}else if(dt\_data\_e\_hora &lt; DateTime.Now.AddDays(5)){   
@ColumnContext.SetCelColor("yellow")  
}

**importante usar o @ na frente**

</td></tr></tbody></table>

##### C# - Variáveis Globais no contexto da listagem

Você pode precisar guardar informações no contexto geral da listagem.

Imagine que você queira fazer uma soma geral ou guardar uma informação que você já tratou na primeira linha e que agora você precisa utiliza-la na última coluna, da última linha. Simples, basta utilizar o método SetGlobalVariable para colocar uma informação no contexto e depois busca-la com o método GetGlobalVariable para

<table border="1" id="bkmrk-void-setglobalvariab" style="border-collapse: collapse; width: 100.881%; height: 296px;"><tbody><tr style="height: 49px;"><td style="width: 37.9011%; height: 49px;">void SetContextVariable(string key, string value)</td><td style="width: 43.7038%; height: 49px;">Colocar uma variável e seu valor no contexto da listagem</td></tr><tr style="height: 31px;"><td style="width: 37.9011%; height: 31px;">string GetContextVariable(string key)</td><td style="width: 43.7038%; height: 31px;">Recupera o valor de uma variável que esteja no contexto da listagem</td></tr></tbody></table>

##### C# - Formatação Numérica

<p class="callout info">***Se você está utilizando o método GetText(..) para buscar uma coluna numérica, esse metódo já retornará o número formatado e não será necessário nenhuma formatação adicional.  
  
Se você está utilizando o método GetDecimal(..) ele não virá formatado pois ele retorna o tipo DECIMAL do C#, sendo assim, se você precisa do dado formatado você pode utilizar o GetText(..)***</p>

<table border="1" id="bkmrk-string-formatdecimal" style="border-collapse: collapse; width: 100.881%; height: 296px;"><tbody><tr style="height: 49px;"><td style="width: 52.7159%; height: 49px;">string FormatDecimalToString(object numDecimal, string mascaraTipo = "dec2")</td><td style="width: 45.8026%; height: 49px;">formata object 999999999.55 para o formato da mascara de acordo com o idioma.

\- se for ingles, será 999,999,999.55  
\- se for portugues, será 999.999.999,55

</td></tr><tr style="height: 31px;"><td style="width: 52.7159%; height: 31px;">string FormatNumberToString\_EnglishFormat(object num, \[optional\]int? qtdCasasDecimais)</td><td style="width: 45.8026%; height: 31px;">converte decimal para string, porém sempre a string vem no formato Inglês.

coloca a a mesma qtd de casas decimais, caso o parâmetro qtdCasasDecimais estivar em branco

</td></tr></tbody></table>

##### C# - Usuário logado

<table border="1" id="bkmrk-string-getusuariolog" style="border-collapse: collapse; width: 100.881%; height: 155px;"><tbody><tr style="height: 31px;"><td style="width: 37.9011%; height: 31px;">string GetUsuarioLogadoNome()</td><td style="width: 43.7038%; height: 31px;">retorna o nome do usuário logado</td></tr><tr style="height: 31px;"><td style="width: 37.9011%; height: 31px;">string GetUsuarioLogadoPrimeiroNome()</td><td style="width: 43.7038%; height: 31px;">retorna o primeiro nome do usuário logado</td></tr><tr style="height: 31px;"><td style="width: 37.9011%; height: 31px;">string GetUsuarioLogadoPrimeiroESegundoNome()</td><td style="width: 43.7038%; height: 31px;">retorna o primeiro e o segundo nome do usuário logado</td></tr><tr style="height: 31px;"><td style="width: 37.9011%; height: 31px;">string GetUsuarioLogadoEmail()</td><td style="width: 43.7038%; height: 31px;">retorna o e-mail do usuário logado</td></tr><tr style="height: 31px;"><td style="width: 37.9011%; height: 31px;">Guid GetUsuarioLogadoId()</td><td style="width: 43.7038%; height: 31px;">retorna o id do usuário logado</td></tr></tbody></table>

#####  

##### C# - Idioma, Linguagem / Internationalization (i18n)

<table border="1" id="bkmrk-currentlanguage.isen" style="border-collapse: collapse; width: 100.881%; height: 296px;"><tbody><tr><td style="width: 57.901%;"><div><div>CurrentLanguage.IsEnglish()</div></div></td><td style="width: 23.7039%;">retorna true se for inglês</td></tr><tr><td style="width: 57.901%;"><div><div>CurrentLanguage.IsPortuguese()</div></div></td><td style="width: 23.7039%;">retorna true se for português</td></tr><tr><td style="width: 57.901%;"><div><div>CurrentLanguage.IsSpanish()</div></div></td><td style="width: 23.7039%;">returna true se for espanhol</td></tr><tr><td style="width: 57.901%;"><div><div>CurrentLanguage.GetIIF_TextFromCurrentLanguage(text_ptBR, text_ENG ,text_ESP)</div></div></td><td style="width: 23.7039%;">dependendo do idioma, retorna o texto passado em 1 dos 3 parâmetros</td></tr></tbody></table>

#####  

##### C# - Geral

<table border="1" id="bkmrk-string-geturlbase%28%29-" style="border-collapse: collapse; width: 100.881%; height: 111px;"><tbody><tr style="height: 49px;"><td style="width: 44.6912%; height: 49px;">string GetUrlBase()</td><td style="width: 36.9137%; height: 49px;">Retorna a URL base onde o agilityflow está instalado</td></tr><tr style="height: 31px;"><td style="width: 44.6912%; height: 31px;"><span style="text-decoration: line-through;">string GetEnvironmentVariable(string nomeDaVariavel)</span></td><td style="width: 36.9137%; height: 31px;"><span style="text-decoration: line-through;">Retorna o valor de uma variável de ambiente</span>

**Não é perimitir utilizar esse metodo nesse contexto**

</td></tr><tr style="height: 31px;"><td style="width: 44.6912%; height: 31px;"><span style="text-decoration: line-through;">string GetEnvironmentVariable\_Text(string nomeDaVariavel)</span></td><td style="width: 36.9137%; height: 31px;"><span style="text-decoration: line-through;">Retorna o texto de uma variável de ambiente</span>

<span style="text-decoration: line-through;">**Não é perimitir utilizar esse metodo nesse contexto**</span>

</td></tr></tbody></table>

#### Elementos Visuais para deixar a tabela mais bonita

<p class="callout info"><span class="info-options">Você pode utilizar qualquer elemento HTML para a customização da coluna.</span></p>

<span class="info-options">Abaixo listamos alguns elementos pré-definidos no agilityflow para facilitar o seu desenvolvimento.</span>

<span class="info-options">\* Caso seja necessário criar um elemento visual de forma dinâmica ou dentro de um IF, usar a função Html.Raw(), como no exemplo abaixo:  
</span>

<table id="bkmrk-small-text-%3Ctext-sma" style="width: 931px; height: 1858px;"><tbody><tr style="height: 50px;"><td style="width: 127px; height: 50px;">Button</td><td style="width: 142px; height: 50px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616516230091.png)

</td><td class="col-code" style="width: 662px; height: 84px;">```pt
<button type="button" class="btn-list">Botão</button>
```

</td></tr><tr style="height: 76px;"><td class="col-desc" style="width: 127px; height: 76px;">Small Text</td><td class="col-varvalue" style="width: 142px; height: 76px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514394521.png)

</td><td class="col-code" style="width: 662px; height: 76px;">```pt
<text-small>small</text-small>
```

</td></tr><tr style="height: 84px;"><td class="col-desc" style="width: 127px; height: 84px;">Tag Red</td><td class="col-varvalue" style="width: 142px; height: 84px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616669633685.png)

</td><td class="col-code" style="width: 662px; height: 84px;">```pt
<tag-red>red</tag-red> 
```

</td></tr><tr><td class="col-desc" style="width: 127px;">Tag Outline Red</td><td class="col-varvalue" style="width: 142px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616669622189.png)

</td><td class="col-code" style="width: 662px;">```pt
<tag-outline-red>red</tag-outline-red> 
```

</td></tr><tr style="height: 84px;"><td class="col-desc" style="width: 127px; height: 84px;">Tag Yellow</td><td class="col-varvalue" style="width: 142px; height: 84px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616669647727.png)

</td><td class="col-code" style="width: 662px; height: 84px;">```pt
<tag-yellow>yellow</tag-yellow> 
```

</td></tr><tr><td class="col-desc" style="width: 127px;">Tag Outline Yellow</td><td class="col-varvalue" style="width: 142px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616669656783.png)

</td><td class="col-code" style="width: 662px;">```pt
<tag-outline-yellow>yellow</tag-outline-yellow> 
```

</td></tr><tr style="height: 78px;"><td class="col-desc" style="width: 127px; height: 78px;">Tag Blue</td><td class="col-varvalue" style="width: 142px; height: 78px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616669669098.png)

</td><td class="col-code" style="width: 662px; height: 78px;">```pt
<tag-blue>blue</tag-blue> 
```

</td></tr><tr><td class="col-desc" style="width: 127px;">Tag Outline Blue</td><td class="col-varvalue" style="width: 142px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616669676419.png)

</td><td class="col-code" style="width: 662px;">```pt
<tag-outline-blue>blue</tag-outline-blue> 
```

</td></tr><tr style="height: 79px;"><td class="col-desc" style="width: 127px; height: 79px;">Tag Green</td><td class="col-varvalue" style="width: 142px; height: 79px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616669684182.png)

</td><td class="col-code" style="width: 662px; height: 79px;">```pt
<tag-green>green</tag-green> 
```

</td></tr><tr><td class="col-desc" style="width: 127px;">Tag Outline Green</td><td class="col-varvalue" style="width: 142px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616669691223.png)

</td><td class="col-code" style="width: 662px;">```pt
<tag-outline-green>green</tag-outline-green> 
```

</td></tr><tr style="height: 76px;"><td class="col-desc" style="width: 127px; height: 76px;">Tag gray</td><td class="col-varvalue" style="width: 142px; height: 76px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616669700632.png)

</td><td class="col-code" style="width: 662px; height: 76px;">```pt
<tag-gray>gray</tag-gray> 
```

</td></tr><tr><td class="col-desc" style="width: 127px;">Tag Outline gray</td><td class="col-varvalue" style="width: 142px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616669709348.png)

</td><td class="col-code" style="width: 662px;">```pt
<tag-outline-gray>gray</tag-outline-gray> 
```

</td></tr><tr style="height: 91px;"><td class="col-desc" style="width: 127px; height: 91px;">Avatar</td><td class="col-varvalue" style="width: 142px; height: 91px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514447071.png)

</td><td class="col-code" style="width: 662px; height: 91px;">```pt
<avatars><avatar>John Charles</avatar></avatars> 
```

</td></tr><tr style="height: 93px;"><td class="col-desc" style="width: 127px; height: 93px;">Avatar</td><td class="col-varvalue" style="width: 142px; height: 93px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514457075.png)

</td><td class="col-code" style="width: 662px; height: 93px;">```pt
<avatars><avatar>Luigi Charles</avatar><avatar>Brain Colleman</avatar></avatars> 
```

</td></tr><tr style="height: 111px;"><td class="col-desc" style="width: 127px; height: 111px;">Rating</td><td class="col-varvalue" style="width: 142px; height: 111px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514483212.png)

</td><td class="col-code" style="width: 662px; height: 111px;">```pt
<star-rating max="4" show-value="false">3</star-rating> 
```

</td></tr><tr style="height: 86px;"><td class="col-desc" style="width: 127px; height: 86px;">Rating</td><td class="col-varvalue" style="width: 142px; height: 86px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514526108.png)

</td><td class="col-code" style="width: 662px; height: 86px;">```pt
<star-rating max="6" show-value="true">3.5</star-rating> 
```

</td></tr><tr style="height: 87px;"><td class="col-desc" style="width: 127px; height: 87px;">Rating Red</td><td class="col-varvalue" style="width: 142px; height: 87px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514532757.png)

</td><td class="col-code" style="width: 662px; height: 87px;">```pt
<star-rating color='red' max="7" show-value="false">6</star-rating> 
```

</td></tr><tr style="height: 83px;"><td class="col-desc" style="width: 127px; height: 83px;">Rating Blue</td><td class="col-varvalue" style="width: 142px; height: 83px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514538876.png)

</td><td class="col-code" style="width: 662px; height: 83px;">```pt
<star-rating color='blue' max="7" show-value="false">6</star-rating> 
```

</td></tr><tr style="height: 81px;"><td class="col-desc" style="width: 127px; height: 81px;">Rating Green</td><td class="col-varvalue" style="width: 142px; height: 81px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514545330.png)

</td><td class="col-code" style="width: 662px; height: 81px;">```pt
<star-rating color='green' max="7" show-value="false">6</star-rating> 
```

</td></tr><tr style="height: 79px;"><td class="col-desc" style="width: 127px; height: 79px;">Rating Gray</td><td class="col-varvalue" style="width: 142px; height: 79px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514551364.png)

</td><td class="col-code" style="width: 662px; height: 79px;">```pt
<star-rating color='gray' max="7" show-value="false">6</star-rating> 
```

</td></tr><tr style="height: 76px;"><td class="col-desc" style="width: 127px; height: 76px;">Rating Ball</td><td class="col-varvalue" style="width: 142px; height: 76px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514586755.png)

</td><td class="col-code" style="width: 662px; height: 76px;">```pt
<ball-rating max="4" show-value="false">3</ball-rating> 
```

</td></tr><tr style="height: 76px;"><td class="col-desc" style="width: 127px; height: 76px;">Rating Ball</td><td class="col-varvalue" style="width: 142px; height: 76px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514594547.png)

</td><td class="col-code" style="width: 662px; height: 76px;">```pt
<ball-rating max="6" show-value="true">3.5</ball-rating> 
```

</td></tr><tr style="height: 76px;"><td class="col-desc" style="width: 127px; height: 76px;">Rating Ball Red</td><td class="col-varvalue" style="width: 142px; height: 76px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514600103.png)

</td><td class="col-code" style="width: 662px; height: 76px;">```pt
<ball-rating color='red' max="7" show-value="false">6</ball-rating> 
```

</td></tr><tr style="height: 76px;"><td class="col-desc" style="width: 127px; height: 76px;">Rating Ball Blue</td><td class="col-varvalue" style="width: 142px; height: 76px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514605734.png)

</td><td class="col-code" style="width: 662px; height: 76px;">```pt
<ball-rating color='blue' max="7" show-value="false">6</ball-rating> 
```

</td></tr><tr style="height: 76px;"><td class="col-desc" style="width: 127px; height: 76px;">Rating Ball Green</td><td class="col-varvalue" style="width: 142px; height: 76px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514613027.png)

</td><td class="col-code" style="width: 662px; height: 76px;">```pt
<ball-rating color='green' max="7" show-value="false">6</ball-rating> 
```

</td></tr><tr style="height: 76px;"><td class="col-desc" style="width: 127px; height: 76px;">Rating Ball Gray</td><td class="col-varvalue" style="width: 142px; height: 76px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514619953.png)

</td><td class="col-code" style="width: 662px; height: 76px;">```pt
<ball-rating color='gray' max="7" show-value="false">6</ball-rating> 
```

</td></tr><tr style="height: 76px;"><td class="col-desc" style="width: 127px; height: 76px;">Break Line</td><td class="col-varvalue" style="width: 142px; height: 76px;"> </td><td class="col-code" style="width: 662px; height: 76px;">```pt
<br/>
```

</td></tr><tr style="height: 88px;"><td class="col-desc" style="width: 127px; height: 88px;">Line</td><td class="col-varvalue" style="width: 142px; height: 88px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514634174.png)

</td><td class="col-code" style="width: 662px; height: 88px;">```pt
<hr/>
```

</td></tr></tbody></table>

### Exemplos de customização

Agora que já sabemos os métodos que podemos utilizar para facilitar a customização, abaixo listamos alguns exemplos de como utiliza-los na prática.

#### Comparação por Data e Hora. Pintar a linha e coluna se a data e hora (DateTime) estiver atrasada

No arquivo de customização **"data\_e\_hora",** vamos criar uma regrinha:

\- Vamos buscar a data e hora já no tipo DateTime para podermos usar na condicional   
\- Se a data estiver atrasada, colocaremos a linha em vermelho  
\- Se faltar até 5 dias a para chegar na data, colocaremos a célula da tabela em amarelo

```C#
@{    
    //buscar a data e hora já no tipo Datetime para podermos usar na condicional
    var dt_data_e_hora = ColumnContext.GetDateTime("data_e_hora");

    //se não for possível converter a data, ela sempre retornará null
    if(dt_data_e_hora != null){

        //se está atrasada, coloca em vermelho a linha
        if(dt_data_e_hora  < DateTime.Now){ 
            @ColumnContext.SetRowColor("red")


        //se em até 5 dias for ficar atrasado, coloca em amarelo a célula
        }else if(dt_data_e_hora  < DateTime.Now.AddDays(5)){ 
            @ColumnContext.SetCelColor("yellow")
        }
    }

    //e por fim mostramos a data e a hora na célula
}
    @dt_data_e_hora        
```

resultado:

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514761299.png)

#### Comparação Numérica e tipos Numéricos

No arquivo de customização **"decimal\_3casas",** vamos criar uma regrinha:

\- Vamos mostrar na coluna o valor do campo "Decimal com 3 Casas", buscando ele no formato **<span style="text-decoration: underline;">string</span>** e usando o método `GetText`  
\- Vamos mostrar na coluna o valor do campo "Decimal com 3 Casas", buscando ele como tipo **<span style="text-decoration: underline;">inteiro</span>** (ignorando as casas decimais) e usando o método `GetInt`  
\- Vamos mostrar na coluna o valor do campo "Decimal com 3 Casas", buscando ele no tipo **<span style="text-decoration: underline;">decimal</span>** e usando o método `GetDecimal`  
\- Vamos fazer uma condicional para mostrar uma tag em verde escrito "é Maior que 10 mil" caso o valor do campo seja maior que 10.000,00  
\- Vamos fazer uma condicional para mostrar uma tag em vermelho escrito "é Menor que 10 mil" caso o valor do campo seja menor que 10.000,00

```C#
@ColumnContext.GetText("decimal_3casas")
<br>
@ColumnContext.GetInt("decimal_3casas")
<br>
@ColumnContext.GetDecimal("decimal_3casas")
<br>
@{
    if(ColumnContext.GetDecimal("decimal_3casas") > 10000){
        <text>
            <tag-green>é MAIOR que 10 mil</tag-green>
        </text>
    }else{
        <text>
            <tag-red>é MENOR que 10 mil</tag-red>
        </text>
    }
}
```

resultado:

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616515952336.png)

#### Coluna Invisível: Como acessar via *GetText* os dados de um campo do formulário que não está marcado para aparecer como coluna da lista?

<p class="callout warning">**Dica:**  
Apenas campos que estão marcados para serem colunas da lista podem ser acessados através do método `ColumnContext.GetText(...),`sendo assim se você quer acessar uma informação através do `GetText `mas não quer que essa informação seja uma coluna, deixe ela invisível para os usuários, seguindo o procedimento abaixo.</p>

Seguindo nosso exemplo, na coluna **NOME** da listagem, eu quero concatenar o Nome e a Idade do usuário, porém como eu não coloquei a Idade para ser visível na lista, ela não estará acessível se eu não seguir esses passos:

<div id="bkmrk-passo-1.-adicione-a-">Passo 1. Adicione a coluna NOME na listagem do formulário Cliente</div><div id="bkmrk-passo%E2%A02.-adicione-a">Passo 2. Adicione a coluna IDADE na listagem do formulário Cliente</div><div id="bkmrk-passo%E2%A03.-desmarque-">Passo 3. Desmarque na coluna IDADE as opções "Visível no Mobile" e "Visível no Desktop"</div><div id="bkmrk-%E2%A0-4"> </div><div id="bkmrk-pronto%2C-agora-a-colu">Pronto, agora a coluna idade ficará disponível para ser acessar pelo contexto: `ColumnContext.GetText("idade")```</div>mas não será uma coluna da Listagem.

#### Adicionar um botão na listagem

No arquivo de customização **"email",** vamos criar uma regrinha:

\- Vamos mostrar o valor do campo E-mail   
\- Vamos adicionar um botão que quando o usuário clicar apresentará a msg "Mensagem de Exemplo"  
\- Para esse exemplo, vamos precisar fazer uso do arquivo padrão "Javascript" do List Page

No arquivo de customização de **"email",** cole o código abaixo

```C#
@ColumnContext.GetText("email") 
<br>
<button type="button" class="btn-list btn-exemplo-botao">Botão</button>
```

No arquivo Javascript da List Page, cole o código abaixo

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616527835085.png)

```JavaScript
$(document).on('click', '.btn-exemplo-botao', function (e) {

    //bloqueia a abertura da tela de visualização do formulário
    listcontext.blockLinkOpening();

    //aqui você pode colocar seu código
    //apresenta uma mensagem
    alert('Mensagem de Exemplo')
    

    //desbloqueia a abertura da tela de visualização do formulário
    listcontext.unlockLinkOpening(false);
})

```

##### **Formulário Filho:** No caso dessa tabela também estar dentro de um <span style="text-decoration: underline;">**Formulário Pai**</span>, algumas coisas mudam:

O Javascript feito acima está colocado apenas no **List Page da página de Listagem**, dessa forma ele não será adicionado ao Formulário Pai, então você deve entrar dentro da área de desenvolvimento do Formulário Pai abrir o arquivo **Javascript** e ao invés de colocar o código no Javascript da aba List Page, coloque ocódigo **abaixo** na aba **Form Page** do formulário pai.

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616527791095.png)

<p class="callout warning">No caso de Formulário Filho dentro de um formulário Pai, não existirá no Javascript a biblioteca listContext pois essa biblioteca só está presenta na tela de lista. Nesse caso precisaremos usar o formContext mas como estamos falando de um Formulário Filho, as funções referente a ele está dentro de `formContext.childForm.xxxx()`</p>

Código para o mesmo funcionamento do botão mas agora no formulário Pai.  
**Observe que no código abaixo, além da mudança de local do Javascript, o `listContext.` foi substituido por `formContext.childForm`**

```JavaScript
$(document).on('click', '.btn-exemplo-botao', function (e) {

    //bloqueia a abertura da tela de visualização do formulário
    formcontext.childForm.blockLinkOpening();

    //aqui você pode colocar seu código
    //apresenta uma mensagem
    alert('Mensagem de Exemplo')
    

    //desbloqueia a abertura da tela de visualização do formulário
    formcontext.childForm.unlockLinkOpening(false);
})

```

Resultado:

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616525270847.png)

Quando o usuário, clicar no botão "Botão" ele receberá essa mensagem:

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616525325946.png)

#### Como utilizar uma Variável de Contexto ou Variável Global para interagir e armazenar informações entre todas as linhas e colunas da mesma listagem

Para esse exemplo demonstraremos o uso dos métodos `ColumnContext.GetGlobalVariable("variavel");` e ColumnContext.SetGlobalVariable("variavel", "valor");

No arquivo de customização **"nome",** vamos criar uma regrinha:

\- Vamos mostrar o valor do campo Nome, concatenado com a palavra "Nome:"  
\- Vamos somar a idade da linha anterior com a linha atual, até a última linha ser a soma total das idades  
\- Vamos mostrar uma frase mostrando a posição da linha (RowIndex) concatenada com a idade total somada até aquele momento

```C#
@{
    //recupera o total já gravado em uma variavel global
    var str_idade_total = ColumnContext.GetGlobalVariable("idade");

    //pega a idade referente a essa linha na tabela
  	//já puxa a idade no formato INT (número inteiro) para ser possível 
  	//fazer a soma total sem precisar de conversão de número
    var idade = @ColumnContext.GetInt("idade");

    //se a idade não tiver sido preenchida no formulário, então considera ela como zero
    if(idade == null)
    {
        idade = 0;
    }

    //se a idade total já estiver sido preenchida, então, soma com a idade dessa linha
    //caso contrário ignora pois será o primeiro registro da linha e não precisará ser feito nenhuma soma
    if(!string.IsNullOrEmpty(str_idade_total)){    
        idade = Convert.ToInt32(str_idade_total) + idade;        
    }

    //coloca novamente a soma das idades totais na Variável Global, para ser recuparada na próxima linha
    str_idade_total = idade.ToString();
    ColumnContext.SetGlobalVariable("idade", str_idade_total);
    
}
Nome: @ColumnContext.GetText("nome")
<br>
Até o RowIndex @ColumnContext.RowIndex a Idade era de  @str_idade_total anos
```

#### Customizar e acessar as colunas de Log: Data de criação, Data de Alteração, Criado por e Alterado por.

Para recuperar os campos de Log na listagem através do `GetText(...)` ou `GetDateTime(...)` utilizar os ids padrões de cada campo:

<table border="1" id="bkmrk-nome-id-data-de-cria" style="border-collapse: collapse; width: 100%; height: 124px;"><tbody><tr><td style="width: 50%;">**Nome**</td><td style="width: 50%;">**ID**</td></tr><tr style="height: 31px;"><td style="width: 50%; height: 31px;">Data de criação</td><td style="width: 50%; height: 31px;">log\_data\_criacao</td></tr><tr style="height: 31px;"><td style="width: 50%; height: 31px;">Data de Alteração</td><td style="width: 50%; height: 31px;">log\_data\_alteracao</td></tr><tr style="height: 31px;"><td style="width: 50%; height: 31px;">Criado por</td><td style="width: 50%; height: 31px;">log\_usu\_criacao</td></tr><tr style="height: 31px;"><td style="width: 50%; height: 31px;">Alterado por</td><td style="width: 50%; height: 31px;">log\_usu\_alteracao</td></tr></tbody></table>

# Relatório / Dashboard - customizar colunas da tabale de dados com Html, C#,  CSS e Javascript

O agilityflow permite customização através da Linguagem Html, CSS, Javascript e C# (csharp).

O html do agilityflow é baseado no Razor do framework .Net, isso é, você pode além de customizar com HTML, utilizar código C# (razor) para dar mais flexibilidade e poder ao seu componente Html.

### Customizar a Tabela de dados (Datatable)

Você pode utilizar tabela de dados nos Reports e/ou nos Dasboards.

Estando na editção e customização de uma Tabela de dados, na barra de botões, clique na opção Customizar via Código, como na imagem abaixo:

![](https://wiki.agilityflow.io/uploads/images/gallery/2024-11-Nov/scaled-840-0/image-1731953101768.png)

Nessa área você poderá customizar o Javascript, CSS e o CSHTML (Razor C# + Html):

![](https://wiki.agilityflow.io/uploads/images/gallery/2024-11-Nov/scaled-840-0/image-1731953177108.png)

Nessa área podemos customizar toda a tabela de dados, como no exemplo abaixo.

![](https://wiki.agilityflow.io/uploads/images/gallery/2024-11-Nov/scaled-840-0/image-1731953464895.png)

Voltando a área de desenvolvimento, no menu de customização, teremos sempre 2 arquivos padrões: **CSS** e **Javascript**.

O **CSS** é sempre colocado no topo da página, dentro da tag &lt;HEAD&gt; do Html

O **Javascript** é sempre colocado no final da página, antes do fechamento do &lt;/Body&gt;

### Customizar com CSS

Todo código CSS da tabela de dados deve ser colocado na aba Style (CSS)

![](https://wiki.agilityflow.io/uploads/images/gallery/2024-11-Nov/scaled-840-0/image-1731953560379.png)

Nessa área, você pode criar customizações via linguagem CSS para toda a listagem e o seu uso é livre.

<p class="callout warning">Levar em consideração o tratamento em CSS para a responsividade da plataforma em outros device, Mobile, Computador Desktop, Tablet, etc.</p>

### Customizar com Javascript

Todo código Javascript da datatable, deve ficar no arquivo Javascript.

![](https://wiki.agilityflow.io/uploads/images/gallery/2024-11-Nov/scaled-840-0/image-1731955949766.png)

### Customizar com Html e/ou C#

rie através do botão NOVO CSHTML um arquivo para cada coluna que incluímos na tabela de dados. Para isso, utilize o id da coluna como o nome do arquivo. Suas configurações devem estar como na imagem abaixo:

![](https://wiki.agilityflow.io/uploads/images/gallery/2024-11-Nov/scaled-840-0/image-1731956093951.png)

Antes de mostrar cada exemplo, abaixo descrevemos alguns métodos e propriedades disponíveis no contexto de cada customização de coluna, para que você consiga entender o que podemos fazer.

#### Propriedade e Métodos C# disponíveis no contexto do CSHTML da Coluna

O agilityflow disponibiliza uma biblioteca **C#** de contexto para a customização das colunas. Essa biblioteca está disponível no objeto "<span style="color: #000000;">**ColumnContext**</span>" e abaixo estão descritos as propriedades e métodos pré-programados para facilitar na utilização:

<p class="callout info">Para utilizar qualquer método ou propriedade listadas abaixo, sempre utilizar antes a nomenclatura "ColumnContext.". Exemplo: **ColumnContext.Metodo()** ou **ColumnContext.Propriedade**</p>

##### C# - Propriedades

<table border="1" id="bkmrk-bool-israscunho-%7Bget" style="border-collapse: collapse; width: 100.711%; height: 62px;"><tbody><tr style="height: 31px;"><td style="width: 30.4938%; height: 31px;">int RowIndex {get;}</td><td style="width: 36.1728%; height: 31px;">Retorna a posição da Linha na tabela, começando do 0</td></tr></tbody></table>

##### C# - Recuperar (Get) valor das colunas

<table border="1" id="bkmrk-string-getvalue%28stri" style="border-collapse: collapse; width: 100.881%; height: 235px;"><tbody><tr style="height: 31px;"><td style="width: 35.3085%; height: 31px;">string GetText(string idColuna)</td><td style="width: 46.2964%; height: 31px;">Retorna uma string com o **texto** da coluna passada no parâmetro

</td></tr><tr style="height: 37px;"><td style="width: 35.3085%; height: 37px;">string GetValue(string idColuna)</td><td style="width: 46.2964%; height: 37px;">Retorna uma string com o **texto** da coluna passada no parâmetro

</td></tr><tr style="height: 31px;"><td style="width: 35.3085%; height: 31px;">int? GetInt(string idColuna)</td><td style="width: 46.2964%; height: 31px;">Retorna o valor da coluna no tipo INT (inteiro), caso esse campo no formulário seja um número, se o valor for 10.000,99

Será retornado: 10000

</td></tr><tr style="height: 31px;"><td style="width: 35.3085%; height: 31px;">decimal? GetDecimal(string idColuna)</td><td style="width: 46.2964%; height: 31px;">Retorna o valor da coluna no tipo Decimal, caso esse campo no formulário seja um número, se o valor for 10.000,99 Será retornado: 10000.99

</td></tr><tr style="height: 31px;"><td style="width: 35.3085%; height: 31px;">DateTime? GetDateTime(string idColuna)</td><td style="width: 46.2964%; height: 31px;">Retorna o valor da coluna no tipo DateTime para valores que estão no formato de data dd/MM/yyyy ou dd/MM/yyyy hh:mm</td></tr></tbody></table>

##### C# - Customização visual da coluna ou linha

<table border="1" id="bkmrk-void-setcelcolor%28str-0" style="border-collapse: collapse; width: 100.881%; height: 62px;"><tbody><tr style="height: 31px;"><td style="width: 26.9134%; height: 31px;">void SetCelColor(string color)</td><td style="width: 54.6915%; height: 31px;">**Pinta o fundo da célula da coluna**

Algumas cores já estão predefinidas seguindo padrão de tonalidade do agilityflow. Essas cores são: "red", "green", "yellow", "blue". Caso você julgue necessário você também pode utilizar cores no formato hexadecimal

if(dt\_data\_e\_hora &lt; DateTime.Now){   
@ColumnContext.SetRowColor("red")

  
//se em até 5 dias for ficar atrasado, coloca em amarelo a célula  
}else if(dt\_data\_e\_hora &lt; DateTime.Now.AddDays(5)){   
@ColumnContext.SetCelColor("yellow")  
}

**importante usar o @ na frente**

</td></tr><tr style="height: 31px;"><td style="width: 26.9134%; height: 31px;">void SetRowColor(string color)</td><td style="width: 54.6915%; height: 31px;">**Pinta o fundo da linha da linha**

Algumas cores já estão predefinidas seguindo padrão de tonalidade do agilityflow. Essas cores são: "red", "green", "yellow", "blue". Caso você julgue necessário você também pode utilizar cores no formato hexadecimal

if(dt\_data\_e\_hora &lt; DateTime.Now){   
@ColumnContext.SetRowColor("red")

  
//se em até 5 dias for ficar atrasado, coloca em amarelo a célula  
}else if(dt\_data\_e\_hora &lt; DateTime.Now.AddDays(5)){   
@ColumnContext.SetCelColor("yellow")  
}

**importante usar o @ na frente**

</td></tr></tbody></table>

##### C# - Variáveis de contexto da tabela de dados

Você pode precisar guardar informações no contexto geral da listagem.

Imagine que você queira fazer uma soma geral ou guardar uma informação que você já tratou na primeira linha e que agora você precisa utiliza-la na última coluna, da última linha. Simples, basta utilizar o método SetGlobalVariable para colocar uma informação no contexto e depois busca-la com o método GetGlobalVariable para

<table border="1" id="bkmrk-void-setglobalvariab" style="border-collapse: collapse; width: 100.881%; height: 296px;"><tbody><tr style="height: 49px;"><td style="width: 37.9011%; height: 49px;">void SetContextVariable(string key, string value)</td><td style="width: 43.7038%; height: 49px;">Colocar uma variável e seu valor no contexto da listagem</td></tr><tr style="height: 31px;"><td style="width: 37.9011%; height: 31px;">string GetContextVariable(string key)</td><td style="width: 43.7038%; height: 31px;">Recupera o valor de uma variável que esteja no contexto da listagem</td></tr></tbody></table>

##### C# - Formatação Numérica

<table border="1" id="bkmrk-string-formatdecimal" style="border-collapse: collapse; width: 100.881%; height: 296px;"><tbody><tr style="height: 49px;"><td style="width: 52.7159%; height: 49px;">string FormatDecimalToString(object numDecimal, string mascaraTipo = "dec2")</td><td style="width: 45.8026%; height: 49px;">formata object 999999999.55 para o formato da mascara de acordo com o idioma.

\- se for ingles, será 999,999,999.55  
\- se for portugues, será 999.999.999,55

</td></tr><tr style="height: 31px;"><td style="width: 52.7159%; height: 31px;">string FormatNumberToString\_EnglishFormat(object num, \[optional\]int? qtdCasasDecimais)</td><td style="width: 45.8026%; height: 31px;">converte decimal para string, porém sempre a string vem no formato Inglês.

coloca a a mesma qtd de casas decimais, caso o parâmetro qtdCasasDecimais estivar em branco

</td></tr></tbody></table>

##### C# - Usuário logado

<table border="1" id="bkmrk-string-getusuariolog" style="border-collapse: collapse; width: 100.881%; height: 155px;"><tbody><tr style="height: 31px;"><td style="width: 37.9011%; height: 31px;">string GetUsuarioLogadoNome()</td><td style="width: 43.7038%; height: 31px;">retorna o nome do usuário logado</td></tr><tr style="height: 31px;"><td style="width: 37.9011%; height: 31px;">string GetUsuarioLogadoPrimeiroNome()</td><td style="width: 43.7038%; height: 31px;">retorna o primeiro nome do usuário logado</td></tr><tr style="height: 31px;"><td style="width: 37.9011%; height: 31px;">string GetUsuarioLogadoPrimeiroESegundoNome()</td><td style="width: 43.7038%; height: 31px;">retorna o primeiro e o segundo nome do usuário logado</td></tr><tr style="height: 31px;"><td style="width: 37.9011%; height: 31px;">string GetUsuarioLogadoEmail()</td><td style="width: 43.7038%; height: 31px;">retorna o e-mail do usuário logado</td></tr><tr style="height: 31px;"><td style="width: 37.9011%; height: 31px;">Guid GetUsuarioLogadoId()</td><td style="width: 43.7038%; height: 31px;">retorna o id do usuário logado</td></tr></tbody></table>

#####  

##### C# - Idioma, Linguagem / Internationalization (i18n)

<table border="1" id="bkmrk-currentlanguage.isen" style="border-collapse: collapse; width: 100.881%; height: 296px;"><tbody><tr><td style="width: 57.901%;"><div><div>CurrentLanguage.IsEnglish()</div></div></td><td style="width: 23.7039%;">retorna true se for inglês</td></tr><tr><td style="width: 57.901%;"><div><div>CurrentLanguage.IsPortuguese()</div></div></td><td style="width: 23.7039%;">retorna true se for português</td></tr><tr><td style="width: 57.901%;"><div><div>CurrentLanguage.IsSpanish()</div></div></td><td style="width: 23.7039%;">returna true se for espanhol</td></tr><tr><td style="width: 57.901%;"><div><div>CurrentLanguage.GetIIF_TextFromCurrentLanguage(text_ptBR, text_ENG ,text_ESP)</div></div></td><td style="width: 23.7039%;">dependendo do idioma, retorna o texto passado em 1 dos 3 parâmetros</td></tr></tbody></table>

#####  

##### C# - Geral

<table border="1" id="bkmrk-string-geturlbase%28%29-" style="border-collapse: collapse; width: 100.881%; height: 111px;"><tbody><tr style="height: 49px;"><td style="width: 44.6912%; height: 49px;">string GetUrlBase()</td><td style="width: 36.9137%; height: 49px;">Retorna a URL base onde o agilityflow está instalado</td></tr><tr style="height: 31px;"><td style="width: 44.6912%; height: 31px;"><span style="text-decoration: line-through;">string GetEnvironmentVariable(string nomeDaVariavel)</span></td><td style="width: 36.9137%; height: 31px;"><span style="text-decoration: line-through;">Retorna o valor de uma variável de ambiente</span>

**Não é perimitir utilizar esse metodo nesse contexto**

</td></tr><tr style="height: 31px;"><td style="width: 44.6912%; height: 31px;"><span style="text-decoration: line-through;">string GetEnvironmentVariable\_Text(string nomeDaVariavel)</span></td><td style="width: 36.9137%; height: 31px;"><span style="text-decoration: line-through;">Retorna o texto de uma variável de ambiente</span>

<span style="text-decoration: line-through;">**Não é perimitir utilizar esse metodo nesse contexto**</span>

</td></tr></tbody></table>

####  

#### Elementos Visuais para deixar a tabela mais bonita

<p class="callout info"><span class="info-options">Você pode utilizar qualquer elemento HTML para a customização da coluna.</span></p>

<span class="info-options">Abaixo listamos alguns elementos pré-definidos no agilityflow para facilitar o seu desenvolvimento.</span>

<span class="info-options">\* Caso seja necessário criar um elemento visual de forma dinâmica ou dentro de um IF, usar a função Html.Raw(), como no exemplo abaixo:  
</span>

<table id="bkmrk-small-text-%3Ctext-sma" style="width: 931px; height: 1858px;"><tbody><tr style="height: 50px;"><td style="width: 127px; height: 50px;">Button</td><td style="width: 142px; height: 50px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616516230091.png)

</td><td class="col-code" style="width: 662px; height: 84px;">```pt
<button type="button" class="btn-list">Botão</button>
```

</td></tr><tr style="height: 76px;"><td class="col-desc" style="width: 127px; height: 76px;">Small Text</td><td class="col-varvalue" style="width: 142px; height: 76px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514394521.png)

</td><td class="col-code" style="width: 662px; height: 76px;">```pt
<text-small>small</text-small>
```

</td></tr><tr style="height: 84px;"><td class="col-desc" style="width: 127px; height: 84px;">Tag Red</td><td class="col-varvalue" style="width: 142px; height: 84px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616669633685.png)

</td><td class="col-code" style="width: 662px; height: 84px;">```pt
<tag-red>red</tag-red> 
```

</td></tr><tr><td class="col-desc" style="width: 127px;">Tag Outline Red</td><td class="col-varvalue" style="width: 142px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616669622189.png)

</td><td class="col-code" style="width: 662px;">```pt
<tag-outline-red>red</tag-outline-red> 
```

</td></tr><tr style="height: 84px;"><td class="col-desc" style="width: 127px; height: 84px;">Tag Yellow</td><td class="col-varvalue" style="width: 142px; height: 84px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616669647727.png)

</td><td class="col-code" style="width: 662px; height: 84px;">```pt
<tag-yellow>yellow</tag-yellow> 
```

</td></tr><tr><td class="col-desc" style="width: 127px;">Tag Outline Yellow</td><td class="col-varvalue" style="width: 142px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616669656783.png)

</td><td class="col-code" style="width: 662px;">```pt
<tag-outline-yellow>yellow</tag-outline-yellow> 
```

</td></tr><tr style="height: 78px;"><td class="col-desc" style="width: 127px; height: 78px;">Tag Blue</td><td class="col-varvalue" style="width: 142px; height: 78px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616669669098.png)

</td><td class="col-code" style="width: 662px; height: 78px;">```pt
<tag-blue>blue</tag-blue> 
```

</td></tr><tr><td class="col-desc" style="width: 127px;">Tag Outline Blue</td><td class="col-varvalue" style="width: 142px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616669676419.png)

</td><td class="col-code" style="width: 662px;">```pt
<tag-outline-blue>blue</tag-outline-blue> 
```

</td></tr><tr style="height: 79px;"><td class="col-desc" style="width: 127px; height: 79px;">Tag Green</td><td class="col-varvalue" style="width: 142px; height: 79px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616669684182.png)

</td><td class="col-code" style="width: 662px; height: 79px;">```pt
<tag-green>green</tag-green> 
```

</td></tr><tr><td class="col-desc" style="width: 127px;">Tag Outline Green</td><td class="col-varvalue" style="width: 142px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616669691223.png)

</td><td class="col-code" style="width: 662px;">```pt
<tag-outline-green>green</tag-outline-green> 
```

</td></tr><tr style="height: 76px;"><td class="col-desc" style="width: 127px; height: 76px;">Tag gray</td><td class="col-varvalue" style="width: 142px; height: 76px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616669700632.png)

</td><td class="col-code" style="width: 662px; height: 76px;">```pt
<tag-gray>gray</tag-gray> 
```

</td></tr><tr><td class="col-desc" style="width: 127px;">Tag Outline gray</td><td class="col-varvalue" style="width: 142px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616669709348.png)

</td><td class="col-code" style="width: 662px;">```pt
<tag-outline-gray>gray</tag-outline-gray> 
```

</td></tr><tr style="height: 91px;"><td class="col-desc" style="width: 127px; height: 91px;">Avatar</td><td class="col-varvalue" style="width: 142px; height: 91px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514447071.png)

</td><td class="col-code" style="width: 662px; height: 91px;">```pt
<avatars><avatar>John Charles</avatar></avatars> 
```

</td></tr><tr style="height: 93px;"><td class="col-desc" style="width: 127px; height: 93px;">Avatar</td><td class="col-varvalue" style="width: 142px; height: 93px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514457075.png)

</td><td class="col-code" style="width: 662px; height: 93px;">```pt
<avatars><avatar>Luigi Charles</avatar><avatar>Brain Colleman</avatar></avatars> 
```

</td></tr><tr style="height: 111px;"><td class="col-desc" style="width: 127px; height: 111px;">Rating</td><td class="col-varvalue" style="width: 142px; height: 111px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514483212.png)

</td><td class="col-code" style="width: 662px; height: 111px;">```pt
<star-rating max="4" show-value="false">3</star-rating> 
```

</td></tr><tr style="height: 86px;"><td class="col-desc" style="width: 127px; height: 86px;">Rating</td><td class="col-varvalue" style="width: 142px; height: 86px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514526108.png)

</td><td class="col-code" style="width: 662px; height: 86px;">```pt
<star-rating max="6" show-value="true">3.5</star-rating> 
```

</td></tr><tr style="height: 87px;"><td class="col-desc" style="width: 127px; height: 87px;">Rating Red</td><td class="col-varvalue" style="width: 142px; height: 87px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514532757.png)

</td><td class="col-code" style="width: 662px; height: 87px;">```pt
<star-rating color='red' max="7" show-value="false">6</star-rating> 
```

</td></tr><tr style="height: 83px;"><td class="col-desc" style="width: 127px; height: 83px;">Rating Blue</td><td class="col-varvalue" style="width: 142px; height: 83px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514538876.png)

</td><td class="col-code" style="width: 662px; height: 83px;">```pt
<star-rating color='blue' max="7" show-value="false">6</star-rating> 
```

</td></tr><tr style="height: 81px;"><td class="col-desc" style="width: 127px; height: 81px;">Rating Green</td><td class="col-varvalue" style="width: 142px; height: 81px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514545330.png)

</td><td class="col-code" style="width: 662px; height: 81px;">```pt
<star-rating color='green' max="7" show-value="false">6</star-rating> 
```

</td></tr><tr style="height: 79px;"><td class="col-desc" style="width: 127px; height: 79px;">Rating Gray</td><td class="col-varvalue" style="width: 142px; height: 79px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514551364.png)

</td><td class="col-code" style="width: 662px; height: 79px;">```pt
<star-rating color='gray' max="7" show-value="false">6</star-rating> 
```

</td></tr><tr style="height: 76px;"><td class="col-desc" style="width: 127px; height: 76px;">Rating Ball</td><td class="col-varvalue" style="width: 142px; height: 76px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514586755.png)

</td><td class="col-code" style="width: 662px; height: 76px;">```pt
<ball-rating max="4" show-value="false">3</ball-rating> 
```

</td></tr><tr style="height: 76px;"><td class="col-desc" style="width: 127px; height: 76px;">Rating Ball</td><td class="col-varvalue" style="width: 142px; height: 76px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514594547.png)

</td><td class="col-code" style="width: 662px; height: 76px;">```pt
<ball-rating max="6" show-value="true">3.5</ball-rating> 
```

</td></tr><tr style="height: 76px;"><td class="col-desc" style="width: 127px; height: 76px;">Rating Ball Red</td><td class="col-varvalue" style="width: 142px; height: 76px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514600103.png)

</td><td class="col-code" style="width: 662px; height: 76px;">```pt
<ball-rating color='red' max="7" show-value="false">6</ball-rating> 
```

</td></tr><tr style="height: 76px;"><td class="col-desc" style="width: 127px; height: 76px;">Rating Ball Blue</td><td class="col-varvalue" style="width: 142px; height: 76px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514605734.png)

</td><td class="col-code" style="width: 662px; height: 76px;">```pt
<ball-rating color='blue' max="7" show-value="false">6</ball-rating> 
```

</td></tr><tr style="height: 76px;"><td class="col-desc" style="width: 127px; height: 76px;">Rating Ball Green</td><td class="col-varvalue" style="width: 142px; height: 76px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514613027.png)

</td><td class="col-code" style="width: 662px; height: 76px;">```pt
<ball-rating color='green' max="7" show-value="false">6</ball-rating> 
```

</td></tr><tr style="height: 76px;"><td class="col-desc" style="width: 127px; height: 76px;">Rating Ball Gray</td><td class="col-varvalue" style="width: 142px; height: 76px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514619953.png)

</td><td class="col-code" style="width: 662px; height: 76px;">```pt
<ball-rating color='gray' max="7" show-value="false">6</ball-rating> 
```

</td></tr><tr style="height: 76px;"><td class="col-desc" style="width: 127px; height: 76px;">Break Line</td><td class="col-varvalue" style="width: 142px; height: 76px;"> </td><td class="col-code" style="width: 662px; height: 76px;">```pt
<br/>
```

</td></tr><tr style="height: 88px;"><td class="col-desc" style="width: 127px; height: 88px;">Line</td><td class="col-varvalue" style="width: 142px; height: 88px;">![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514634174.png)

</td><td class="col-code" style="width: 662px; height: 88px;">```pt
<hr/>
```

</td></tr></tbody></table>

### Exemplos de customização

Agora que já sabemos os métodos que podemos utilizar para facilitar a customização, abaixo listamos alguns exemplos de como utiliza-los na prática.

#### Comparação por Data e Hora. Pintar a linha e coluna se a data e hora (DateTime) estiver atrasada

No arquivo de customização **"data\_e\_hora",** vamos criar uma regrinha:

\- Vamos buscar a data e hora já no tipo DateTime para podermos usar na condicional   
\- Se a data estiver atrasada, colocaremos a linha em vermelho  
\- Se faltar até 5 dias a para chegar na data, colocaremos a célula da tabela em amarelo

```C#
@{    
    //buscar a data e hora já no tipo Datetime para podermos usar na condicional
    var dt_data_e_hora = ColumnContext.GetDateTime("data_e_hora");

    //se não for possível converter a data, ela sempre retornará null
    if(dt_data_e_hora != null){

        //se está atrasada, coloca em vermelho a linha
        if(dt_data_e_hora  < DateTime.Now){ 
            @ColumnContext.SetRowColor("red")


        //se em até 5 dias for ficar atrasado, coloca em amarelo a célula
        }else if(dt_data_e_hora  < DateTime.Now.AddDays(5)){ 
            @ColumnContext.SetCelColor("yellow")
        }
    }

    //e por fim mostramos a data e a hora na célula
}
    @dt_data_e_hora        
```

resultado:

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616514761299.png)

#### Comparação Numérica e tipos Numéricos

No arquivo de customização **"decimal\_3casas",** vamos criar uma regrinha:

\- Vamos mostrar na coluna o valor do campo "Decimal com 3 Casas", buscando ele no formato **<span style="text-decoration: underline;">string</span>** e usando o método `GetText`  
\- Vamos mostrar na coluna o valor do campo "Decimal com 3 Casas", buscando ele como tipo **<span style="text-decoration: underline;">inteiro</span>** (ignorando as casas decimais) e usando o método `GetInt`  
\- Vamos mostrar na coluna o valor do campo "Decimal com 3 Casas", buscando ele no tipo **<span style="text-decoration: underline;">decimal</span>** e usando o método `GetDecimal`  
\- Vamos fazer uma condicional para mostrar uma tag em verde escrito "é Maior que 10 mil" caso o valor do campo seja maior que 10.000,00  
\- Vamos fazer uma condicional para mostrar uma tag em vermelho escrito "é Menor que 10 mil" caso o valor do campo seja menor que 10.000,00

```C#
@ColumnContext.GetText("decimal_3casas")
<br>
@ColumnContext.GetInt("decimal_3casas")
<br>
@ColumnContext.GetDecimal("decimal_3casas")
<br>
@{
    if(ColumnContext.GetDecimal("decimal_3casas") > 10000){
        <text>
            <tag-green>é MAIOR que 10 mil</tag-green>
        </text>
    }else{
        <text>
            <tag-red>é MENOR que 10 mil</tag-red>
        </text>
    }
}
```

resultado:

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616515952336.png)

#### Adicionar um botão na tabela de dados

No arquivo de customização **"email",** vamos criar uma regrinha:

\- Vamos mostrar o valor do campo E-mail   
\- Vamos adicionar um botão que quando o usuário clicar apresentará a msg "Mensagem de Exemplo"  
\- Para esse exemplo, vamos precisar fazer uso do arquivo padrão "Javascript" do List Page

No arquivo de customização de **"email",** cole o código abaixo

```C#
@ColumnContext.GetText("email") 
<br>
<button type="button" class="btn-list btn-exemplo-botao">Botão</button>
```

No arquivo Javascript da List Page, cole o código abaixo

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616527835085.png)

```JavaScript
$(document).on('click', '.btn-exemplo-botao', function (e) {

    //aqui você pode colocar seu código
    //apresenta uma mensagem
    alert('Mensagem de Exemplo')
    

})

```

Quando o usuário, clicar no botão "Botão" ele receberá essa mensagem:

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-03-Mar/scaled-840-0/image-1616525325946.png)

#### Como utilizar uma Variável de Contexto ou Variável Global para interagir e armazenar informações entre todas as linhas e colunas da mesma listagem

Para esse exemplo demonstraremos o uso dos métodos `ColumnContext.GetGlobalVariable("variavel");` e ColumnContext.SetGlobalVariable("variavel", "valor");

No arquivo de customização **"nome",** vamos criar uma regrinha:

\- Vamos mostrar o valor do campo Nome, concatenado com a palavra "Nome:"  
\- Vamos somar a idade da linha anterior com a linha atual, até a última linha ser a soma total das idades  
\- Vamos mostrar uma frase mostrando a posição da linha (RowIndex) concatenada com a idade total somada até aquele momento

```C#
@{
    //recupera o total já gravado em uma variavel global
    var str_idade_total = ColumnContext.GetGlobalVariable("idade");

    //pega a idade referente a essa linha na tabela
  	//já puxa a idade no formato INT (número inteiro) para ser possível 
  	//fazer a soma total sem precisar de conversão de número
    var idade = @ColumnContext.GetInt("idade");

    //se a idade não tiver sido preenchida no formulário, então considera ela como zero
    if(idade == null)
    {
        idade = 0;
    }

    //se a idade total já estiver sido preenchida, então, soma com a idade dessa linha
    //caso contrário ignora pois será o primeiro registro da linha e não precisará ser feito nenhuma soma
    if(!string.IsNullOrEmpty(str_idade_total)){    
        idade = Convert.ToInt32(str_idade_total) + idade;        
    }

    //coloca novamente a soma das idades totais na Variável Global, para ser recuparada na próxima linha
    str_idade_total = idade.ToString();
    ColumnContext.SetGlobalVariable("idade", str_idade_total);
    
}
Nome: @ColumnContext.GetText("nome")
<br>
Até o RowIndex @ColumnContext.RowIndex a Idade era de  @str_idade_total anos
```

#### Customizar e acessar as colunas de Log: Data de criação, Data de Alteração, Criado por e Alterado por.

Para recuperar os campos de Log na listagem através do `GetText(...)` ou `GetDateTime(...)` utilizar os ids padrões de cada campo:

<table border="1" id="bkmrk-nome-id-data-de-cria" style="border-collapse: collapse; width: 100%; height: 124px;"><tbody><tr><td style="width: 50%;">**Nome**</td><td style="width: 50%;">**ID**</td></tr><tr style="height: 31px;"><td style="width: 50%; height: 31px;">Data de criação</td><td style="width: 50%; height: 31px;">log\_data\_criacao</td></tr><tr style="height: 31px;"><td style="width: 50%; height: 31px;">Data de Alteração</td><td style="width: 50%; height: 31px;">log\_data\_alteracao</td></tr><tr style="height: 31px;"><td style="width: 50%; height: 31px;">Criado por</td><td style="width: 50%; height: 31px;">log\_usu\_criacao</td></tr><tr style="height: 31px;"><td style="width: 50%; height: 31px;">Alterado por</td><td style="width: 50%; height: 31px;">log\_usu\_alteracao</td></tr></tbody></table>

# Configuração dos Campos

Detalhes sobre como customizar os campos de um formulário, de acordo com a sua necessidade.

# Textbox

O campo textbox é o tipo de campo mais usado no agilityflow. Isso é devido à sua versatilidade graças às inúmeras [máscaras](#bkmrk-m%E3%A1scara) disponíveis. Apesar do nome, é com o campo textbox que iremos armazenar [números](#bkmrk-n%E3%BAmero) também.

Ao criar um campo textbox no formulário, é solicitado escolher um grupo de informações e informar um nome de apresentação. Caso seja necessário, as configurações abaixo, estão disponíveis para o campo:

### Grupo de informações

Dentro das configurações, é possível alterar o [grupo de informação](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/divis%C3%A3o-e-agrupamento-dos-campos "Divisão e agrupamento dos campos") ao qual o campo foi atribuído no momento da criação.

### Nome de Apresentação

Mostra o nome de apresentação informado no momento da criação. Esse é o nome que será mostrado na tela para o usuário.

### Tipo

Para o campo textbox, é possível definir um subtipo. São eles:

#### Campo de Texto Simples

É o tipo padrão. Permite que o usuário insira qualquer tipo de informação de texto, em uma linha única.

#### Campo de Texto Multi Linha

Similar ao Campo de Texto Simples, porém, com mais de uma linha. Ao selecionar essa opção, é possível escolher quantas linhas ficarão visíveis ao usuário.

#### Campo com criptografia MD5 (Ex: Senha)

[![campo_senha.gif](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/campo_senha.gif)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/campo_senha.gif)

Funciona para armazenar textos, que ao digitados, serem ocultados tendo seus caracteres substituídos. Ao selecionar esse subtipo, não é possível definir uma [máscara](#bkmrk-m%E3%A1scara).

#### Campo Auto Numérico (Número Sequencial preenchido automaticamente)

Nesse campo, o próprio agilityflow preenche o campo com um número sequencial. Esse valor, começa em 1 e vai se somando conforme se criam novos registros do formulário.

### Coluna Banco de dados (SQL)

Esse é o nome interno, usado pelo sistema, a ser criado no banco de dados do agilityflow. É uma informação técnica e esse campo é preenchido automaticamente pelo sistema.

<p class="callout warning">Na maioria dos casos, você não precisa alterar o nome sugerido pelo sistema.</p>

Diferentemente do campo "Nome de Apresentação", esse campo não fica visível para o usuário.

> Para que serve o campo Coluna Banco de dados (SQL)?

Esse campo vai ser utilizado ao criar reports e dashboards. É através dele, que poderemos extrair informações e expor usando esses recursos do sistema.

### Informações de ajuda

Nesse campo é possível incluir um texto que ajudará o usuário a preenche-lo. Abaixo, um exemplo de dois campos: um campo sem informações de ajuda e outro com esse campo configurado:

[![informacoes_ajuda.gif](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/informacoes_ajuda.gif)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/informacoes_ajuda.gif)

### Preenchimento Padrão

O preenchimento padrão, permite ao sistema, sugerir o preenchimento do campo. Isso é útil, quando o usuário, na maioria das vezes, vai preencher esse campo da mesma forma. Isso economiza o tempo do usuário no preenchimento das informações.

Mesmo que haja definido um preenchimento padrão, o campo fica disponível para que o usuário altere esse valor.

#### Preencher Quando

Nessa opção, o usuário define em que momento o sistema faz o preenchimento padrão do campo. São duas opções:

##### No carregamento inicial (On PageLoad)

Ao abrir o formulário, o campo já é preenchido automaticamente.

##### Na alteração do valor de um determinado campo (On Change)

O campo não é preenchido com o valor padrão, até que um campo seja alterado. É possível definir qual campo ao ser alterado, será o gatilho para o preenchimento padrão.

#### Valor Padrão

É o valor que será preenchido por padrão nesse campo.

### Máscara

É a forma que o sistema utiliza para mostrar ao usuário, o conteúdo do campo de texto. Isso facilita a visualização da informação por parte do usuário. Por exemplo, é muito fácil ver o telefone "(11) 98765-4321" do que "11987654321".

#### Tipo de máscara

Existe uma série de máscaras disponíveis no agilityflow.

##### Número

> Como criar um campo numérico?

Um número não deixa de ser um texto. Portanto, para criar um campo numérico basta criar um campo textbox e aplicar uma máscara de número.

- Tipo de Número  
      
    
    - Inteiro: o campo não aceita "," ou "." no seu conteúdo. Ao digitar um desses símbolos, o sistema ignora a digitação. Por exemplo, digitando "1,5", o sistema ignora a vírgula e preenche "15". Caso o usuário cole o valor "1,5541", o sistema ignora a vírgula e o conteúdo à direita da vírgula, aceitando o valor "1".
    - Moeda (Real): coloca vírgula, deixando o campo com duas casas decimais;
    - Decimal (1 casa decimal): coloca vírgula, deixando o campo com duas casas decimais;
    - Decimal (2 casas decimais): coloca vírgula, deixando o campo com duas casas decimais;
    - Decimal (3 casas decimais): coloca vírgula, deixando o campo com duas casas decimais;
    - Decimal (4 casas decimais): coloca vírgula, deixando o campo com duas casas decimais;
    - Decimal (5 casas decimais): coloca vírgula, deixando o campo com duas casas decimais;

##### CPF

Insere "." e "-" de acordo com o CPF brasileiro. Esse campo, apenas separa os dígitos e não faz validação se o CPF é válido ou não. Pra isso, é necessário incluir uma [validação](#bkmrk-%E2%A0-8).

##### CNPJ

Insere "." e "-" de acordo com o CNPJ brasileiro. Esse campo, apenas separa os dígitos e não faz validação se o CNPJ é válido ou não. Pra isso, é necessário incluir uma [validação](#bkmrk-%E2%A0-8).

##### CEP

Insere "-", separando o número de acordo com o formato do CEP brasileiro.

<p class="callout info">Para buscar o CEP automaticamente na base dos correios e preencher os campos de endereço, **[verifique o tutorial aqui nesse link](https://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/buscar-o-cep-nos-correios-e-preencher-os-campos-de-endere%C3%A7o-automaticamente)**</p>

##### Máscara Customizada

A máscara customizada, permite o usuário crie sua própria máscara. O agilityflow, utiliza a biblioteca Inputmask do javascript, criada por Robin Herbots. A documentação completa pode ser acessada no [github](https://github.com/RobinHerbots/Inputmask). Você só precisa ler essa documentação, caso opte por fazer uma customização avançada.

##### Tipo de Customização

- Básica: é um forma fácil de criar uma máscara não existente no agilityflow. A sintaxe utilizada é a seguinte:  
      
    9: caractere numérico (de "0" a "9");  
    a: caractere alfabético (de "a" a "z");  
    A: caractere alfabético (de "A" a "Z");  
    \*: caractere alfanumérico (todos acima);  
    \[\]: quando usado, identifica um caractere opcional;  
    \\\\: Par usar um dos caracteres acima como caractere e não como sintaxe;  
      
    Exemplos:  
    <table border="1" style="border-collapse: collapse;"><tbody><tr><td style="width: 33.3333%;">**Máscara**</td><td style="width: 33.3333%;">**Entrada**</td><td style="width: 33.3333%;">**Resultado**</td></tr><tr><td style="width: 33.3333%;">(99) 9999\[9\]-9999</td><td style="width: 33.3333%;">12123451234</td><td style="width: 33.3333%;">(12) 12345-1234</td></tr><tr><td style="width: 33.3333%;">(99) 9999\[9\]-9999</td><td style="width: 33.3333%;">121234-1234</td><td style="width: 33.3333%;">(12) 1234-1234</td></tr><tr><td style="width: 33.3333%;">\[9-\]AAA-999</td><td style="width: 33.3333%;">5ahg123</td><td style="width: 33.3333%;">5-AHG-123</td></tr><tr><td style="width: 33.3333%;">\[9-\]aaa-999</td><td style="width: 33.3333%;">ahg123</td><td style="width: 33.3333%;">ahg123</td></tr><tr><td style="width: 33.3333%;">+999-\\\\9</td><td style="width: 33.3333%;">123</td><td style="width: 33.3333%;">+123-9</td></tr></tbody></table>
- Avançada: você pode usar todos os recursos da biblioteca Inputmask. A documentação completa pode ser acessada no [github](https://github.com/RobinHerbots/Inputmask).

##### Máscara com 'Regular Expression'

Utiliza o padrão de expressões regulares, que é um padrão utilizado em programação para identificar cadeias de caracteres. Caso haja necessidade de formatar seu texto, procure saber mais sobre esse padrão, já que ele é extremamente completo, no que diz respeito a identificar textos.

##### Telefone: País + DDD + Cel/Tel Brasil

Sinal de "+", espaço, código do país com dois dígitos, espaço, código de área com dois dígitos entre parêntesis, espaço, telefone com 9 ou 8 dígitos, tendo um hífen separando após o 4 ou quinto dígito (seguindo o padrão brasileiros para telefones fixos e móveis). O sistema não aceita entrada que não tenha esse formato.

Ex: +55 (11) 98765-4321 ou +55 (81) 4321-1234

##### Telefone: DDD + Cel/Tel Brasil

Código de área com dois dígitos entre parêntesis, espaço, telefone com 9 ou 8 dígitos, tendo um hífen separando após o 4 ou quinto dígito (seguindo o padrão brasileiros para telefones fixos e móveis). O sistema não aceita entrada que não tenha esse formato.

Ex: (11) 98765-4321 ou (81) 4321-1234

##### Telefone: Cel/Tel Brasil

Telefone com 9 ou 8 dígitos, tendo um hífen separando após o 4 ou quinto dígito (seguindo o padrão brasileiros para telefones fixos e móveis). O sistema não aceita entrada que não tenha esse formato.

Ex: 98765-4321 ou 4321-1234

> Como configurar um campo de data?

##### Data e hora no formato dd/mm/yyyy hh:mm

Formato de data onde o ano tem 4 dígitos, seguido de hora sem os segundos. O sistema não aceita entrada que não tenha esse formato.

Ex: 18/01/1981 23:52

##### Data e hora (Com Segundos) no formato dd/mm/yyyy hh:mm:ss

Formato de data onde o ano tem 4 dígitos, seguido de hora com os segundos. O sistema não aceita entrada que não tenha esse formato.

Ex: 18/01/1981 23:52:13

##### Data sem hora no formato dd/mm/yyyy

Formato de data onde o ano tem 4 dígitos. O sistema não aceita entrada que não tenha esse formato.

Ex: 18/01/1981

> Como configurar um campo de hora?

##### Hora no formato hh:mm

Horário, sem os segundos. O sistema não aceita entrada que não tenha esse formato.

Ex: 19:37

##### Hora (Com Segundos) no formato hh:mm:ss

Horário, com os segundos. O sistema não aceita entrada que não tenha esse formato.

Ex: 19:37:22

#### Tamanho máximo de Preenchimento

Com esse campo é possível limitar o número máximo de caracteres a ser preenchido nesse campo.

### Validação

Nessa parte, é possível configurar validações dos dados inseridos pelo usuário, garantindo um padrão de preenchimento.

#### Obrigatório

> Como deixar um campo obrigatório?

Caso marcado como "sim", não permite o salvamento do fomulário sem o preenchimento desse campo. Ao marcar como "sim" essa opção, são abertos duas outras opções:

##### Obrigatório mesmo que por algum motivo o campo esteja marcado como invisível?

Use essa opção para fazer um campo definido como obrigatório, deixar sua obrigatoriedade caso ele esteja [invisível](#bkmrk-%E2%A0-8).

##### Obrigatório a partir da etapa

Para os formulários com fluxo de etapas, é possível atrelar a obrigatoriedade de um campo à etapa em que se encontra o fluxo.

#### Valor do campo deve ser único em relação a todos os registros

O sistema, valida a inserção do campo, com os registros do mesmo campo, já salvos em outros formulários. Por exemplo, talvez exista uma necessidade de validação de um e-mail para o cadastro de um cliente. Caso o e-mail digitado já conste em outro registro, não será permitido o salvamento do formulário.

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="425" src="https://player.vimeo.com/video/328685546" width="760"></iframe>

#### Valor do campo deve ser único em relação ao formulário PAI

Caso o formulário tenha uma relação com outro formulário (chamamos de formulário Pai), será validado que os dados inseridos são únicos, mas apenas para o registro filho.

#### Valor do campo deve ser único em relação APENAS ao CAMPO relacionado do formulário PAI

Caso haja, mais de um campo no formulário pai, relacionado ao mesmo formulário filho, a validação de valor único, ocorre apenas par cada campo do relacionamento.

Abaixo, um vídeo explica essas 3 últimas opções:

<div id="bkmrk--2"><iframe allowfullscreen="allowfullscreen" frameborder="0" height="425" src="https://player.vimeo.com/video/318250365" width="760"></iframe>

</div>### Regras de Visibilidade e desativação

Usando essas opções, é possível tornar um campo visível, invisível, ativo ou inativo, e definir quando uma dessas ações deve ocorrer. É possível adicionar várias regras para cada campo.

#### Descrição

É um texto que ajuda a identificar a regra que se está criando. Muito útil quando existem múltiplas regras.

#### Ação

##### Ativar

Deixa o campo disponível para inserção de dados. É o estado padrão do campo.

##### Inativar

Deixa o campo indisponível para inserção de dados.

##### Visível

O campo é mostrado na tela, caso esteja inserido para tal, nas configurações de tela.

##### Invisível

O campo é não é mostrado na tela, mesmo que esteja inserido para tal, nas configurações de tela.

#### A partir da etapa / Até a etapa

Em formulários com etapas, é possível estabelecer que uma regra será aplicada em alguma(s) etapa(s). Para isso, basta selecionar as etapas nos campos "a partir da etapa" e "até a etapa", para definir em que momento do fluxo essa regra vai ser aplicada.

#### Quando

Define em que momento a ação deve acontecer.

##### Sempre

É o padrão do formulário.

##### Condicional

- Tipo de condição  
    Para fazer um validação condicional, estão disponíveis as seguintes condições:  
    
    - Se o campo: compara um campo com um valor, ou com outro campo.  
        Abaixo, uma tabela com os operadores disponíveis para as comparações:  
          
        <table border="1" style="border-collapse: collapse; width: 100%;"><tbody><tr><td style="width: 50%;">**Comparação por valor**</td><td style="width: 50%;">**Comparação por outro campo**</td></tr><tr><td style="width: 50%;">For igual a</td><td style="width: 50%;">É igual ao campo</td></tr><tr><td style="width: 50%;">For maior ou igual a</td><td style="width: 50%;">É diferente do campo</td></tr><tr><td style="width: 50%;">For menor ou igual a </td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">For maior que</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">For menor que</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">For diferente de</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">Conter</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">Não conter</td><td style="width: 50%;"> </td></tr></tbody></table>
        
        <p class="callout success">É possível adicionar mais de um condição na mesma regra.</p>
    - Se é um novo formulário: regra será aplicada quando uma nova entrada no formulário estiver sendo criada.
    - Se é edição de formulário: regra será aplicada quando uma entrada no formulário estiver sendo alterada.

### Customização Javascript

Caso a customização desejada, não esteja disponível, ainda assim é possível programá-la utilizando javascript. Para mais detalhes, acesse o [capítulo](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/customiza%C3%A7%C3%A3o-javascript "Customização javascript") sobre essa opção.

# Label Dinâmica

Label Dinâmica é um campo de texto não editável, que é preenchido através de outro campo. Esse campo é muito útil, quando se tem um campo de lista de seleção (ou pesquisa com auto-completar) com uma fonte dinâmica e há a necessidade mostrar outros campos do formulário usado como fonte por esse campo.

No exemplo abaixo, o formulário tem uma lista de seleção de clientes. Os outros dois campos, são label dinâmicas com informações do formulário de cliente.

[![label_dinamica.gif](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/label_dinamica.gif)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/label_dinamica.gif)

Ao mudar o campo de lista de seleção, a label dinâmica é preenchida automaticamente.

### Grupo de informações

Dentro das configurações, é possível alterar o [grupo de informação](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/divis%C3%A3o-e-agrupamento-dos-campos "Divisão e agrupamento dos campos") ao qual o campo foi atribuído no momento da criação.

### Nome de Apresentação

Mostra o nome de apresentação informado no momento da criação. Esse é o nome que será mostrado na tela para o usuário.

### Informações de ajuda

Nesse campo é possível incluir um texto que ajudará o usuário a preenche-lo. Abaixo, um exemplo de dois campos: um campo sem informações de ajuda e outro com esse campo configurado:

[![informacoes_ajuda.gif](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/informacoes_ajuda.gif)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/informacoes_ajuda.gif)

### Preenchimento da Label Dinâmica

Aqui, estão as opções principais de configurações para a label dinâmica.

#### Preencher a label dinâmica ao alterar o campo

Nessa opção, apenas os campos Lista de Seleção com lista dinâmica, ou o campo Pesquisa com Auto Completar serão mostrados aqui. É esse campo que, ao ser alterado, preencherá a label dinâmica.

#### Campo de apresentação (Base de dados)

É o campo do formulário usado como fonte na lista de seleção (ou pesquisa com auto completar) será usado para o preenchimento.

### Regras de Visibilidade e desativação

Usando essas opções, é possível tornar um campo visível, invisível, ativo ou inativo, e definir quando uma dessas ações deve ocorrer. É possível adicionar várias regras para cada campo.

#### Descrição

É um texto que ajuda a identificar a regra que se está criando. Muito útil quando existem múltiplas regras.

#### Ação

##### Visível

O campo é mostrado na tela, caso esteja inserido para tal, nas configurações de tela.

##### Invisível

O campo é não é mostrado na tela, mesmo que esteja inserido para tal, nas configurações de tela.

#### A partir da etapa / Até a etapa

Em formulários com etapas, é possível estabelecer que uma regra será aplicada em alguma(s) etapa(s). Para isso, basta selecionar as etapas nos campos "a partir da etapa" e "até a etapa", para definir em que momento do fluxo essa regra vai ser aplicada.

#### Quando

Define em que momento a ação deve acontecer.

##### Sempre

É o padrão do formulário.

##### Condicional

- Tipo de condição  
    Para fazer um validação condicional, estão disponíveis as seguintes condições:  
    
    - Se o campo: compara um campo com um valor, ou com outro campo.  
        Abaixo, uma tabela com os operadores disponíveis para as comparações:  
          
        <table border="1" style="border-collapse: collapse; width: 100%;"><tbody><tr><td style="width: 50%;">**Comparação por valor**</td><td style="width: 50%;">**Comparação por outro campo**</td></tr><tr><td style="width: 50%;">For igual a</td><td style="width: 50%;">É igual ao campo</td></tr><tr><td style="width: 50%;">For maior ou igual a</td><td style="width: 50%;">É diferente do campo</td></tr><tr><td style="width: 50%;">For menor ou igual a </td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">For maior que</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">For menor que</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">For diferente de</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">Conter</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">Não conter</td><td style="width: 50%;"> </td></tr></tbody></table>
        
        <p class="callout success">É possível adicionar mais de um condição na mesma regra.</p>
    - Se é um novo formulário: regra será aplicada quando uma nova entrada no formulário estiver sendo criada.
    - Se é edição de formulário: regra será aplicada quando uma entrada no formulário estiver sendo alterada.

# Upload

Esse campo é utilizado para o envio de arquivos.

### Grupo de informações

Dentro das configurações, é possível alterar o [grupo de informação](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/divis%C3%A3o-e-agrupamento-dos-campos "Divisão e agrupamento dos campos") ao qual o campo foi atribuído no momento da criação.

### Nome de Apresentação

Mostra o nome de apresentação informado no momento da criação. Esse é o nome que será mostrado na tela para o usuário.

### Informações de ajuda

Nesse campo é possível incluir um texto que ajudará o usuário a preenche-lo. Abaixo, um exemplo de dois campos: um campo sem informações de ajuda e outro com esse campo configurado:

[![informacoes_ajuda.gif](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/informacoes_ajuda.gif)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/informacoes_ajuda.gif)

### Validação

Nessa parte, é possível configurar validações dos dados inseridos pelo usuário, garantindo um padrão de preenchimento.

#### Obrigatório

Caso marcado como "sim", não permite o salvamento do fomulário sem o preenchimento desse campo. Ao marcar como "sim" essa opção, são abertos duas outras opções:

##### Obrigatório mesmo que por algum motivo o campo esteja marcado como invisível?

Use essa opção para fazer um campo definido como obrigatório, deixar sua obrigatoriedade caso ele esteja [invisível](#bkmrk-%E2%A0-8).

##### Obrigatório a partir da etapa

Para os formulários com fluxo de etapas, é possível atrelar a obrigatoriedade de um campo à etapa em que se encontra o fluxo.

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="425" src="https://player.vimeo.com/video/328685546" width="760"></iframe>

#### Extensão Permitida

É possível adicionar uma lista branca, com as extensões permitidas.

#### Extensão não permitida

É possível adicionar uma lista negra, com as extensões não permitidas.

#### Validação Customizada

##### Tipo de Validação

- Upload de no máximo X itens: é possível definir um limite de arquivos;
- Upload no mínimo X itens: é possível definir um mínimo de arquivos;
- Upload exatamente X itens: é possível definir uma quantidade específica de arquivos;

##### Validar a partir da etapa

Em formulários com etapas, é possível estabelecer que uma validação será aplicada em alguma(s) etapa(s). Para isso, basta selecionar a etapa no campo "validar a partir da etapa".

### Regras de Visibilidade e desativação

Usando essas opções, é possível tornar um campo visível, invisível, ativo ou inativo, e definir quando uma dessas ações deve ocorrer. É possível adicionar várias regras para cada campo.

#### Descrição

É um texto que ajuda a identificar a regra que se está criando. Muito útil quando existem múltiplas regras.

#### Ação

##### Ativar

Deixa o campo disponível para inserção de dados. É o estado padrão do campo.

##### Inativar

Deixa o campo indisponível para inserção de dados.

##### Visível

O campo é mostrado na tela, caso esteja inserido para tal, nas configurações de tela.

##### Invisível

O campo é não é mostrado na tela, mesmo que esteja inserido para tal, nas configurações de tela.

#### A partir da etapa / Até a etapa

Em formulários com etapas, é possível estabelecer que uma regra será aplicada em alguma(s) etapa(s). Para isso, basta selecionar as etapas nos campos "a partir da etapa" e "até a etapa", para definir em que momento do fluxo essa regra vai ser aplicada.

#### Quando

Define em que momento a ação deve acontecer.

##### Sempre

É o padrão do formulário.

##### Condicional

<div id="bkmrk-tipo-de-condi%E3%A7%E3%A3opa">- <span class="input-group">Tipo de condição  
    </span>Para fazer um validação condicional, estão disponíveis as seguintes condições:  
    
    - Se o campo: compara um campo com um valor, ou com outro campo.  
        Abaixo, uma tabela com os operadores disponíveis para as comparações:  
          
        <table border="1"><tbody><tr><td>**Comparação por valor**</td><td>**Comparação por outro campo**</td></tr><tr><td>For igual a</td><td>É igual ao campo</td></tr><tr><td>For maior ou igual a</td><td>É diferente do campo</td></tr><tr><td>For menor ou igual a </td><td> </td></tr><tr><td>For maior que</td><td> </td></tr><tr><td>For menor que</td><td> </td></tr><tr><td>For diferente de</td><td> </td></tr><tr><td>Conter</td><td> </td></tr><tr><td>Não conter</td><td> </td></tr></tbody></table>
        
        <p class="callout success">É possível adicionar mais de um condição na mesma regra.</p>
    - Se é um novo formulário: regra será aplicada quando uma nova entrada no formulário estiver sendo criada.
    - Se é edição de formulário: regra será aplicada quando uma entrada no formulário estiver sendo alterada.

</div>

# Lista de seleção (Combo)

Esse campo, permite que o usuário escolha uma opção pré-determinada.

#### [![lista_para_selecao.gif](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/lista_para_selecao.gif)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/lista_para_selecao.gif)

### Grupo de informações

Dentro das configurações, é possível alterar o [grupo de informação](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/divis%C3%A3o-e-agrupamento-dos-campos "Divisão e agrupamento dos campos") ao qual o campo foi atribuído no momento da criação.

### Nome de Apresentação

Mostra o nome de apresentação informado no momento da criação. Esse é o nome que será mostrado na tela para o usuário.

### Coluna Banco de dados (SQL)

Esse é o nome interno, usado pelo sistema, a ser criado no banco de dados do agilityflow. É uma informação técnica e esse campo é preenchido automaticamente pelo sistema.

<p class="callout warning">Na maioria dos casos, você não precisa alterar o nome sugerido pelo sistema.</p>

Diferentemente do campo "Nome de Apresentação", esse campo não fica visível para o usuário.

> Para que serve o campo Coluna Banco de dados (SQL)?

Esse campo vai ser utilizado ao criar reports e dashboards. É através dele, que poderemos extrair informações e expor usando esses recursos do sistema.

### Informações de ajuda

Nesse campo é possível incluir um texto que ajudará o usuário a preenche-lo. Abaixo, um exemplo de dois campos: um campo sem informações de ajuda e outro com esse campo configurado:

[![informacoes_ajuda.gif](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/informacoes_ajuda.gif)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/informacoes_ajuda.gif)

---

### Origem dos Dados

Como existe uma lista de opções pré-determinadas, é necessário definir a origem dos dados.

#### Origem dos Itens

São duas as possibilidades:

**1. Lista Dinâmica** <span style="color: #3366ff;">(Utilização recomendada)</span> **:** Nessa opção, os dados têm como origem um outro formulário. Ao selecionar esse outro formulário, é necessário informar qual o campo desse formulário será exibido.

**2. Lista Estática:** O usuário insere as opções nas configurações do campo. Com isso, o usuário que acessa o formulário não pode criar novas opções. Ao criar as opções, além do nome, é possível definir a ordem em que aparecerão na lista de seleção. Outra opção, é o Id Customizado (Banco de Dados). Essa opção, normalmente não precisa ser preenchido. Entretanto, em alguns casos, esse id pode ser customizado. Isso pode ser útil, para a criação de dashboard e reports, para montar mais facilmente as *queries*.

<p class="callout danger">Sugerimos que o campo de Lista de seleção (combo) não seja usado quando há muitas itens pois todas as opções desse campo são lidas quando a página é carregada. Se houver muitos itens, o carregamento da página pode ser afetado. Para esses casos, usar o campo [**Pesquisa com auto completar.**](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/pesquisa-com-auto-completar "Pesquisa com auto completar")</p>

#### **Configuração de uma <span style="color: #000000;">Lista Dinâmica</span>**

Abaixo estão descritos os campos básicos de preenchimento para definição de uma lista dinâmica.

Abra a tela de edição do campo e clique na aba **Origem dos Dados**

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555598725240.png)

##### **Campos para preenchimento:**

##### Origem dos dados

Defina como "Lista Dinâmica"

##### Quando os dados serão carregados?

Quando a lista é dinâmica, é possível definir algumas opções relativas ao carregamento da lista. Esse carregamento pode ocorrer de duas maneiras.

**<span style="color: #808080;">No carregamento inicial (On PageLoad):</span>** Assim que o formulário é carregado, as opções da lista de seleção também são carregados imediatamente.

<span style="color: #808080;">**Na alteração do valor de um determinado campo (On Change):** </span>As opções só serão carregadas quando um determinado campo mudar. Isso é útil, para uma lista de seleção selecionar níveis de outra lista de seleção. Ex: seleciona-se primeiro o estado e só depois, é selecionada a cidade. Esse campo Lista de Cidade, apenas é carregado quando o outro campo Lista de Estados é alterado. Para isso, é necessário também adicionar uma[ condição na base de dados](#h_50356803591550685996742).

##### Qual será a Base de dados

É o formulário que servirá de fonte para a Lista Dinâmica.

##### Campo de apresentação (Base de dados)

Essa é a informação que será apresentada para o usuário na apresentação do combo. Esse campo é referente ao formulário que foi selecionado no campo [Qual será a Base de dados](#h_695508394161550686141083).

##### Ordenar os itens pelo campo

A ordenação padrão do itens do combo é alfabética. Entretanto há casos onde queremos alterar essa ordem. Para isso, podemos utilizar um segundo campo como critério de ordenação, que não o campo de exibição. Como exemplo, vamos usar um formulário que só tem o campo nome, e os seguintes dados?

<table border="1" id="bkmrk-prioridade-alta-baix" style="border-collapse: collapse; width: 0%; height: 120px;"><tbody><tr><td style="width: 100%;">**Prioridade**</td></tr><tr><td style="width: 100%;">Alta</td></tr><tr><td style="width: 100%;">Baixa</td></tr><tr><td style="width: 100%;">Média</td></tr></tbody></table>

Ao usarmos o campo prioridade como critério de ordenação, os itens serão apresentados na ordem alfabética (Alta, Baixa e Média), quando o mais intuitivo seria apresentar a ordem como (Baixa, Média, Alta).

Para isso, podemos criar um campo chamado 'Ordem' nesse formulário, e incluir números. Dessa forma:

<table border="1" id="bkmrk-prioridade-ordem-alt" style="border-collapse: collapse; width: 100%;"><tbody><tr><td style="width: 50%;">**Prioridade**</td><td style="width: 50%;">**Ordem**</td></tr><tr><td style="width: 50%;">Alta</td><td style="width: 50%;">3</td></tr><tr><td style="width: 50%;">Baixa</td><td style="width: 50%;">2</td></tr><tr><td style="width: 50%;">Média</td><td style="width: 50%;">1</td></tr></tbody></table>

Feito isso, o campo Campo de Apresentação continua sendo o campo 'Prioridade', mas o campo selecionado para ordenação é o 'Ordem'. Com isso, os itens serão apresentados na ordem (Baixa, Média e Alta).

##### Condição na Base de Dados

Na condição, pode-se escolher um dos campos da [Base de dados](#h_695508394161550686141083) para ser usado em uma comparação por valor (É igual a, É diferente de, Conter e Não conter) ou por outro campo (É igual ao campo ou É diferente do campo) desse formulário.

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="425" src="https://player.vimeo.com/video/318536339" width="760"></iframe>

<div id="bkmrk--3"></div><div id="bkmrk--4"></div>##### <span style="color: #3366ff;">**Caso esse formulário possa ser usado como tabela filha de outro formulário, essas duas opções são habilitadas:**</span>

##### Esse campo pode ser Relacionado a um formulário Pai e preenchido automaticamente pelo ID (Primary Key) do formulário pai

Caso esse formulário possa ser incluído como filho de um formulário pai, ative essa opção e selecione qual formulário que preencherá automaticamente esse campo. Para mais detalhes sobre esse funcionamento, veja detalhes na configuração de [Formulários Relacionados](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/formul%C3%A1rios-relacionados "Formulários Relacionados").

##### Esconder campo quando o formulário for aberto através do formulário pai

Quando esse formulário estiver incluído em um formulário pai, ative essa opção para que esse campo fique oculto, mesmo que esteja configurado para ser exibido na tela.

---

### Validação

Nessa parte, é possível configurar validações dos dados inseridos pelo usuário, garantindo um padrão de preenchimento.

> Como deixar um campo obrigatório?

#### Obrigatório

Caso marcado como "sim", não permite o salvamento do fomulário sem o preenchimento desse campo. Ao marcar como "sim" essa opção, são abertos duas outras opções:

##### Obrigatório mesmo que por algum motivo o campo esteja marcado como invisível?

Use essa opção para fazer um campo definido como obrigatório, deixar sua obrigatoriedade caso ele esteja [invisível](#bkmrk-%E2%A0-8).

##### Obrigatório a partir da etapa

Para os formulários com fluxo de etapas, é possível atrelar a obrigatoriedade de um campo à etapa em que se encontra o fluxo.

#### Valor do campo deve ser único em relação a todos os registros

O sistema, valida a inserção do campo, com os registros do mesmo campo, já salvos em outros formulários. Por exemplo, talvez exista uma necessidade de validação de um e-mail para o cadastro de um cliente. Caso o e-mail digitado já conste em outro registro, não será permitido o salvamento do formulário.

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="425" src="https://player.vimeo.com/video/328685546" width="760"></iframe>

#### Valor do campo deve ser único em relação ao formulário PAI

Caso o formulário tenha uma relação com outro formulário (chamamos de formulário Pai), será validado que os dados inseridos são únicos, mas apenas para o registro filho.

#### Valor do campo deve ser único em relação APENAS ao CAMPO relacionado do formulário PAI

Caso haja, mais de um campo no formulário pai, relacionado ao mesmo formulário filho, a validação de valor único, ocorre apenas par cada campo do relacionamento.

Abaixo, um vídeo explica essas 3 últimas opções:

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="425" src="https://player.vimeo.com/video/318250365" width="760"></iframe>

### Regras de Visibilidade e desativação

Usando essas opções, é possível tornar um campo visível, invisível, ativo ou inativo, e definir quando uma dessas ações deve ocorrer. É possível adicionar várias regras para cada campo.

#### Descrição

É um texto que ajuda a identificar a regra que se está criando. Muito útil quando existem múltiplas regras.

#### Ação

##### Ativar

Deixa o campo disponível para inserção de dados. É o estado padrão do campo.

##### Inativar

Deixa o campo indisponível para inserção de dados.

##### Visível

O campo é mostrado na tela, caso esteja inserido para tal, nas configurações de tela.

##### Invisível

O campo é não é mostrado na tela, mesmo que esteja inserido para tal, nas configurações de tela.

#### A partir da etapa / Até a etapa

Em formulários com etapas, é possível estabelecer que uma regra será aplicada em alguma(s) etapa(s). Para isso, basta selecionar as etapas nos campos "a partir da etapa" e "até a etapa", para definir em que momento do fluxo essa regra vai ser aplicada.

#### Quando

Define em que momento a ação deve acontecer.

##### Sempre

É o padrão do formulário.

##### Condicional

- Tipo de condição  
    Para fazer um validação condicional, estão disponíveis as seguintes condições:  
    
    - Se o campo: compara um campo com um valor, ou com outro campo.  
        Abaixo, uma tabela com os operadores disponíveis para as comparações:  
          
        <table border="1" style="border-collapse: collapse; width: 100%;"><tbody><tr><td style="width: 50%;">**Comparação por valor**</td><td style="width: 50%;">**Comparação por outro campo**</td></tr><tr><td style="width: 50%;">For igual a</td><td style="width: 50%;">É igual ao campo</td></tr><tr><td style="width: 50%;">For maior ou igual a</td><td style="width: 50%;">É diferente do campo</td></tr><tr><td style="width: 50%;">For menor ou igual a </td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">For maior que</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">For menor que</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">For diferente de</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">Conter</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">Não conter</td><td style="width: 50%;"> </td></tr></tbody></table>
        
        <p class="callout success">É possível adicionar mais de um condição na mesma regra.</p>
    - Se é um novo formulário: regra será aplicada quando uma nova entrada no formulário estiver sendo criada.
    - Se é edição de formulário: regra será aplicada quando uma entrada no formulário estiver sendo alterada.

### Customização Javascript

Caso a customização desejada, não esteja disponível, ainda assim é possível programá-la utilizando javascript. Para mais detalhes, acesse o [capítulo](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/customiza%C3%A7%C3%A3o-javascript "Customização javascript") sobre essa opção.

# Pesquisa com auto completar

Esse campo, é muito similar ao campo [Lista de Seleção](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/lista-de-sele%C3%A7%C3%A3o-%28combo%29 "Lista de seleção (Combo)") e permite que o usuário escolha uma opção pré-determinada.

Abaixo é possível comparar ambos campos, com a mesma fonte dinâmica de dados:

[![lista_auto_completar.gif](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/lista_auto_completar.gif)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/lista_auto_completar.gif)

### Grupo de informações

Dentro das configurações, é possível alterar o [grupo de informação](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/divis%C3%A3o-e-agrupamento-dos-campos "Divisão e agrupamento dos campos") ao qual o campo foi atribuído no momento da criação.

### Nome de Apresentação

Mostra o nome de apresentação informado no momento da criação. Esse é o nome que será mostrado na tela para o usuário.

### Coluna Banco de dados (SQL)

Esse é o nome interno, usado pelo sistema, a ser criado no banco de dados do agilityflow. É uma informação técnica e esse campo é preenchido automaticamente pelo sistema.

<p class="callout warning">Na maioria dos casos, você não precisa alterar o nome sugerido pelo sistema.</p>

Diferentemente do campo "Nome de Apresentação", esse campo não fica visível para o usuário.

> Para que serve o campo Coluna Banco de dados (SQL)?

Esse campo vai ser utilizado ao criar reports e dashboards. É através dele, que poderemos extrair informações e expor usando esses recursos do sistema.

### Informações de ajuda

Nesse campo é possível incluir um texto que ajudará o usuário a preenche-lo. Abaixo, um exemplo de dois campos: um campo sem informações de ajuda e outro com esse campo configurado:

[![informacoes_ajuda.gif](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/informacoes_ajuda.gif)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/informacoes_ajuda.gif)

---

### Origem dos Dados

Como existe uma lista de opções pré-determinadas, é necessário definir a origem dos dados.

#### Origem dos Itens

São duas as possibilidades:

**1. Lista Dinâmica** <span style="color: #3366ff;">(Utilização recomendada)</span> **:** Nessa opção, os dados têm como origem um outro formulário. Ao selecionar esse outro formulário, é necessário informar qual o campo desse formulário será exibido.

**2. Lista Estática:** O usuário insere as opções nas configurações do campo. Com isso, o usuário que acessa o formulário não pode criar novas opções. Ao criar as opções, além do nome, é possível definir a ordem em que aparecerão na lista de seleção. Outra opção, é o Id Customizado (Banco de Dados). Essa opção, normalmente não precisa ser preenchido. Entretanto, em alguns casos, esse id pode ser customizado. Isso pode ser útil, para a criação de dashboard e reports, para montar mais facilmente as *queries*.

#### **Configuração de uma <span style="color: #000000;">Lista Dinâmica </span>**

Abaixo estão descritos os campos básicos de preenchimento para definição de uma lista dinâmica.

Abra a tela de edição do campo e clique na aba **Origem dos Dados**

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555598725240.png)

##### **Campos para preenchimento:**

##### Origem dos dados

Defina como "Lista Dinâmica"

##### Quando os dados serão carregados?

Quando a lista é dinâmica, é possível definir algumas opções relativas ao carregamento da lista. Esse carregamento pode ocorrer de duas maneiras.

**<span style="color: #808080;">No carregamento inicial (On PageLoad):</span>** Assim que o formulário é carregado, as opções da lista de seleção também são carregados imediatamente.

<span style="color: #808080;">**Na alteração do valor de um determinado campo (On Change):** </span>As opções só serão carregadas quando um determinado campo mudar. Isso é útil, para uma lista de seleção selecionar níveis de outra lista de seleção. Ex: seleciona-se primeiro o estado e só depois, é selecionada a cidade. Esse campo Lista de Cidade, apenas é carregado quando o outro campo Lista de Estados é alterado. Para isso, é necessário também adicionar uma[ condição na base de dados](#h_50356803591550685996742).

##### Qual será a Base de dados

É o formulário que servirá de fonte para a Lista Dinâmica.

##### Campo de apresentação (Base de dados)

Essa é a informação que será apresentada para o usuário na apresentação do combo. Esse campo é referente ao formulário que foi selecionado no campo [Qual será a Base de dados](#h_695508394161550686141083).

##### Ordenar os itens pelo campo

A ordenação padrão do itens do combo é alfabética. Entretanto há casos onde queremos alterar essa ordem. Para isso, podemos utilizar um segundo campo como critério de ordenação, que não o campo de exibição. Como exemplo, vamos usar um formulário que só tem o campo nome, e os seguintes dados?

<table border="1" id="bkmrk-prioridade-alta-baix" style="border-collapse: collapse; width: 0%; height: 120px;"><tbody><tr><td style="width: 100%;">**Prioridade**</td></tr><tr><td style="width: 100%;">Alta</td></tr><tr><td style="width: 100%;">Baixa</td></tr><tr><td style="width: 100%;">Média</td></tr></tbody></table>

Ao usarmos o campo prioridade como critério de ordenação, os itens serão apresentados na ordem alfabética (Alta, Baixa e Média), quando o mais intuitivo seria apresentar a ordem como (Baixa, Média, Alta).

Para isso, podemos criar um campo chamado 'Ordem' nesse formulário, e incluir números. Dessa forma:

<table border="1" id="bkmrk-prioridade-ordem-alt" style="border-collapse: collapse; width: 100%;"><tbody><tr><td style="width: 50%;">**Prioridade**</td><td style="width: 50%;">**Ordem**</td></tr><tr><td style="width: 50%;">Alta</td><td style="width: 50%;">3</td></tr><tr><td style="width: 50%;">Baixa</td><td style="width: 50%;">2</td></tr><tr><td style="width: 50%;">Média</td><td style="width: 50%;">1</td></tr></tbody></table>

Feito isso, o campo Campo de Apresentação continua sendo o campo 'Prioridade', mas o campo selecionado para ordenação é o 'Ordem'. Com isso, os itens serão apresentados na ordem (Baixa, Média e Alta).

##### Condição na Base de Dados

Na condição, pode-se escolher um dos campos da [Base de dados](#h_695508394161550686141083) para ser usado em uma comparação por valor (É igual a, É diferente de, Conter e Não conter) ou por outro campo (É igual ao campo ou É diferente do campo) desse formulário.

<p class="callout success">O vídeo abaixo mostra a configuração da lista de seleção, mas também se aplica para o campo Pesquisa com Auto completar. O processo de configuração e o comportamento é idêntico.</p>

<div id="bkmrk--3"><iframe allowfullscreen="allowfullscreen" data-mce-fragment="1" frameborder="0" height="425" src="https://player.vimeo.com/video/318536339" width="760"></iframe>

</div><div id="bkmrk--4"></div>##### <span style="color: #3366ff;">**Caso esse formulário possa ser usado como tabela filha de outro formulário, essas duas opções são habilitadas:**</span>

##### Esse campo pode ser Relacionado a um formulário Pai e preenchido automaticamente pelo ID (Primary Key) do formulário pai

Caso esse formulário possa ser incluído como filho de um formulário pai, ative essa opção e selecione qual formulário que preencherá automaticamente esse campo. Para mais detalhes sobre esse funcionamento, veja detalhes na configuração de [Formulários Relacionados](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/formul%C3%A1rios-relacionados "Formulários Relacionados").

##### Esconder campo quando o formulário for aberto através do formulário pai

Quando esse formulário estiver incluído em um formulário pai, ative essa opção para que esse campo fique oculto, mesmo que esteja configurado para ser exibido na tela.

---

### Validação

Nessa parte, é possível configurar validações dos dados inseridos pelo usuário, garantindo um padrão de preenchimento.

> Como deixar um campo obrigatório?

#### Obrigatório

Caso marcado como "sim", não permite o salvamento do fomulário sem o preenchimento desse campo. Ao marcar como "sim" essa opção, são abertos duas outras opções:

##### Obrigatório mesmo que por algum motivo o campo esteja marcado como invisível?

Use essa opção para fazer um campo definido como obrigatório, deixar sua obrigatoriedade caso ele esteja [invisível](#bkmrk-%E2%A0-8).

##### Obrigatório a partir da etapa

Para os formulários com fluxo de etapas, é possível atrelar a obrigatoriedade de um campo à etapa em que se encontra o fluxo.

#### Valor do campo deve ser único em relação a todos os registros

O sistema, valida a inserção do campo, com os registros do mesmo campo, já salvos em outros formulários. Por exemplo, talvez exista uma necessidade de validação de um e-mail para o cadastro de um cliente. Caso o e-mail digitado já conste em outro registro, não será permitido o salvamento do formulário.

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="425" src="https://player.vimeo.com/video/328685546" width="760"></iframe>

#### Valor do campo deve ser único em relação ao formulário PAI

Caso o formulário tenha uma relação com outro formulário (chamamos de formulário Pai), será validado que os dados inseridos são únicos, mas apenas para o registro filho.

#### Valor do campo deve ser único em relação APENAS ao CAMPO relacionado do formulário PAI

Caso haja, mais de um campo no formulário pai, relacionado ao mesmo formulário filho, a validação de valor único, ocorre apenas par cada campo do relacionamento.

Abaixo, um vídeo explica essas 3 últimas opções:

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="425" src="https://player.vimeo.com/video/318250365" width="760"></iframe>

### Regras de Visibilidade e desativação

Usando essas opções, é possível tornar um campo visível, invisível, ativo ou inativo, e definir quando uma dessas ações deve ocorrer. É possível adicionar várias regras para cada campo.

#### Descrição

É um texto que ajuda a identificar a regra que se está criando. Muito útil quando existem múltiplas regras.

#### Ação

##### Ativar

Deixa o campo disponível para inserção de dados. É o estado padrão do campo.

##### Inativar

Deixa o campo indisponível para inserção de dados.

##### Visível

O campo é mostrado na tela, caso esteja inserido para tal, nas configurações de tela.

##### Invisível

O campo é não é mostrado na tela, mesmo que esteja inserido para tal, nas configurações de tela.

#### A partir da etapa / Até a etapa

Em formulários com etapas, é possível estabelecer que uma regra será aplicada em alguma(s) etapa(s). Para isso, basta selecionar as etapas nos campos "a partir da etapa" e "até a etapa", para definir em que momento do fluxo essa regra vai ser aplicada.

#### Quando

Define em que momento a ação deve acontecer.

##### Sempre

É o padrão do formulário.

##### Condicional

- Tipo de condição  
    Para fazer um validação condicional, estão disponíveis as seguintes condições:  
    
    - Se o campo: compara um campo com um valor, ou com outro campo.  
        Abaixo, uma tabela com os operadores disponíveis para as comparações:  
          
        <table border="1" style="border-collapse: collapse; width: 100%;"><tbody><tr><td style="width: 50%;">**Comparação por valor**</td><td style="width: 50%;">**Comparação por outro campo**</td></tr><tr><td style="width: 50%;">For igual a</td><td style="width: 50%;">É igual ao campo</td></tr><tr><td style="width: 50%;">For maior ou igual a</td><td style="width: 50%;">É diferente do campo</td></tr><tr><td style="width: 50%;">For menor ou igual a </td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">For maior que</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">For menor que</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">For diferente de</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">Conter</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">Não conter</td><td style="width: 50%;"> </td></tr></tbody></table>
        
        <p class="callout success">É possível adicionar mais de um condição na mesma regra.</p>
    - Se é um novo formulário: regra será aplicada quando uma nova entrada no formulário estiver sendo criada.
    - Se é edição de formulário: regra será aplicada quando uma entrada no formulário estiver sendo alterada.

### Customização Javascript

Caso a customização desejada, não esteja disponível, ainda assim é possível programá-la utilizando javascript. Para mais detalhes, acesse o [capítulo](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/customiza%C3%A7%C3%A3o-javascript "Customização javascript") sobre essa opção.

# Checkbox (Único)

Esse campo permite o usuário responder a uma pergunta cuja resposta tem duas opções.

### Grupo de informações

Dentro das configurações, é possível alterar o [grupo de informação](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/divis%C3%A3o-e-agrupamento-dos-campos "Divisão e agrupamento dos campos") ao qual o campo foi atribuído no momento da criação.

### Nome de Apresentação

Mostra o nome de apresentação informado no momento da criação. Esse é o nome que será mostrado na tela para o usuário.

### Texto ao lado do Checkbox

Nesse campo, é possível definir o texto quando o campo está marcado, e quando o campo está desmarcado. O texto escolhido quando o campo está marcado, será mostrado na tela, enquanto o texto do campo quando está desmarcado, apenas será mostrado na listagem e no filtro de dados.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/scaled-840-0/image-1550697051924.png)

#### Quando marcado

Texto a ser exibido ao lado do campo. Quando estiver marcado, esse texto será mostrado na listagem de dados.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/scaled-840-0/image-1550696926304.png)

#### Quando desmarcado

Esse texto não será exibido quando estiver desmarcado, mas será mostrado na listagem de dados.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/scaled-840-0/image-1550697002065.png)

### Coluna Banco de dados (SQL)

Esse é o nome interno, usado pelo sistema, a ser criado no banco de dados do agilityflow. É uma informação técnica e esse campo é preenchido automaticamente pelo sistema.

<p class="callout warning">Na maioria dos casos, você não precisa alterar o nome sugerido pelo sistema.</p>

Diferentemente do campo "Nome de Apresentação", esse campo não fica visível para o usuário.

> Para que serve o campo Coluna Banco de dados (SQL)?

Esse campo vai ser utilizado ao criar reports e dashboards. É através dele, que poderemos extrair informações e expor usando esses recursos do sistema.

### Informações de ajuda

Nesse campo é possível incluir um texto que ajudará o usuário a preenche-lo. Abaixo, um exemplo de dois campos: um campo sem informações de ajuda e outro com esse campo configurado:

[![informacoes_ajuda.gif](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/informacoes_ajuda.gif)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/informacoes_ajuda.gif)

### Validação

Nessa parte, é possível configurar validações dos dados inseridos pelo usuário, garantindo um padrão de preenchimento.

> Como deixar um campo obrigatório?

#### Obrigatório

Caso marcado como "sim", não permite o salvamento do fomulário sem o preenchimento desse campo. Ao marcar como "sim" essa opção, são abertos duas outras opções:

##### Obrigatório mesmo que por algum motivo o campo esteja marcado como invisível?

Use essa opção para fazer um campo definido como obrigatório, deixar sua obrigatoriedade caso ele esteja [invisível](#bkmrk-%E2%A0-8).

##### Obrigatório a partir da etapa

Para os formulários com fluxo de etapas, é possível atrelar a obrigatoriedade de um campo à etapa em que se encontra o fluxo.

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="425" src="https://player.vimeo.com/video/328685546" width="760"></iframe>

### Regras de Visibilidade e desativação

Usando essas opções, é possível tornar um campo visível, invisível, ativo ou inativo, e definir quando uma dessas ações deve ocorrer. É possível adicionar várias regras para cada campo.

#### Descrição

É um texto que ajuda a identificar a regra que se está criando. Muito útil quando existem múltiplas regras.

#### Ação

##### Ativar

Deixa o campo disponível para inserção de dados. É o estado padrão do campo.

##### Inativar

Deixa o campo indisponível para inserção de dados.

##### Visível

O campo é mostrado na tela, caso esteja inserido para tal, nas configurações de tela.

##### Invisível

O campo é não é mostrado na tela, mesmo que esteja inserido para tal, nas configurações de tela.

#### A partir da etapa / Até a etapa

Em formulários com etapas, é possível estabelecer que uma regra será aplicada em alguma(s) etapa(s). Para isso, basta selecionar as etapas nos campos "a partir da etapa" e "até a etapa", para definir em que momento do fluxo essa regra vai ser aplicada.

#### Quando

Define em que momento a ação deve acontecer.

##### Sempre

É o padrão do formulário.

##### Condicional

- Tipo de condição  
    Para fazer um validação condicional, estão disponíveis as seguintes condições:  
    
    - Se o campo: compara um campo com um valor, ou com outro campo.  
        Abaixo, uma tabela com os operadores disponíveis para as comparações:  
          
        <table border="1" style="border-collapse: collapse; width: 100%;"><tbody><tr><td style="width: 50%;">**Comparação por valor**</td><td style="width: 50%;">**Comparação por outro campo**</td></tr><tr><td style="width: 50%;">For igual a</td><td style="width: 50%;">É igual ao campo</td></tr><tr><td style="width: 50%;">For maior ou igual a</td><td style="width: 50%;">É diferente do campo</td></tr><tr><td style="width: 50%;">For menor ou igual a </td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">For maior que</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">For menor que</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">For diferente de</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">Conter</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">Não conter</td><td style="width: 50%;"> </td></tr></tbody></table>
        
        <p class="callout success">É possível adicionar mais de um condição na mesma regra.</p>
    - Se é um novo formulário: regra será aplicada quando uma nova entrada no formulário estiver sendo criada.
    - Se é edição de formulário: regra será aplicada quando uma entrada no formulário estiver sendo alterada.

### Customização Javascript

Caso a customização desejada, não esteja disponível, ainda assim é possível programá-la utilizando javascript. Para mais detalhes, acesse o [capítulo](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/customiza%C3%A7%C3%A3o-javascript "Customização javascript") sobre essa opção.

# Lista aberta com escolha única (Radio)

Esse campo é muito similar ao tipo [Lista de Seleção](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/lista-de-sele%C3%A7%C3%A3o-%28combo%29 "Lista de seleção (Combo)"), mudando apenas a forma como é apresentado. Abaixo, um exemplo do campo radio (Lista aberta com escolha única):

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1553779733129.png)

### Grupo de informações

Dentro das configurações, é possível alterar o [grupo de informação](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/divis%C3%A3o-e-agrupamento-dos-campos "Divisão e agrupamento dos campos") ao qual o campo foi atribuído no momento da criação.

### Nome de Apresentação

Mostra o nome de apresentação informado no momento da criação. Esse é o nome que será mostrado na tela para o usuário.

### Coluna Banco de dados (SQL)

Esse é o nome interno, usado pelo sistema, a ser criado no banco de dados do agilityflow. É uma informação técnica e esse campo é preenchido automaticamente pelo sistema.

<p class="callout warning">Na maioria dos casos, você não precisa alterar o nome sugerido pelo sistema.</p>

Diferentemente do campo "Nome de Apresentação", esse campo não fica visível para o usuário.

> Para que serve o campo Coluna Banco de dados (SQL)?

Esse campo vai ser utilizado ao criar reports e dashboards. É através dele, que poderemos extrair informações e expor usando esses recursos do sistema.

### Informações de ajuda

Nesse campo é possível incluir um texto que ajudará o usuário a preenche-lo. Abaixo, um exemplo de dois campos: um campo sem informações de ajuda e outro com esse campo configurado:

[![informacoes_ajuda.gif](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/informacoes_ajuda.gif)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/informacoes_ajuda.gif)

---

### Origem dos Dados

Como existe uma lista de opções pré-determinadas, é necessário definir a origem dos dados.

#### Origem dos Itens

São duas as possibilidades:

**1. Lista Dinâmica** <span style="color: #3366ff;">(Utilização recomendada)</span> **:** Nessa opção, os dados têm como origem um outro formulário. Ao selecionar esse outro formulário, é necessário informar qual o campo desse formulário será exibido.

**2. Lista Estática:** O usuário insere as opções nas configurações do campo. Com isso, o usuário que acessa o formulário não pode criar novas opções. Ao criar as opções, além do nome, é possível definir a ordem em que aparecerão na lista de seleção. Outra opção, é o Id Customizado (Banco de Dados). Essa opção, normalmente não precisa ser preenchido. Entretanto, em alguns casos, esse id pode ser customizado. Isso pode ser útil, para a criação de dashboard e reports, para montar mais facilmente as *queries*.

#### **Configuração de uma <span style="color: #000000;">Lista Dinâmica</span>**

Abaixo estão descritos os campos básicos de preenchimento para definição de uma lista dinâmica.

Abra a tela de edição do campo e clique na aba **Origem dos Dados**

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555598725240.png)

##### **Campos para preenchimento:**

##### Origem dos dados

Defina como "Lista Dinâmica"

##### Quando os dados serão carregados?

Quando a lista é dinâmica, é possível definir algumas opções relativas ao carregamento da lista. Esse carregamento pode ocorrer de duas maneiras.

**<span style="color: #808080;">No carregamento inicial (On PageLoad):</span>** Assim que o formulário é carregado, as opções da lista de seleção também são carregados imediatamente.

<span style="color: #808080;">**Na alteração do valor de um determinado campo (On Change):** </span>As opções só serão carregadas quando um determinado campo mudar. Isso é útil, para uma lista de seleção selecionar níveis de outra lista de seleção. Ex: seleciona-se primeiro o estado e só depois, é selecionada a cidade. Esse campo Lista de Cidade, apenas é carregado quando o outro campo Lista de Estados é alterado. Para isso, é necessário também adicionar uma[ condição na base de dados](#h_50356803591550685996742).

##### Qual será a Base de dados

É o formulário que servirá de fonte para a Lista Dinâmica.

##### Campo de apresentação (Base de dados)

Essa é a informação que será apresentada para o usuário na apresentação do combo. Esse campo é referente ao formulário que foi selecionado no campo [Qual será a Base de dados](#h_695508394161550686141083).

##### Ordenar os itens pelo campo

A ordenação padrão do itens do combo é alfabética. Entretanto há casos onde queremos alterar essa ordem. Para isso, podemos utilizar um segundo campo como critério de ordenação, que não o campo de exibição. Como exemplo, vamos usar um formulário que só tem o campo nome, e os seguintes dados?

<table border="1" id="bkmrk-prioridade-alta-baix" style="border-collapse: collapse; width: 0%; height: 120px;"><tbody><tr><td style="width: 100%;">**Prioridade**</td></tr><tr><td style="width: 100%;">Alta</td></tr><tr><td style="width: 100%;">Baixa</td></tr><tr><td style="width: 100%;">Média</td></tr></tbody></table>

Ao usarmos o campo prioridade como critério de ordenação, os itens serão apresentados na ordem alfabética (Alta, Baixa e Média), quando o mais intuitivo seria apresentar a ordem como (Baixa, Média, Alta).

Para isso, podemos criar um campo chamado 'Ordem' nesse formulário, e incluir números. Dessa forma:

<table border="1" id="bkmrk-prioridade-ordem-alt" style="border-collapse: collapse; width: 100%;"><tbody><tr><td style="width: 50%;">**Prioridade**</td><td style="width: 50%;">**Ordem**</td></tr><tr><td style="width: 50%;">Alta</td><td style="width: 50%;">3</td></tr><tr><td style="width: 50%;">Baixa</td><td style="width: 50%;">2</td></tr><tr><td style="width: 50%;">Média</td><td style="width: 50%;">1</td></tr></tbody></table>

Feito isso, o campo Campo de Apresentação continua sendo o campo 'Prioridade', mas o campo selecionado para ordenação é o 'Ordem'. Com isso, os itens serão apresentados na ordem (Baixa, Média e Alta).

##### Condição na Base de Dados

Na condição, pode-se escolher um dos campos da [Base de dados](#h_695508394161550686141083) para ser usado em uma comparação por valor (É igual a, É diferente de, Conter e Não conter) ou por outro campo (É igual ao campo ou É diferente do campo) desse formulário.

<p class="callout success">O vídeo abaixo mostra a configuração da lista de seleção, mas também se aplica para o campo Lista aberta com escolha única (Radio). O processo de configuração e o comportamento é idêntico.</p>

<div id="bkmrk--3"><iframe allowfullscreen="allowfullscreen" frameborder="0" height="425" src="https://player.vimeo.com/video/318536339" width="760"></iframe>

</div><div id="bkmrk--4"></div><div id="bkmrk--5"></div>---

### Validação

Nessa parte, é possível configurar validações dos dados inseridos pelo usuário, garantindo um padrão de preenchimento.

> Como deixar um campo obrigatório?

#### Obrigatório

Caso marcado como "sim", não permite o salvamento do fomulário sem o preenchimento desse campo. Ao marcar como "sim" essa opção, são abertos duas outras opções:

##### Obrigatório mesmo que por algum motivo o campo esteja marcado como invisível?

Use essa opção para fazer um campo definido como obrigatório, deixar sua obrigatoriedade caso ele esteja [invisível](#bkmrk-%E2%A0-8).

##### Obrigatório a partir da etapa

Para os formulários com fluxo de etapas, é possível atrelar a obrigatoriedade de um campo à etapa em que se encontra o fluxo.

#### Valor do campo deve ser único em relação a todos os registros

O sistema, valida a inserção do campo, com os registros do mesmo campo, já salvos em outros formulários. Por exemplo, talvez exista uma necessidade de validação de um e-mail para o cadastro de um cliente. Caso o e-mail digitado já conste em outro registro, não será permitido o salvamento do formulário.

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="425" src="https://player.vimeo.com/video/328685546" width="760"></iframe>

#### Valor do campo deve ser único em relação ao formulário PAI

Caso o formulário tenha uma relação com outro formulário (chamamos de formulário Pai), será validado que os dados inseridos são únicos, mas apenas para o registro filho.

#### Valor do campo deve ser único em relação APENAS ao CAMPO relacionado do formulário PAI

Caso haja, mais de um campo no formulário pai, relacionado ao mesmo formulário filho, a validação de valor único, ocorre apenas par cada campo do relacionamento.

Abaixo, um vídeo explica essas 3 últimas opções:

<div id="bkmrk--8"><iframe allowfullscreen="allowfullscreen" frameborder="0" height="425" src="https://player.vimeo.com/video/318250365" width="760"></iframe>

</div>### Regras de Visibilidade e desativação

Usando essas opções, é possível tornar um campo visível, invisível, ativo ou inativo, e definir quando uma dessas ações deve ocorrer. É possível adicionar várias regras para cada campo.

#### Descrição

É um texto que ajuda a identificar a regra que se está criando. Muito útil quando existem múltiplas regras.

#### Ação

##### Ativar

Deixa o campo disponível para inserção de dados. É o estado padrão do campo.

##### Inativar

Deixa o campo indisponível para inserção de dados.

##### Visível

O campo é mostrado na tela, caso esteja inserido para tal, nas configurações de tela.

##### Invisível

O campo é não é mostrado na tela, mesmo que esteja inserido para tal, nas configurações de tela.

#### A partir da etapa / Até a etapa

Em formulários com etapas, é possível estabelecer que uma regra será aplicada em alguma(s) etapa(s). Para isso, basta selecionar as etapas nos campos "a partir da etapa" e "até a etapa", para definir em que momento do fluxo essa regra vai ser aplicada.

#### Quando

Define em que momento a ação deve acontecer.

##### Sempre

É o padrão do formulário.

##### Condicional

- Tipo de condição  
    Para fazer um validação condicional, estão disponíveis as seguintes condições:  
    
    - Se o campo: compara um campo com um valor, ou com outro campo.  
        Abaixo, uma tabela com os operadores disponíveis para as comparações:  
          
        <table border="1" style="border-collapse: collapse; width: 100%;"><tbody><tr><td style="width: 50%;">**Comparação por valor**</td><td style="width: 50%;">**Comparação por outro campo**</td></tr><tr><td style="width: 50%;">For igual a</td><td style="width: 50%;">É igual ao campo</td></tr><tr><td style="width: 50%;">For maior ou igual a</td><td style="width: 50%;">É diferente do campo</td></tr><tr><td style="width: 50%;">For menor ou igual a </td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">For maior que</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">For menor que</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">For diferente de</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">Conter</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">Não conter</td><td style="width: 50%;"> </td></tr></tbody></table>
        
        <p class="callout success">É possível adicionar mais de um condição na mesma regra.</p>
    - Se é um novo formulário: regra será aplicada quando uma nova entrada no formulário estiver sendo criada.
    - Se é edição de formulário: regra será aplicada quando uma entrada no formulário estiver sendo alterada.

### Customização Javascript

Caso a customização desejada, não esteja disponível, ainda assim é possível programá-la utilizando javascript. Para mais detalhes, acesse o [capítulo](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/customiza%C3%A7%C3%A3o-javascript "Customização javascript") sobre essa opção.

# Fórmula

Com o campo de fórmula, é possível fazer cálculos com valores dos campos disponíveis no formulário, além de utilizar valores fixos na composição da fórmula.

O campo de fórmula faz dois tipos de cálculos: com campos numéricos e com campos com data/hora. É na definição do campo que seleciona-se o tipo de cálculo.

### Grupo de informações

Dentro das configurações, é possível alterar o [grupo de informação](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/divis%C3%A3o-e-agrupamento-dos-campos "Divisão e agrupamento dos campos") ao qual o campo foi atribuído no momento da criação.

### Nome de Apresentação

Mostra o nome de apresentação informado no momento da criação. Esse é o nome que será mostrado na tela para o usuário.

### Coluna Banco de dados (SQL)

Esse é o nome interno, usado pelo sistema, a ser criado no banco de dados do agilityflow. É uma informação técnica e esse campo é preenchido automaticamente pelo sistema.

<p class="callout warning">Na maioria dos casos, você não precisa alterar o nome sugerido pelo sistema.</p>

Diferentemente do campo "Nome de Apresentação", esse campo não fica visível para o usuário.

> Para que serve o campo Coluna Banco de dados (SQL)?

Esse campo vai ser utilizado ao criar reports e dashboards. É através dele, que poderemos extrair informações e expor usando esses recursos do sistema.

### Informações de ajuda

Nesse campo é possível incluir um texto que ajudará o usuário a preenche-lo. Abaixo, um exemplo de dois campos: um campo sem informações de ajuda e outro com esse campo configurado:

[![informacoes_ajuda.gif](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/informacoes_ajuda.gif)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/informacoes_ajuda.gif)

### Máscara

É a forma que o sistema utiliza para mostrar ao usuário, o conteúdo do campo de texto. Isso facilita a visualização da informação por parte do usuário. Por exemplo, é muito fácil ver o telefone "(11) 98765-4321" do que "11987654321".

#### Tipo de máscara

Existe uma série de máscaras disponíveis no agilityflow.

##### Número

> Como criar um campo numérico?

Um número não deixa de ser um texto. Portanto, para criar um campo numérico basta criar um campo textbox e aplicar uma máscara de número.

- Tipo de Número  
      
    
    - Inteiro: o campo não aceita "," ou "." no seu conteúdo. Ao digitar um desses símbolos, o sistema ignora a digitação. Por exemplo, digitando "1,5", o sistema ignora a vírgula e preenche "15". Caso o usuário cole o valor "1,5541", o sistema ignora a vírgula e o conteúdo à direita da vírgula, aceitando o valor "1".
    - Moeda (Real): coloca vírgula, deixando o campo com duas casas decimais;
    - Decimal (1 casa decimal): coloca vírgula, deixando o campo com duas casas decimais;
    - Decimal (2 casas decimais): coloca vírgula, deixando o campo com duas casas decimais;
    - Decimal (3 casas decimais): coloca vírgula, deixando o campo com duas casas decimais;
    - Decimal (4 casas decimais): coloca vírgula, deixando o campo com duas casas decimais;
    - Decimal (5 casas decimais): coloca vírgula, deixando o campo com duas casas decimais;

### Definição da Fórmula

São as configurações para os cálculos.

#### Tipo de Cálculo

Ao escolher o tipo, serão mostrados os campos disponíveis para serem usados.

##### Fórmula Numérica

é possível fazer as 4 operações aritméticas (soma, subtração, divisão e multiplicação) nesse campo. Para isso, basta selecionar um ou mais campos com a máscara do tipo numérico e escrever a fórmula.

<div id="bkmrk-"><iframe allowfullscreen="allowfullscreen" frameborder="0" src="https://player.vimeo.com/video/316087003"></iframe>

</div>##### Fórmula por data/hora

Fórmula por data/hora: nessa opção, é possível subtrair um campo do tipo data/hora, por outro campo do tipo data/hora. Como resultado, é possível obter:

- Número de Dias
- Número de Meses
- Número de Anos
- Número de Semanas
- Número de Horas:Minutos

<p class="callout info">Para fórmula com datas, só é possível fazer a operação de subtração.</p>

#### Fórmula

É a composição da fórmula. Basta começar a digitar o nome dos campos que estão mostrados logo abaixo e compor a fórmula. Esses campos são mostrados, de acordo com a máscara dos demais campos disponíveis do formulário. Além dos campos, é possível fazer a utilização dos operadores matemáticos.

[![composicao_formula.gif](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/composicao_formula.gif)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/composicao_formula.gif)

### Regras de Visibilidade e desativação

Usando essas opções, é possível tornar um campo visível, invisível, ativo ou inativo, e definir quando uma dessas ações deve ocorrer. É possível adicionar várias regras para cada campo.

#### Descrição

É um texto que ajuda a identificar a regra que se está criando. Muito útil quando existem múltiplas regras.

#### Ação

##### Visível

O campo é mostrado na tela, caso esteja inserido para tal, nas configurações de tela.

##### Invisível

O campo é não é mostrado na tela, mesmo que esteja inserido para tal, nas configurações de tela.

#### A partir da etapa / Até a etapa

Em formulários com etapas, é possível estabelecer que uma regra será aplicada em alguma(s) etapa(s). Para isso, basta selecionar as etapas nos campos "a partir da etapa" e "até a etapa", para definir em que momento do fluxo essa regra vai ser aplicada.

#### Quando

Define em que momento a ação deve acontecer.

##### Sempre

É o padrão do formulário.

##### Condicional

- Tipo de condição  
    Para fazer um validação condicional, estão disponíveis as seguintes condições:  
    
    - Se o campo: compara um campo com um valor, ou com outro campo.  
        Abaixo, uma tabela com os operadores disponíveis para as comparações:  
          
        <table border="1" style="border-collapse: collapse; width: 100%;"><tbody><tr><td style="width: 50%;">**Comparação por valor**</td><td style="width: 50%;">**Comparação por outro campo**</td></tr><tr><td style="width: 50%;">For igual a</td><td style="width: 50%;">É igual ao campo</td></tr><tr><td style="width: 50%;">For maior ou igual a</td><td style="width: 50%;">É diferente do campo</td></tr><tr><td style="width: 50%;">For menor ou igual a </td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">For maior que</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">For menor que</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">For diferente de</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">Conter</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">Não conter</td><td style="width: 50%;"> </td></tr></tbody></table>
        
        <p class="callout success">É possível adicionar mais de um condição na mesma regra.</p>
    - Se é um novo formulário: regra será aplicada quando uma nova entrada no formulário estiver sendo criada.
    - Se é edição de formulário: regra será aplicada quando uma entrada no formulário estiver sendo alterada.

### Customização Javascript

Caso a customização desejada, não esteja disponível, ainda assim é possível programá-la utilizando javascript. Para mais detalhes, acesse o [capítulo](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/customiza%C3%A7%C3%A3o-javascript "Customização javascript") sobre essa opção.

# Campo com Múltipla Escolha

Apesar do visual um pouco diferente, tem comportamento similar ao campo [checkbox](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/checkbox-%28%C3%BAnico%29 "Checkbox (Único)"), mas permite a escolha de mais de uma opção.

### Grupo de informações

Dentro das configurações, é possível alterar o [grupo de informação](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/divis%C3%A3o-e-agrupamento-dos-campos "Divisão e agrupamento dos campos") ao qual o campo foi atribuído no momento da criação.

### Nome de Apresentação

Mostra o nome de apresentação informado no momento da criação. Esse é o nome que será mostrado na tela para o usuário.

### Coluna Banco de dados (SQL)

Esse é o nome interno, usado pelo sistema, a ser criado no banco de dados do agilityflow. É uma informação técnica e esse campo é preenchido automaticamente pelo sistema.

<p class="callout warning">Na maioria dos casos, você não precisa alterar o nome sugerido pelo sistema.</p>

Diferentemente do campo "Nome de Apresentação", esse campo não fica visível para o usuário.

> Para que serve o campo Coluna Banco de dados (SQL)?

Esse campo vai ser utilizado ao criar reports e dashboards. É através dele, que poderemos extrair informações e expor usando esses recursos do sistema.

### Informações de ajuda

Nesse campo é possível incluir um texto que ajudará o usuário a preenche-lo. Abaixo, um exemplo de dois campos: um campo sem informações de ajuda e outro com esse campo configurado:

[![informacoes_ajuda.gif](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/informacoes_ajuda.gif)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/informacoes_ajuda.gif)

---

### Origem dos Dados

Como existe uma lista de opções pré-determinadas, é necessário definir a origem dos dados.

#### Origem dos Itens

São duas as possibilidades:

**1. Lista Dinâmica** <span style="color: #3366ff;">(Utilização recomendada)</span> **:** Nessa opção, os dados têm como origem um outro formulário. Ao selecionar esse outro formulário, é necessário informar qual o campo desse formulário será exibido.

**2. Lista Estática:** O usuário insere as opções nas configurações do campo. Com isso, o usuário que acessa o formulário não pode criar novas opções. Ao criar as opções, além do nome, é possível definir a ordem em que aparecerão na lista de seleção. Outra opção, é o Id Customizado (Banco de Dados). Essa opção, normalmente não precisa ser preenchido. Entretanto, em alguns casos, esse id pode ser customizado. Isso pode ser útil, para a criação de dashboard e reports, para montar mais facilmente as *queries*.

#### **Configuração de uma <span style="color: #000000;">Lista Dinâmica</span>**

Abaixo estão descritos os campos básicos de preenchimento para definição de uma lista dinâmica.

Abra a tela de edição do campo e clique na aba **Origem dos Dados**

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555598725240.png)

##### **Campos para preenchimento:**

##### Origem dos dados

Defina como "Lista Dinâmica"

##### Quando os dados serão carregados?

Quando a lista é dinâmica, é possível definir algumas opções relativas ao carregamento da lista. Esse carregamento pode ocorrer de duas maneiras.

**<span style="color: #808080;">No carregamento inicial (On PageLoad):</span>** Assim que o formulário é carregado, as opções da lista de seleção também são carregados imediatamente.

<span style="color: #808080;">**Na alteração do valor de um determinado campo (On Change):** </span>As opções só serão carregadas quando um determinado campo mudar. Isso é útil, para uma lista de seleção selecionar níveis de outra lista de seleção. Ex: seleciona-se primeiro o estado e só depois, é selecionada a cidade. Esse campo Lista de Cidade, apenas é carregado quando o outro campo Lista de Estados é alterado. Para isso, é necessário também adicionar uma[ condição na base de dados](#h_50356803591550685996742).

##### Qual será a Base de dados

É o formulário que servirá de fonte para a Lista Dinâmica.

##### Campo de apresentação (Base de dados)

Essa é a informação que será apresentada para o usuário na apresentação do combo. Esse campo é referente ao formulário que foi selecionado no campo [Qual será a Base de dados](#h_695508394161550686141083).

##### Ordenar os itens pelo campo

A ordenação padrão do itens do combo é alfabética. Entretanto há casos onde queremos alterar essa ordem. Para isso, podemos utilizar um segundo campo como critério de ordenação, que não o campo de exibição. Como exemplo, vamos usar um formulário que só tem o campo nome, e os seguintes dados?

<table border="1" id="bkmrk-prioridade-alta-baix" style="border-collapse: collapse; width: 0%; height: 120px;"><tbody><tr><td style="width: 100%;">**Prioridade**</td></tr><tr><td style="width: 100%;">Alta</td></tr><tr><td style="width: 100%;">Baixa</td></tr><tr><td style="width: 100%;">Média</td></tr></tbody></table>

Ao usarmos o campo prioridade como critério de ordenação, os itens serão apresentados na ordem alfabética (Alta, Baixa e Média), quando o mais intuitivo seria apresentar a ordem como (Baixa, Média, Alta).

Para isso, podemos criar um campo chamado 'Ordem' nesse formulário, e incluir números. Dessa forma:

<table border="1" id="bkmrk-prioridade-ordem-alt" style="border-collapse: collapse; width: 100%;"><tbody><tr><td style="width: 50%;">**Prioridade**</td><td style="width: 50%;">**Ordem**</td></tr><tr><td style="width: 50%;">Alta</td><td style="width: 50%;">3</td></tr><tr><td style="width: 50%;">Baixa</td><td style="width: 50%;">2</td></tr><tr><td style="width: 50%;">Média</td><td style="width: 50%;">1</td></tr></tbody></table>

Feito isso, o campo Campo de Apresentação continua sendo o campo 'Prioridade', mas o campo selecionado para ordenação é o 'Ordem'. Com isso, os itens serão apresentados na ordem (Baixa, Média e Alta).

##### Condição na Base de Dados

Na condição, pode-se escolher um dos campos da [Base de dados](#h_695508394161550686141083) para ser usado em uma comparação por valor (É igual a, É diferente de, Conter e Não conter) ou por outro campo (É igual ao campo ou É diferente do campo) desse formulário.

<p class="callout success">O vídeo abaixo mostra a configuração da lista de seleção, mas também se aplica para o campo Campo com Múltipla Escolha. O processo de configuração e o comportamento é idêntico.</p>

<div id="bkmrk--0"><iframe allowfullscreen="allowfullscreen" data-mce-fragment="1" frameborder="0" height="425" src="https://player.vimeo.com/video/318536339" width="760"></iframe>

</div>---

###  

### Validação

Nessa parte, é possível configurar validações dos dados inseridos pelo usuário, garantindo um padrão de preenchimento.

> Como deixar um campo obrigatório?

#### Obrigatório

Caso marcado como "sim", não permite o salvamento do fomulário sem o preenchimento desse campo. Ao marcar como "sim" essa opção, são abertos duas outras opções:

##### Obrigatório mesmo que por algum motivo o campo esteja marcado como invisível?

Use essa opção para fazer um campo definido como obrigatório, deixar sua obrigatoriedade caso ele esteja [invisível](#bkmrk-%E2%A0-8).

##### Obrigatório a partir da etapa

Para os formulários com fluxo de etapas, é possível atrelar a obrigatoriedade de um campo à etapa em que se encontra o fluxo.

#### Tipo de Validação

Para o campo com múltipla escolha, é possível fazer uma validação relativo à quantidade de itens marcados.

- Selecionar no máximo X itens: define um limite máximo de itens marcados;
- Selecionar no mínimo X itens: define um limite mínimo de itens marcados;
- Selecionar exatamente X itens: define um número exato de itens marcados;

### Regras de Visibilidade e desativação

Usando essas opções, é possível tornar um campo visível, invisível, ativo ou inativo, e definir quando uma dessas ações deve ocorrer. É possível adicionar várias regras para cada campo.

#### Descrição

É um texto que ajuda a identificar a regra que se está criando. Muito útil quando existem múltiplas regras.

#### Ação

##### Ativar

Deixa o campo disponível para inserção de dados. É o estado padrão do campo.

##### Inativar

Deixa o campo indisponível para inserção de dados.

##### Visível

O campo é mostrado na tela, caso esteja inserido para tal, nas configurações de tela.

##### Invisível

O campo é não é mostrado na tela, mesmo que esteja inserido para tal, nas configurações de tela.

#### A partir da etapa / Até a etapa

Em formulários com etapas, é possível estabelecer que uma regra será aplicada em alguma(s) etapa(s). Para isso, basta selecionar as etapas nos campos "a partir da etapa" e "até a etapa", para definir em que momento do fluxo essa regra vai ser aplicada.

#### Quando

Define em que momento a ação deve acontecer.

##### Sempre

É o padrão do formulário.

##### Condicional

- Tipo de condição  
    Para fazer um validação condicional, estão disponíveis as seguintes condições:  
    
    - Se o campo: compara um campo com um valor, ou com outro campo.  
        Abaixo, uma tabela com os operadores disponíveis para as comparações:  
          
        <table border="1" style="border-collapse: collapse; width: 100%;"><tbody><tr><td style="width: 50%;">**Comparação por valor**</td><td style="width: 50%;">**Comparação por outro campo**</td></tr><tr><td style="width: 50%;">For igual a</td><td style="width: 50%;">É igual ao campo</td></tr><tr><td style="width: 50%;">For maior ou igual a</td><td style="width: 50%;">É diferente do campo</td></tr><tr><td style="width: 50%;">For menor ou igual a </td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">For maior que</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">For menor que</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">For diferente de</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">Conter</td><td style="width: 50%;"> </td></tr><tr><td style="width: 50%;">Não conter</td><td style="width: 50%;"> </td></tr></tbody></table>
        
        <p class="callout success">É possível adicionar mais de um condição na mesma regra.</p>
    - Se é um novo formulário: regra será aplicada quando uma nova entrada no formulário estiver sendo criada.
    - Se é edição de formulário: regra será aplicada quando uma entrada no formulário estiver sendo alterada.

### Customização Javascript

Caso a customização desejada, não esteja disponível, ainda assim é possível programá-la utilizando javascript. Para mais detalhes, acesse o [capítulo](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/customiza%C3%A7%C3%A3o-javascript "Customização javascript") sobre essa opção.

# Botão Customizado

Caso seja necessário uma ação no formulário que não exista no agilityflow, é possível criar um botão. Esse botão, executa um código [javascript](#bkmrk-customiza%E3%A7%E3%A3o-javas) personalizado, que deve ser criado pelo usuário. Para a configuração desse campo, é necessário conhecimento de [javascript](#bkmrk-customiza%E3%A7%E3%A3o-javas), já que qualquer ação com esse botão é 100% customizada.

### Grupo de informações

Dentro das configurações, é possível alterar o [grupo de informação](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/divis%C3%A3o-e-agrupamento-dos-campos "Divisão e agrupamento dos campos") ao qual o campo foi atribuído no momento da criação.

### Nome de Apresentação

Mostra o nome de apresentação informado no momento da criação. Esse é o nome que será mostrado na tela para o usuário.

### Regras de Visibilidade e desativação

Usando essas opções, é possível tornar um campo visível, invisível, ativo ou inativo, e definir quando uma dessas ações deve ocorrer. É possível adicionar várias regras para cada campo.

#### Descrição

É um texto que ajuda a identificar a regra que se está criando. Muito útil quando existem múltiplas regras.

#### Ação

##### Ativar

Deixa o campo disponível para inserção de dados. É o estado padrão do campo.

##### Inativar

Deixa o campo indisponível para inserção de dados.

##### Visível

O campo é mostrado na tela, caso esteja inserido para tal, nas configurações de tela.

##### Invisível

O campo é não é mostrado na tela, mesmo que esteja inserido para tal, nas configurações de tela.

#### A partir da etapa / Até a etapa

Em formulários com etapas, é possível estabelecer que uma regra será aplicada em alguma(s) etapa(s). Para isso, basta selecionar as etapas nos campos "a partir da etapa" e "até a etapa", para definir em que momento do fluxo essa regra vai ser aplicada.

#### Quando

Define em que momento a ação deve acontecer.

##### Sempre

É o padrão do formulário.

##### Condicional

- Tipo de condição  
    Para fazer um validação condicional, estão disponíveis as seguintes condições:  
    
    - Se o campo: compara um campo com um valor, ou com outro campo.  
        Abaixo, uma tabela com os operadores disponíveis para as comparações:  
          
        <table border="1"><tbody><tr><td>**Comparação por valor**</td><td>**Comparação por outro campo**</td></tr><tr><td>For igual a</td><td>É igual ao campo</td></tr><tr><td>For maior ou igual a</td><td>É diferente do campo</td></tr><tr><td>For menor ou igual a </td><td> </td></tr><tr><td>For maior que</td><td> </td></tr><tr><td>For menor que</td><td> </td></tr><tr><td>For diferente de</td><td> </td></tr><tr><td>Conter</td><td> </td></tr><tr><td>Não conter</td><td> </td></tr></tbody></table>
        
        <p class="callout success">É possível adicionar mais de um condição na mesma regra.</p>
    - Se é um novo formulário: regra será aplicada quando uma nova entrada no formulário estiver sendo criada.
    - Se é edição de formulário: regra será aplicada quando uma entrada no formulário estiver sendo alterada.

### Customização Javascript

A parte mais importante do botão customizado é a programação em javascript. É com ela que o botão será capaz de executar alguma ação no formulário.

Com a customização em Javascript, as possibilidade são inúmeras. Qualquer que seja o código javascript, ele pode ser usado aqui.

#### Exemplo de código

> Posso abrir o WhatsApp pelo agilityflow?

No exemplo abaixo, o botão customizado está configurado para abrir o WhatsApp Web e iniciar uma conversa com o número cadastrado no formulário.

```JavaScript
var fone = $("#telefone").val();

if (fone !== null)
    fone = fone.replaceAll(/\(/,"").replaceAll(/\)/,"").replaceAll(/-/,"").replaceAll(/ /,"");

window.open("https://web.whatsapp.com/send?phone="+fone);
```

##### Explicando o código

```JavaScript
var fone = $("#telefone").val();
```

Obtém-se o valor do campo telefone, e o armazena na variável chamada *fone*. Note que esse nome é exatamente o nome definidos na configuração [Coluna Banco de dados (SQL)](http://wiki.agilityflow.io/link/38#bkmrk-%E2%A0-0 "Coluna Banco de dados (SQL)").

```JavaScript
if (fone !== null)
    fone = fone.replaceAll(/\(/,"").replaceAll(/\)/,"").replaceAll(/-/,"").replaceAll(/ /,"");
```

Nesse ponto, checa se o valor é nulo. Caso não seja, limpa o número, removendo parêntesis e hifens.

<div data-lang="JavaScript" id="bkmrk-window.open%28%22https%3A%2F"><div data-lang="JavaScript"><textarea style="display: none;">window.open("https://web.whatsapp.com/send?phone="+fone);</textarea><div><div><textarea spellcheck="false" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;" tabindex="0"></textarea></div></div></div></div>```JavaScript
window.open("https://web.whatsapp.com/send?phone="+fone);
```

<div data-lang="JavaScript" id="bkmrk-abre-se-uma-nova-jan"><div><div>Abre-se uma nova janela, passando o valor da variável *fone* na URL.</div></div></div><div id="bkmrk-"></div><div id="bkmrk--0"></div><div data-lang="JavaScript" id="bkmrk--1"><div><div><div></div></div><div></div></div></div>

# Formulários Relacionados

Basicamente, um formulário relacionado é um formulário dentro de outro formulário.

> Como criar um formulário relacionado?

Para criar um formulário relacionado, você deve criar um [formulário](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/chapter/formul%C3%A1rios "Formulários") comum, como qualquer outro. Além disso é necessário adicionar dois componentes adicionais:

- Ativar a opção de relacionamento com outros formulários:  
      
    ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/scaled-840-0/image-1551110874990.png)
    
      
    Na definição básica do formulário, deve-se ativar a opção "*Pode ser usado como tabela filha de um outro formulário (Tabela de Formulário Relacionado)*". A opção "Abrir apenas através de um formulário pai", inibe que esse formulário seja aberto da maneira convencional, permitindo apenas que ele seja aberto através de outro formulário.
- Criar um campo de relacionamento com o formulário Pai:  
      
    Isso é fundamental para exista a relação entre os dois formulários. Para isso, é necessário criar um campo de autocompletar ou lista de seleção, com uma fonte dinâmica de dados, usando o formulário pai como fonte. Feito isso, escolhe-se um campo para que seja mostrado (de preferência o campo com maior importância desse formulário) e marca-se as seguintes duas opções:  
    
    - Esse campo pode ser Relacionado a um formulário Pai e preenchido automaticamente pelo ID (Primary Key) do formulário pai: essa opção deve ser marcada, para que o sistema automaticamente preencha essa opção. como esse formulário, vai ser aberto através do formulário pai, o preenchimento fica sendo automático e transparente para o usuário.
    - Esconder campo quando o formulário for aberto através do formulário pai (opcional): como esse campo vai ser preenchido automaticamente pelo formulário, podemos ocultar quando o formulário for aberto pelo formulário pai.

No exemplo abaixo, temos um formulário chamado Clientes, que é um cadastro de pessoas jurídicas. Para cada cadastro, queremos incluir N contatos com nomes de pessoas físicas que trabalham nessa empresa.

Para fazer isso, criamos um formulário chamado Contatos. Nas definições básicas desse formulário, marcamos a opção "*Pode ser usado como tabela filha de um outro formulário (Tabela de Formulário Relacionado)*". Além dos campos necessários para o cadastro dos contatos, criamos um campo chamado Relacionamento\_Clientes, que é o campo que vai se relacionar com o formulário *Clientes* (formulário Pai). A configuração desse campo fica assim:

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/scaled-840-0/image-1551188642189.png)

Quando o formulário filho está configurado dessa forma, ele fica disponível para ser adicionado no formulário pai:

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/scaled-840-0/image-1551188621161.png)

O uso é transparente para o usuário, não percebendo essa amarração entre os formulários.

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="425" src="https://player.vimeo.com/video/319870425" width="760"></iframe>

Abaixo, as demais configurações de um formulário relacionado:

### Grupo de informações

Dentro das configurações, é possível alterar o [grupo de informação](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/divis%C3%A3o-e-agrupamento-dos-campos "Divisão e agrupamento dos campos") ao qual o campo foi atribuído no momento da criação.

### Nome de Apresentação

Mostra o nome de apresentação informado no momento da criação. Esse é o nome que será mostrado na tela para o usuário.

### Ordenação manual organizada pelo próprio usuário através de Arrastar e Soltar (Drag and Drop)

Permite ao usuário, ordenar as entradas do formulário relacionado.

[![reordenar_lista.gif](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/reordenar_lista.gif)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/reordenar_lista.gif)

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="425" src="https://player.vimeo.com/video/332437405" width="760"></iframe>

### Customização da Lista

Essas opções, permitem configurar aspectos da lista do formulário relacionado que serão exibidos

#### Coluna Visível

Caso não seja necessário, uma ou mais colunas podem ser ocultadas da visualização dentro do formulário pai. Isso ajuda na organização dos dados que são mostrados na tela.

##### Prefixo

Adiciona um texto opcional antes do conteúdo do campo.

##### Sufixo

Adicional um texto opcional após o conteúdo do campo.

##### Informação no Rodapé

No rodapé, é possível exibir uma informação extra, baseada nos campos numéricos do formulário relacionado. São elas:

- Soma da Coluna  
    Faz a soma de todos os valores dessa coluna e exibe o total.
- Média da Coluna  
    Faz a média de todos os valores dessa coluna e exibe o resultado.  
      
    Caso uma dessas opções seja selecionada, é preciso selecionar uma [máscara](http://wiki.agilityflow.io/link/38#bkmrk-m%E3%A1scara) para o rodapé.  
    
    - Moeda (Real)
    - Decimal (1 casa decimal)
    - Decimal (2 casas decimais)
    - Decimal (3 casas decimais)
    - Decimal (4 casas decimais)
    - Decimal (5 casas decimais)

### Lista do formulário que podem ser apresentadas como Sub Lista

Caso o formulário relacionado, contenha outro formulário relacionado, essas opções serão apresentadas.

#### Já abrir com as Sub Lista expandidas

O formulário relacionado que pertence a esse, será apresentado com a lista expandida. Essa configuração dá a opção do usuário definir o comportamento padrão. Isso é útil, caso hajam muitos dados, e nem todos precisam estar visíveis no primeiro momento, deixando a leitura do formulário mais simples.

#### Sub Lista visível

Aqui o usuário seleciona quais formulários relacionados devem estar visíveis.

### Apresentar nessa tabela de dados apenas os dados que foram cadastrados através desse campo da tela

Essa opção permite ao usuário mostrar apenas os dados cadastrados através do formulário pai, e não os registros cadastrados pelo formulário filho, mesmo que quando feito, tenha sido colocado o relacionamento com algum registro do formulário pai.

# Componentes CsHtml

Para acessar os detalhes desse conteúdo, [clique aqui](http://wiki.agilityflow.io/link/78#bkmrk-page-title).

# Label com Query SQL

Label com Query SQL é um campo de texto não editável, que é preenchido através de uma Query SQL definida por você. Esse campo é muito útil, quando se tem um campo de lista de seleção (ou pesquisa com auto-completar) com uma fonte dinâmica e há a necessidade mostrar outros campos do formulário usado como fonte por esse campo. Também pode ser útil para gerar um SUM, AVG e outras funções do SQL.

No exemplo abaixo, o formulário tem uma lista de seleção de clientes. Os outros dois campos, são Label com Query SQL com informações do formulário de cliente.

[![label_dinamica.gif](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/label_dinamica.gif)](http://wiki.agilityflow.io/uploads/images/gallery/2019-02-Feb/label_dinamica.gif)

<div id="bkmrk-%E2%A0%E2%A0%E2%A0"><div><span class="icon text-primary"><svg class="svg-icon" data-icon="link" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg> </span><span class="input-group"> <button class="button icon" data-clipboard-target="#pointer-url" title="Copia Link" type="button"><svg class="svg-icon" data-icon="copy" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></button> </span>[<svg class="svg-icon" data-icon="edit" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg>](https://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/label-din%C3%A2mica/edit?content-id=bkmrk-ao-mudar-o-campo-de-&content-text=Ao%20mudar%20o%20campo%20de%20lista%20de%20sele%C3%A7%C3%A3o%2C%20a%20label%20din%C3%A2 "Editar conteúdo")</div></div>Ao mudar o campo de lista de seleção, a label com Query SQL é preenchida automaticamente.

# Tabela de dados customizada através de programação: Query SQL, C#, HTML e CSS

Para acessar os detalhes desse conteúdo, [clique aqui](https://wiki.agilityflow.io/link/78#bkmrk-criar-html-com-tabel).

# Campo de Assinatura

O campo de assinatura, permite que um usuário "desenhe" sua assinatura através do dedo (no celular) ou do mouse (no computador), ao final essa assinatura se transformará em uma imagem.

![](https://wiki.agilityflow.io/uploads/images/gallery/2020-07-Jul/scaled-840-0/image-1595285811190.png)

### Grupo de informações

Dentro das configurações, é possível alterar o [grupo de informação](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/divis%C3%A3o-e-agrupamento-dos-campos "Divisão e agrupamento dos campos") ao qual o campo foi atribuído no momento da criação.

### Nome de Apresentação

Mostra o nome de apresentação informado no momento da criação. Esse é o nome que será mostrado na tela para o usuário.

### Regras de Visibilidade e desativação

Usando essas opções, é possível tornar um campo visível, invisível, ativo ou inativo, e definir quando uma dessas ações deve ocorrer. É possível adicionar várias regras para cada campo.

#### Descrição

É um texto que ajuda a identificar a regra que se está criando. Muito útil quando existem múltiplas regras.

#### Ação

##### Ativar

Deixa o campo disponível para inserção de dados. É o estado padrão do campo.

##### Inativar

Deixa o campo indisponível para inserção de dados.

##### Visível

O campo é mostrado na tela, caso esteja inserido para tal, nas configurações de tela.

##### Invisível

O campo é não é mostrado na tela, mesmo que esteja inserido para tal, nas configurações de tela.

#### A partir da etapa / Até a etapa

Em formulários com etapas, é possível estabelecer que uma regra será aplicada em alguma(s) etapa(s). Para isso, basta selecionar as etapas nos campos "a partir da etapa" e "até a etapa", para definir em que momento do fluxo essa regra vai ser aplicada.

#### Quando

Define em que momento a ação deve acontecer.

##### Sempre

É o padrão do formulário.

##### Condicional

- Tipo de condição  
    Para fazer um validação condicional, estão disponíveis as seguintes condições:  
    
    - Se o campo: compara um campo com um valor, ou com outro campo.  
        Abaixo, uma tabela com os operadores disponíveis para as comparações:  
          
        <table border="1"><tbody><tr><td>**Comparação por valor**</td><td>**Comparação por outro campo**</td></tr><tr><td>For igual a</td><td>É igual ao campo</td></tr><tr><td>For maior ou igual a</td><td>É diferente do campo</td></tr><tr><td>For menor ou igual a </td><td> </td></tr><tr><td>For maior que</td><td> </td></tr><tr><td>For menor que</td><td> </td></tr><tr><td>For diferente de</td><td> </td></tr><tr><td>Conter</td><td> </td></tr><tr><td>Não conter</td><td> </td></tr></tbody></table>
        
        <p class="callout success">É possível adicionar mais de um condição na mesma regra.</p>
    - Se é um novo formulário: regra será aplicada quando uma nova entrada no formulário estiver sendo criada.
    - Se é edição de formulário: regra será aplicada quando uma entrada no formulário estiver sendo alterada.

# Programação

Informações aprofundadas sobre o uso de JavaScript, C# e Query (SQL) no agilityflow.

# SQL Server (Query) - Dicas e Funções (Versões Mais Antigas do Agilityflow)

<p class="callout warning">**IMPORTANTE**: Essa documentação é referente as versões antes de 2024 que são mais antigas do agilityflow e que utilizam o Banco de Dados **SQL SERVER.** O agilityflow nas últimas versões está utilizando **POSTGRESQL** .</p>

No agilityflow você pode buscar os dados utilizando SQL, através de queries. As queries devem ser compatíveis com **SQL Server.** Além disso existem alguns padrões que você deve seguir para obter um melhor resultado no agilityflow. Abaixo estão alguns detalhes importantes.

### Tratamento de Registros Deletados

<p class="callout danger">**IMPORTANTE:**   
É de extrema importância o tratamento de registros deletados, usando as regras abaixo.   
  
Já está no nosso Roadmap o tratamento automático dos deletados, enquanto isso, o tratamento se torna obrigatório pelo desenvolvedor.</p>

Para manter a integridade dos dados, o agilityflow nunca apaga um registro de uma tabela. Apenas o marca como deletado. Portanto, para qualquer query, é preciso excluir os deletados da lista.

Essa marcação é feita com campo deletado. Se o valor for 0, significa que ele não foi deletado e está visível no sistema. Caso esteja 1, significa que o registro já foi excluído e não é possível mais vê-lo na listagem principal do sistema.

**Exemplo 1, sem o tratamento de deletados:**

```SQL
select usu_nome, usu_email from tbl_usuario
```

**Resultado**:

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552935887749.png)

**Exemplo 2, com o tratamento de deletados:**

```SQL
select usu_nome, usu_email from tbl_usuario
where deletado = 0
```

**Resultado**:

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552935923310.png)

### Campo do tipo Datetime (Data e Hora)

Sempre que um campo de texto com máscara do tipo data é criado, o sistema cria uma cópia com o mesmo nome seguido de "<span style="color: #ff6600;">**\_\_datetime\_\_**</span>" essa informação é gravada em uma coluna no banco de dados do tipo **<span style="text-decoration: underline;">datetime</span>**, ao invés de varchar. Esses campos são criados para facilitar o uso tipado do dado nas queries

#### **Exemplo de campo Datetime**

Por exemplo, se o campo se chama "data\_e\_hora", haverá um outro chamado "data\_e\_hora\_\_datetime\_\_" e o conteúdo estará no formato padrão do sql server, **YYYY-MM-DD hh:mm:ss**

O campo "data\_e\_hora" estará sempre como varchar e o "data\_e\_hora\_\_datetime\_\_" estará como datetime

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-04-Apr/scaled-840-0/image-1617632924330.png)

### Campo do tipo Numérico (decimal, float, double, int, number)

Sempre que um campo de texto com máscara do tipo número é criado, o sistema cria uma cópia com o mesmo nome seguido de "<span style="color: #ff6600;">**\_\_number\_\_**</span>" essa informação é gravada em uma coluna no banco de dados do tipo **<span style="text-decoration: underline;">numeric(18,6)</span>,** ao invés de varchar. Esses campos são criados para facilitar o uso tipado do dado nas queries

#### **Exemplo de campo numérico**

Por exemplo, se o campo se chama "numero\_exemplo", haverá um outro chamado "numero\_exemplo\_\_number\_\_" e o conteúdo estará no formato padrão do sql server.

O campo "numero\_exemplo" estará sempre como varchar e o "numero\_exemplo\_\_number\_\_" estará como numeric(18,6)

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-04-Apr/scaled-840-0/image-1617633138473.png)

### Formatação de números 

#### Nome da Função

`<span style="color: #ff00ff;"><strong>format</strong></span>(number,format,idioma)`

##### Parâmetro: **number**

Pode ser um número inteiro ou um decimal

##### Parâmetro: **format**

Aqui você passa a formatação que deve ser retornada:

'n0' = retorna o número sem nenhuma casa decimal  
'n1' = retorna o número com 1 casa decimal  
'n2' = retorna o número com 2 casas decimais  
'n3' = retorna o número com 3 casas decimais  
'n4' = retorna o número com 4 casas decimais  
'n5' = retorna o número com 5 casas decimais  
'n6' = retorna o número com 6 casas decimais

##### Parâmetro: **idioma** - **@sysCurrentLanguage**

Aqui você precisa passar o idioma do usuário logado, pois alguns idiomas invertem o . (ponto) e a , (virgula) do número.  
O agilityflow guarda o idioma do usuário dentro da variável <span style="text-decoration: underline;">@sysCurrentLanguage</span> então apenas passe no parâmetro esse variável.

#### Exemplo de utilização

Abaixo o número será formato para 5 casas decimais, no padrão do idioma do usuário logado.

`select FORMAT(5800000.888, 'n5', @sysCurrentLanguage)`

#### Retorno para o usuário que está logado no agilityflow em português ou espanhol

<table aria-describedby="dt_info" cellspacing="0" class="dataTable display no-footer" id="bkmrk-5.800.000%2C88800" role="grid"><tbody><tr class="row-query-result" role="row"><td><span title="5.800.000,88800">5.800.000,88800</span></td></tr></tbody></table>

#### Retorno para o usuário que está logado no agilityflow usando em inglês

<table aria-describedby="dt_info" cellspacing="0" class="dataTable display no-footer" id="bkmrk-5%2C800%2C000.88800" role="grid"><tbody><tr class="row-query-result" role="row"><td><span title="5.800.000,88800">5,800,000.88800</span></td></tr></tbody></table>

### Funções de data no SQL Server

As principais funções para manipular datas são: **GETDATE**, **DATEPART**, **DATEADD** e **DATEDIFF**.

Um detalhe importante é que as funções de data trabalham referenciando unidades de data. As mais comuns são:

- year(ano);
- month(mês);
- day(dia);

### GETDATE ( )

A função **GETDATE** retorna a data e a hora atuais do sistema.

```
SELECT GETDATE()
```

### DATEPART (unidade, data)

A função **DATEPART** retorna a parte especificada de uma data como um inteiro. Observe os exemplos:

```
SELECT DATEPART ( YEAR , '2024-02-01' )
```

Reposta: 2024

```
SELECT DATEPART ( MONTH, '2024-02-01' )
```

Reposta: 2

```
SELECT DATEPART ( DAY, '2024-02-01' )
```

Reposta: 1

### DATEADD (unidade, numero\_unid, data)

A função **DATEADD** retorna uma nova data através da soma do número de unidades especificadas pelo valor *unidade* a uma data. Observe os exemplos:

```
SELECT DATEADD ( DAY ,6, '2024-02-01' )
```

Reposta: 2024-02-07

```
SELECT DATEADD ( MONTH ,6, '2024-02-01' )
```

Reposta: 2024-08-01

```
SELECT DATEADD ( YEAR ,6, '2024-02-01' )
```

Reposta: 2030-02-01

### DATEDIFF (unidade, data1, data2)

A função **DATEDIFF** calcula a diferença entre as datas *data2 e data1*, retornando o resultado como um inteiro, cuja unidade é definida pelo valor *unidade*. Observe os exemplos:

```
SELECT DATEDIFF ( DAY , '2024-02-01' , '2024-05-25' )
```

Reposta: 114 (dias)

```
SELECT DATEDIFF ( MONTH , '2024-02-01' , '2024-05-25' )
```

Reposta: 3 (meses)

```
SELECT DATEDIFF ( YEAR , '2024-02-01' , '2026-05-25' ) )
```

Reposta: 2 (anos)

Sabendo disso, para por exemplo saber o número de dias vivido por você até hoje é:

```SQL
SELECT DATEDIFF(DAY, suadata, GETDATE())
```

**suadata** deve ser substituída pela sua data de nascimento.

Outro exemplo interessante é mostrado através do código SQL abaixo. Usando funções de data, exibimos, para cada cliente, a idade em dias, meses e em anos (idade do cliente na data atual e em 31 de dezembro).

Observe a lógica utilizada no comando **CASE**. Neste caso, é testado se o cliente já fez aniversário, comparando o mês em que ele nasceu com o mês corrente e comparando o dia em que ele nasceu com o dia corrente. Se essa comparação for verdadeira, basta diminuir o ano atual do ano de nascimento do cliente. Caso contrário (o cliente ainda não fez aniversário), temos que diminuir 1 do valor anterior.

```
SELECT NOME, NASCIMENTO,
  DATEDIFF(DAY,NASCIMENTO,GETDATE())AS DIASVIVIDOS,
  DATEDIFF(MONTH,NASCIMENTO,GETDATE()) AS MESESVIVIDOS,
  CASE WHEN
     DATEPART(MONTH,NASCIMENTO)<= DATEPART(MONTH,GETDATE()) AND 
     DATEPART(DAY,NASCIMENTO)<= DATEPART(DAY,GETDATE()) 
  THEN
        (DATEDIFF(YEAR,NASCIMENTO,GETDATE()))
  ELSE
       (DATEDIFF(YEAR,NASCIMENTO,GETDATE()))- 1
       END AS IDADEATUAL,
  DATEDIFF(YEAR,NASCIMENTO,GETDATE())AS IDADE3112
FROM CLIENTE
```

![26-05pic.JPG](https://www.devmedia.com.br/imagens/sqlmagazine/abr2006/26-05pic.JPG)

## Relatório

### Relatório - Filtro

Sempre que um relatório possuir um filtro, é necessário incluir esse filtro na query que gera os dados do relatório.

Não importa como é a query, ela deve incluir a cláusula where, como a chamada da função Filter. Essa função, possui 3 parâmetros:

`<span style="color: #ff00ff;"><strong>Filter</strong> </span>(variável_filtro, tabela, campo)`

- variável\_filtro: é a variável que o agilityflow criou, após a configuração do [filtro](http://wiki.agilityflow.io/link/71#bkmrk-filtro).
- tabela: nome da tabela (definido nos [Dados Técnicos](http://wiki.agilityflow.io/link/21#bkmrk-%E2%A0-5 "Dados Técnicos")) onde se encontra o dado a ser filtrado.
- campo: é o nome do campo (conforme informado no campo Coluna Banco de Dados SQL) onde a informação que o filtro utiliza se encontra.

No exemplo abaixo, a query lista os campos *usu\_nome*, *usu\_email e* *usu\_sexo* da tabela do sistema de usuário (tbl\_usuario) e se inclui a função Filter, usando a variável @sexo aplicada no campo *usu\_sexo*.

```SQL
select usu_nome, usu_email, usu_sexo from tbl_usuario 
where Filter(@sexo, tbl_usuario, usu_sexo) 
```

#### Exemplo de relatório sem filtro

Baseado na query acima, mas sem filtro configurado no relatório.

```SQL
select usu_nome, usu_email, usu_sexo from tbl_usuario 
```

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552917985929.png)

#### Exemplo de relatório com filtro

O mesmo exemplo acima, com o filtro no campo sexo.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552918030578.png)

```
select usu_nome, usu_email, usu_sexo from tbl_usuario 
where Filter(@sexo, tbl_usuario, usu_sexo) 
```

[![relatorio_filtro.gif](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/relatorio_filtro.gif)](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/relatorio_filtro.gif)

Caso seja criado um novo filtro, basta colocar "*and*" depois do primeiro Filter, e colocar o segundo Filter. Não importa a quantidade de filtros, desde que sejam adicionados todos os Filter e os *and*.

```
select usu_nome, usu_email, usu_sexo from tbl_usuario 
where Filter(@sexo, tbl_usuario, usu_sexo) and
      Filter(@nome, tbl_usuario, usu_nome) and
      Filter(@email, tbl_usuario, usu_email)
```

### Relatório - Tabela de Dados

Para as tabelas de dados, existem algumas regrinhas para a customização via Query Sql

1 - Lembre-se de tratar os dados que já foram deletados, usando no where "...deletado = 0.."

2 - **Não** pode conter 'Order by' no select. Essa informação será controlada automaticamente pelo agilityflow e você poderá manipular essa informação na tela de configuração, como na imagem abaixo.

3 - **Não** pode conter o controle de 'Top' no select. Essa informação será controlada automaticamente pelo agilityflow e você poderá manipular essa informação na tela de configuração, como na imagem abaixo.

4 - **Não** pode conter regras de paginação. Essa informação será controlada automaticamente pelo agilityflow e você poderá manipular essa informação na tela de configuração, como na imagem abaixo.

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-04-Apr/scaled-840-0/image-1617637188465.png)

### Relatório - Gráfico

Para gráficos, existem algumas regrinhas para a customização via Query Sql

1 - Lembre-se de tratar os dados que já foram deletados, usando no where "...deletado = 0.."

2 - A query precisa iniciar com 'select **top** ' e o máximo do Top para essa query é <span style="text-decoration: underline;">**100**</span>

3 - Diferentemente da query da tabela de dados, nessa query pode sim conter regras de 'Order by'

### Relatório - Label

Para as labels do relatório, existem algumas regrinhas para a customização via Query Sql

1 - Lembre-se de tratar os dados que já foram deletados, usando no where "...deletado = 0.."

2 - A query precisa iniciar com 'select **top** ' e o máximo do Top para essa query é <span style="text-decoration: underline;">**1**</span>

3 - Diferentemente da query da tabela de dados, nessa query pode sim conter regras de 'Order by'

## Formulário

### Lista Dinâmica - Regras

Os campos que são carregados com Lista dinâmica, podem ser customizados utilizando Query:

**Algumas regras importantes:**  
  
1 - O resultado final da query precisa sempre ser os dados do formulário que você usou como base de dados  
  
2 - Lembre-se de tratar os dados que já foram deletados, usando no where "...deletado = 0.."  
  
3 - A query deve retornar duas colunas com os seguintes *alias*: "Name" e "Value". O "Name" deve ser a mesma coluna definida no campo de apresentação (Nome) e o "Value", deve ser a coluna "id" do formulário definido como base de dados (Cliente). Exemplo:

4 - Na query, o campo de apresentação "Name" pode ser um campo concatenado entre outras colunas.

Exemplo simples:

  
`SELECT Id as Value, [CAMPO_DE_APRESENTACAO] as Name FROM [TABELA] where deletado = 0`

### Report Print - Relatório de Impressão

Para as labels do relatório, existem algumas regrinhas para a customização via Query Sql

Para acessar a customização, clique no botão "Adicionar Outras Fontes de Dados" e selecione o tipo:

1. **Variáveis:** para retornar uma query com apenas 1 linha e várias colunas, cada coluna se torna um campo separado para ser utilizado no relatório
2. **Tabela de Dados:** para retornar uma tabela com diversas colunas e diversas linhas e usa-las em conjunto em uma tabela

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-04-Apr/scaled-840-0/image-1617638740767.png)

**Algumas regras importantes:**

1 - Lembre-se de tratar os dados que já foram deletados, usando no where "...deletado = 0.."

2 - Utilizar no "where" da query, o parâmetro **@formularioid** para filtrar pelo formulário que está sendo solicitada a impressão, caso contrário trará informações de formulários aleatórios.

3 - A query precisa iniciar com 'select **top** ' e o máximo do Top para essa query quando for uma query do tipo:  
\- **Tabela de Dados** é <span style="text-decoration: underline;">**500**</span>,   
\- **Variáveis** é <span style="text-decoration: underline;">**1**</span>

4 - Essa query pode sim conter regras de 'Order by'

# Postgresql (Query) - Dicas e Funções (Versões Mais Recentes do Agilityflow)

<p class="callout warning">**IMPORTANTE**: Essa documentação é referente as versões pós 2023 do agilityflow que utilizam o Banco de Dados **Postgresql.** O agilityflow nas últimas versões está utilizando **POSTGRESQL** .</p>

No agilityflow você pode buscar os dados utilizando SQL, através de queries. As queries devem ser compatíveis com **SQL Server.** Além disso existem alguns padrões que você deve seguir para obter um melhor resultado no agilityflow. Abaixo estão alguns detalhes importantes.

### Tratamento de Registros Deletados

<p class="callout danger">**IMPORTANTE:**   
É de extrema importância o tratamento de registros deletados, usando as regras abaixo.   
  
Já está no nosso Roadmap o tratamento automático dos deletados, enquanto isso, o tratamento se torna obrigatório pelo desenvolvedor.</p>

Para manter a integridade dos dados, o agilityflow nunca apaga um registro de uma tabela. Apenas o marca como deletado. Portanto, para qualquer query, é preciso excluir os deletados da lista.

Essa marcação é feita com campo deletado. Se o valor for **FALSE**, significa que ele não foi deletado e está visível no sistema. Caso esteja **TRUE**, significa que o registro já foi excluído e não é possível mais vê-lo na listagem principal do sistema.

**Exemplo 1, sem o tratamento de deletados:**

```SQL
select usu_nome, usu_email from tbl_usuario
```

**Resultado**:

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552935887749.png)

**Exemplo 2, com o tratamento de deletados:**

```SQL
select usu_nome, usu_email from tbl_usuario
where deletado = false
```

**Resultado**:

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552935923310.png)

### Campo do tipo Date, Timestamp e Datetime (Data e Hora)

Sempre que um campo de texto com máscara do tipo data é criado, o sistema cria uma cópia com o mesmo nome seguido de "<span style="color: #ff6600;">**\_\_datetime\_\_**</span>" essa informação é gravada em uma coluna no banco de dados do tipo **"<span style="text-decoration: underline;">date"</span>** quando for uma coluna sem hora ou "<span style="text-decoration: underline;">timestamp without time zone"</span>** quando for uma coluna com hora<span style="text-decoration: underline;"> </span>, ao invés de varchar. Esses campos são criados para facilitar o uso tipado do dado nas queries

#### **Exemplo de campo Datetime**

Por exemplo, se o campo se chama "data\_e\_hora", haverá um outro chamado "data\_e\_hora\_\_datetime\_\_" e o conteúdo estará no formato padrão do sql server, **YYYY-MM-DD hh:mm:ss**

O campo "data\_e\_hora" estará sempre como varchar e o "data\_e\_hora\_\_datetime\_\_" estará como timestamp

**data\_e\_hora | data\_e\_hora\_\_datetime\_\_**

2027-01-31 23:5959 2027-01-31 23:5959   
2027-01-31 23:5959 2027-01-31 23:5959   
2027-01-31 23:5959 2027-01-31 23:5959

### Campo do tipo Numérico (decimal, float, double, int, number)

Sempre que um campo de texto com máscara do tipo número é criado, o sistema cria uma cópia com o mesmo nome seguido de "<span style="color: #ff6600;">**\_\_number\_\_**</span>" essa informação é gravada em uma coluna no banco de dados do tipo **<span style="text-decoration: underline;">numeric(18,6)</span>,** ao invés de varchar. Esses campos são criados para facilitar o uso tipado do dado nas queries

#### **Exemplo de campo numérico**

Por exemplo, se o campo se chama "numero\_exemplo", haverá um outro chamado "numero\_exemplo\_\_number\_\_" e o conteúdo estará no formato padrão do sql server.

O campo "numero\_exemplo" estará sempre como varchar e o "numero\_exemplo\_\_number\_\_" estará como numeric(18,6)

**numero\_exemplo | numero\_exemplo\_\_number\_\_**

999.99 999.99   
123.89 123.89

### Formatação de números 

#### Nome da Função

`<span style="color: #ff00ff;"><strong>format_number</strong></span>(number,format,idioma)`

##### Parâmetro: **number**

Pode ser um número inteiro ou um decimal

##### Parâmetro: **format**

Aqui você passa a formatação que deve ser retornada:

'0' = retorna o número sem nenhuma casa decimal  
'1' = retorna o número com 1 casa decimal  
'2' = retorna o número com 2 casas decimais  
'3' = retorna o número com 3 casas decimais  
'4' = retorna o número com 4 casas decimais  
'5' = retorna o número com 5 casas decimais  
'6' = retorna o número com 6 casas decimais

##### Parâmetro: **idioma** - **@sysCurrentLanguage**

Aqui você precisa passar o idioma do usuário logado, pois alguns idiomas invertem o . (ponto) e a , (virgula) do número.  
O agilityflow guarda o idioma do usuário dentro da variável <span style="text-decoration: underline;">@sysCurrentLanguage</span> então apenas passe no parâmetro esse variável.

#### Exemplo de utilização

Abaixo o número será formato para 5 casas decimais, no padrão do idioma do usuário logado.

`select format_number(5800000.888, '5', @sysCurrentLanguage)`

#### Retorno para o usuário que está logado no agilityflow em português ou espanhol

<table aria-describedby="dt_info" cellspacing="0" class="dataTable display no-footer" id="bkmrk-5.800.000%2C88800" role="grid"><tbody><tr class="row-query-result" role="row"><td><span title="5.800.000,88800">5.800.000,88800</span></td></tr></tbody></table>

#### Retorno para o usuário que está logado no agilityflow usando em inglês

<table aria-describedby="dt_info" cellspacing="0" class="dataTable display no-footer" id="bkmrk-5%2C800%2C000.88800" role="grid"><tbody><tr class="row-query-result" role="row"><td><span title="5.800.000,88800">5,800,000.88800</span></td></tr></tbody></table>

### Funções de data no Postgresql

As principais funções para manipular datas são: **GETDATE**, **DATEPART**, **DATEADD** e **DATEDIFF**.

Um detalhe importante é que as funções de data trabalham referenciando unidades de data. As mais comuns são:

- year(ano);
- month(mês);
- day(dia);

### CURRENT\_TIMESTAMP)

A função CURRENT\_TIMESTAMP retorna a data e a hora atuais do sistema.

```
SELECT CURRENT_TIMESTAMP
```

### Extrair parte de uma data

A função EXTRACT retorna a parte especificada de uma data como um inteiro. Observe os exemplos:

```
SELECT EXTRACT(YEAR FROM '2024-02-01'::DATE)
```

Reposta: 2024

```
SELECT EXTRACT(MONTH FROM '2024-02-01'::DATE)
```

Reposta: 2

```
SELECT EXTRACT(DAY FROM '2024-02-01'::DATE)
```

Reposta: 1

### Adicionar dias em uma data

A função **abaixo** retorna uma nova data através da soma do número de unidades especificadas pelo valor *unidade* a uma data. Observe os exemplos:

```
SELECT '2024-02-01'::DATE + INTERVAL '7 days';
```

Reposta: 2024-02-07

### Calcular a diferença entre datas (date diff)

A função **abaixo** calcula a diferença entre as datas *data2 e data1*, retornando o resultado como um inteiro, cuja unidade é definida pelo valor *unidade*. Observe os exemplos:

```
SELECT EXTRACT(DAY FROM '2024-02-01'::DATE - '2023-10-10'::DATE);
```

Reposta: 114 (dias)

### Cálculo de idade em anos, meses e dias

```SQL
SELECT DATE_PART('year', AGE(NOW(), '1990-05-15')) AS idade_anos;
```


## Relatório

### Como fazer Filtro nos Relatórios? 

Sempre que um relatório possuir um filtro, é necessário incluir esse filtro na query que gera os dados do relatório.

Não importa como é a query, ela deve incluir a cláusula where, como a chamada da função Filter. Essa função, possui 3 parâmetros:

`<span style="color: #ff00ff;"><strong>Filter</strong> </span>(variável_filtro, tabela, campo)`

- variável\_filtro: é a variável que o agilityflow criou, após a configuração do [filtro](http://wiki.agilityflow.io/link/71#bkmrk-filtro).
- tabela: nome da tabela (definido nos [Dados Técnicos](http://wiki.agilityflow.io/link/21#bkmrk-%E2%A0-5 "Dados Técnicos")) onde se encontra o dado a ser filtrado.
- campo: é o nome do campo (conforme informado no campo Coluna Banco de Dados SQL) onde a informação que o filtro utiliza se encontra.

No exemplo abaixo, a query lista os campos *usu\_nome*, *usu\_email e* *usu\_sexo* da tabela do sistema de usuário (tbl\_usuario) e se inclui a função Filter, usando a variável @sexo aplicada no campo *usu\_sexo*.

```SQL
select usu_nome, usu_email, usu_sexo from tbl_usuario 
where Filter(@sexo, tbl_usuario, usu_sexo) 
```

#### Exemplo de relatório sem filtro

Baseado na query acima, mas sem filtro configurado no relatório.

```SQL
select usu_nome, usu_email, usu_sexo from tbl_usuario 
```

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552917985929.png)

#### Exemplo de relatório com filtro

O mesmo exemplo acima, com o filtro no campo sexo.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/scaled-840-0/image-1552918030578.png)

```
select usu_nome, usu_email, usu_sexo from tbl_usuario 
where Filter(@sexo, tbl_usuario, usu_sexo) 
```

[![relatorio_filtro.gif](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/relatorio_filtro.gif)](http://wiki.agilityflow.io/uploads/images/gallery/2019-03-Mar/relatorio_filtro.gif)

Caso seja criado um novo filtro, basta colocar "*and*" depois do primeiro Filter, e colocar o segundo Filter. Não importa a quantidade de filtros, desde que sejam adicionados todos os Filter e os *and*.

```
select usu_nome, usu_email, usu_sexo from tbl_usuario 
where Filter(@sexo, tbl_usuario, usu_sexo) and
      Filter(@nome, tbl_usuario, usu_nome) and
      Filter(@email, tbl_usuario, usu_email)
```

### Relatório - Tabela de Dados

Para as tabelas de dados, existem algumas regrinhas para a customização via Query Sql

1 - Lembre-se de tratar os dados que já foram deletados, usando no where "...deletado = false.."

2 - **Não** pode conter 'Order by' no select. Essa informação será controlada automaticamente pelo agilityflow e você poderá manipular essa informação na tela de configuração, como na imagem abaixo.

3 - **Não** pode conter o controle de 'Limit' no select. Essa informação será controlada automaticamente pelo agilityflow e você poderá manipular essa informação na tela de configuração, como na imagem abaixo.

4 - **Não** pode conter regras de paginação. Essa informação será controlada automaticamente pelo agilityflow e você poderá manipular essa informação na tela de configuração, como na imagem abaixo.

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-04-Apr/scaled-840-0/image-1617637188465.png)

### Relatório - Gráfico

Para gráficos, existem algumas regrinhas para a customização via Query Sql

1 - Lembre-se de tratar os dados que já foram deletados, usando no where "...deletado = false.."

2 - A query precisa conter '**limit** ' e o máximo do limit para essa query é <span style="text-decoration: underline;">**100**</span>

3 - Diferentemente da query da tabela de dados, nessa query pode sim conter regras de 'Order by'

### Relatório - Label

Para as labels do relatório, existem algumas regrinhas para a customização via Query Sql

1 - Lembre-se de tratar os dados que já foram deletados, usando no where "...deletado = false.."

2 - A query precisa conter '**limit** ' e o máximo do limit para essa query é <span style="text-decoration: underline;">**1**</span>

3 - Diferentemente da query da tabela de dados, nessa query pode sim conter regras de 'Order by'

## Formulário

### Lista Dinâmica - Regras

Os campos que são carregados com Lista dinâmica, podem ser customizados utilizando Query:

**Algumas regras importantes:**  
  
1 - O resultado final da query precisa sempre ser os dados do formulário que você usou como base de dados  
  
2 - Lembre-se de tratar os dados que já foram deletados, usando no where "...deletado = false.."  
  
3 - A query deve retornar duas colunas com os seguintes *alias*: "Name" e "Value". O "Name" deve ser a mesma coluna definida no campo de apresentação (Nome) e o "Value", deve ser a coluna "id" do formulário definido como base de dados (Cliente). Exemplo:

4 - Na query, o campo de apresentação "Name" pode ser um campo concatenado entre outras colunas.

Exemplo simples:

  
`SELECT Id as Value, CAMPO_DE_APRESENTACAO as Name FROM [TABELA] where deletado = false`

### Report Print - Relatório de Impressão

Para as labels do relatório, existem algumas regrinhas para a customização via Query Sql

Para acessar a customização, clique no botão "Adicionar Outras Fontes de Dados" e selecione o tipo:

1. **Variáveis:** para retornar uma query com apenas 1 linha e várias colunas, cada coluna se torna um campo separado para ser utilizado no relatório
2. **Tabela de Dados:** para retornar uma tabela com diversas colunas e diversas linhas e usa-las em conjunto em uma tabela

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-04-Apr/scaled-840-0/image-1617638740767.png)

**Algumas regras importantes:**

1 - Lembre-se de tratar os dados que já foram deletados, usando no where "...deletado = false.."

2 - Utilizar no "where" da query, o parâmetro **@formularioid** para filtrar pelo formulário que está sendo solicitada a impressão, caso contrário trará informações de formulários aleatórios.

3 - A query precisa conter '**limit** ' e o máximo do limit para essa query quando for uma query do tipo:  
\- **Tabela de Dados** é <span style="text-decoration: underline;">**500**</span>,   
\- **Variáveis** é <span style="text-decoration: underline;">**1**</span>

4 - Essa query pode sim conter regras de 'Order by'

# Programação em Html

Para acessar os detalhes desse conteúdo, [clique aqui](http://wiki.agilityflow.io/link/78#bkmrk-page-title).

# Programação em CSS

Para acessar os detalhes desse conteúdo, [clique aqui](http://wiki.agilityflow.io/link/78#bkmrk-page-title).

# Programação em Javascript

Para acessar os detalhes desse conteúdo, [clique aqui](http://wiki.agilityflow.io/link/78#bkmrk-page-title).

# Programação em C# - Na Regra de Negócio

<p class="callout danger">IMPORTANTE: as variáveis e métodos descritos aqui só funcionarão na programação C# na **Regra de Negócio** do formulário. Para a programação C# nas **APIs** [clique aqui.](https://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/programa%C3%A7%C3%A3o-em-c---na-api-de-integra%C3%A7%C3%A3o "Programação em C# - Na API de integração")</p>

O agilityflow permite a customização em C#, além de já disponibilizar diversas bibliotecas e funções para facilitar sua programação, incluindo acesso a dados, validações, envio de e-mail, notificação, entre outras.

Abaixo mostramos alguns exemplos, se o material abaixo não for suficiente , entre em contato com nossa equipe.

##### C# - Propriedades

<table border="1" id="bkmrk-vari%E3%A1vel-tipo-%E2%A0-fo" style="border-collapse: collapse; width: 150.864%; height: 540px;"><tbody><tr style="height: 31px;"><td style="width: 35.1824%; height: 31px;">**Variável**</td><td style="width: 34.3841%; height: 31px;">**Tipo**</td><td style="width: 81.2977%; height: 31px;"> </td></tr><tr style="height: 94px;"><td style="width: 35.1824%; height: 41px;">IsNovoFormulario</td><td style="width: 34.3841%; height: 41px;">bool</td><td style="width: 81.2977%; height: 41px;">retorna true, caso seja um novo formulário, e false caso contrário.</td></tr><tr style="height: 147px;"><td style="width: 35.1824%; height: 28px;">IdFormulario</td><td style="width: 34.3841%; height: 28px;"><span class="csharp_custom_class_var">Guid</span> </td><td style="width: 81.2977%; height: 28px;">retorna o ID do formulário

</td></tr><tr style="height: 400px;"><td style="width: 35.1824%; height: 400px;">CurrentStatusFluxo</td><td style="width: 34.3841%; height: 400px;"><span class="csharp_custom_class_var">StatusFluxo? (<span style="color: #999999;">Enum</span>)</span></td><td style="width: 81.2977%; height: 400px;">Variável disponível apenas para <span style="text-decoration: underline;">Workflow</span>

Nessa ENUM será retornado o Status do fluxo.

As opções podem ser:

- **StatusFluxo.Pendente -** Enquanto o fluxo ainda estiver pendente em alguma das etapas.
- **StatusFluxo.Aprovado -** Depois do fluxo encerrado e completamente aprovado
- **StatusFluxo.Reprovado -** Depois do fluxo encerrado e completamente reprovado

Exemplo de utilização:

`<span style="color: #0000ff;">if</span>(CurrentStatusFluxo == <span style="color: #00ccff;">StatusFluxo</span>.Aprovado){    <span style="color: #339966;">//restante do código</span>}`

</td></tr><tr style="height: 31px;"><td style="width: 35.1824%; height: 40px;"><span style="color: #ff00ff;">(**deprecated)**</span>

<span style="text-decoration: line-through;"><span style="color: #999999; text-decoration: line-through;">FormularioCamposPreenchidos</span></span>

</td><td style="width: 34.3841%; height: 40px;"><span style="color: #ff00ff;">(**deprecated)**</span>

<span style="text-decoration: line-through;"><span style="color: #999999; text-decoration: line-through;">dynamic (Json)</span></span>

</td><td style="width: 81.2977%; height: 40px;"><span style="color: #ff00ff;">(**deprecated**: utilizar o método FormContext.GetValue descrito mais abaixo)</span>

retorna um json com os campos do preenchidos no formulário, exemplo:

{

 "campo1": "xxxxx",

 "campo2": "yyyyy",

 "campo3": "zzzzz",

}

Para resgatar a informação do campo1, utilize:

`<span style="color: #3366ff;">var</span> campo1 = FormularioCamposPreenchidos[<span style="color: #993300;">"campo1"</span>];`

</td></tr></tbody></table>

##### C# - Buscar e preencher valor de um campo

<table border="1" id="bkmrk-op%E3%A7%E3%A3o-retorno-%E2%A0-g" style="border-collapse: collapse; width: 119.753%; height: 942px;"><tbody><tr style="height: 31px;"><td style="width: 61.7256%; height: 31px;">**Método**</td><td style="width: 12.0385%; height: 31px;">**Retorno**</td><td style="width: 51.2976%; height: 31px;"> </td></tr><tr><td style="width: 61.7256%;">**FormContext.SetValue(**string idCampo, string value)

</td><td style="width: 12.0385%;">void</td><td style="width: 51.2976%;">Esse método preencherá um campo com um novo **Valor** (passado por paramêtro)

Para valores que são **Datas**, utilizar o padrão dd/MM/aaaa HH:mm:ss:

Exemplo:<span style="text-decoration: underline;"> ***31/12/2010 22:55***</span>

```C#
var data_e_hora = "31/01/2023 22:55";
FormContext.SetValue("data_e_hora",data_e_hora);
```

Para valores **Numéricos**, o número deve estar no formato com ponto no separador decimal e sem utilização de virgulas.

Exemplo para 2 milhões e 50 centavos**:**

<span style="text-decoration: underline;">***2000000.50***</span>

```
<strong><code class="language-C#">var moeda = "2000000.50";
FormContext.SetValue("moeda",moeda);</code></strong>
```

[Veja exemplo](https://wiki.agilityflow.io/link/82#bkmrk-atualizar-um-outro-f)

</td></tr><tr style="height: 94px;"><td style="width: 61.7256%; height: 94px;">**FormContext**.**GetValue**(string idCampo)</td><td style="width: 12.0385%; height: 94px;">string</td><td style="width: 51.2976%; height: 94px;">Esse método retornará o **Valor** de um determinado campo

</td></tr><tr style="height: 147px;"><td style="width: 61.7256%; height: 147px;">**FormContext.GetText(**string idCampo**)**</td><td style="width: 12.0385%; height: 147px;">string</td><td style="width: 51.2976%; height: 147px;">Esse método retornará o **Texto** de um determinado campo, utilizado apenas se o campo for um campo de **lista dinâmica**, exemplo: Combo, Auto complete, Campo de Múltipla escolha, radio etc.

[Veja exemplo](#bkmrk-para-recuperar-o-tex)

</td></tr><tr><td style="width: 61.7256%;">**FormContext.GetInt**(string idColuna)  
</td><td style="width: 12.0385%;">int?</td><td style="width: 51.2976%;">Retorna o valor da coluna no tipo INT (inteiro), caso esse campo no formulário seja um número, se o valor for 10.000,99

Será retornado: 10000

[Veja exemplo](https://wiki.agilityflow.io/link/82#bkmrk-atualizar-um-outro-f)

</td></tr><tr><td style="width: 61.7256%;">**FormContext.GetDecimal**(string idColuna)</td><td style="width: 12.0385%;">decimal?</td><td style="width: 51.2976%;">Retorna o valor da coluna no tipo Decimal, caso esse campo no formulário seja um número, se o valor for 10.000,99

Será retornado: 10000.99

[Veja exemplo](https://wiki.agilityflow.io/link/82#bkmrk-atualizar-um-outro-f)

</td></tr><tr><td style="width: 61.7256%;">**FormContext.GetDateTime**(string idColuna)</td><td style="width: 12.0385%;">DateTime?</td><td style="width: 51.2976%;">Retorna o valor da coluna no tipo DateTime para valores que estão no formato de data dd/MM/yyyy ou dd/MM/yyyy hh:mm

[Veja exemplo](https://wiki.agilityflow.io/link/82#bkmrk-atualizar-um-outro-f)

</td></tr></tbody></table>

##### C# - Buscar Rascunho por Id

<table border="1" id="bkmrk-m%E3%A9todo-retorno-%E2%A0-f" style="border-collapse: collapse;"><tbody><tr style="height: 31px;"><td style="width: 61.7256%; height: 31px;">**Método**</td><td style="width: 14.0138%; height: 31px;">**Retorno**</td><td style="width: 44.0137%; height: 31px;"> </td></tr><tr style="height: 31px;"><td style="width: 61.7256%; height: 31px;">**FormContext**.**GetDrafJsontById**(string draftid)  
ou

**FormContext**.**GetDrafJsontById**(Guid?draftid)

</td><td style="width: 14.0138%; height: 31px;">dynamic</td><td style="width: 44.0137%; height: 31px;">```
`var str_preco_de_venda = "";var str_quantidade = "";var temRascunho = false;var rascunho_json = PageContext.GetDraftJsontById(str_draftid);if(rascunho_json != null){	temRascunho = true;	str_preco_de_venda = rascunho_json.preco_de_venda;	str_quantidade = rascunho_json.quantidade;}`
```

</td></tr></tbody></table>

##### C# - Executar uma consulta SQL (Query SQL)

<table border="1" id="bkmrk-m%E3%A9todo-retorno-%E2%A0-f-0" style="border-collapse: collapse;"><tbody><tr style="height: 31px;"><td style="width: 61.7256%; height: 31px;">**Método**</td><td style="width: 14.0138%; height: 31px;">**Retorno**</td><td style="width: 44.0137%; height: 31px;"> </td></tr><tr style="height: 31px;"><td style="width: 61.7256%; height: 31px;">**await FormContext**.**GetDataTableAsync**(string sql, params DbParameter\[\] parameters)</td><td style="width: 14.0138%; height: 31px;">DataTable</td><td style="width: 44.0137%; height: 31px;">Permite retornar informações dos bancos de dados através de uma query.

[Veja exemplo](#bkmrk-recuperando-dados-do "Veja exemplo")

</td></tr></tbody></table>


##### C# - Inserir (salvar/criar), alterar, deletar e aprovar outros formulários

<table border="1" id="bkmrk-m%E3%A9todo-retorno-%E2%A0-f-1" style="border-collapse: collapse; width: 119.753%; height: 942px;"><tbody><tr style="height: 31px;"><td style="width: 61.7256%; height: 31px;">**Método**</td><td style="width: 14.0138%; height: 31px;">**Retorno**</td><td style="width: 44.0137%; height: 31px;"> </td></tr><tr><td style="width: 61.7256%;">**await FormContext.SaveEntityAsync**(Guid estruturaformularioid\_ASerCriadoOuAtualizado, DataDictionary campos\_e\_valores)</td><td style="width: 14.0138%;">Guid</td><td style="width: 44.0137%;">Salva (Insere e Atualiza) as informações de um formulário no bancos de dados.

Para atualizar um registro, no parâmetro **campos\_e\_valores**, apenas adicione um parâmetro chamado "**id**" com o id do elemento que você deseja atualizar.

Obs: Para cadastrar valores numéricos, o números devem estar no formato com ponto no separador decimal: 999999.99 sem utilização de virgulas.

[Veja exemplo](https://wiki.agilityflow.io/link/82#bkmrk-salvando-os-dados-re "Veja exemplo")

</td></tr><tr><td style="width: 61.7256%;">**await FormContext.ApproveEntityAsync(**Guid estruturaformularioid\_ASerAprovado, DataDictionary campos\_e\_valores)</td><td style="width: 14.0138%;">Guid</td><td style="width: 44.0137%;">Avança uma etapa em um formulário com Workflow.

As regras de usuário aprovador, permissão de aprovação e responsabilidade por uma etapa devem ser validadas antes desse método ser executado.

Obs: Para cadastrar valores numéricos, o números devem estar no formato com ponto no separador decimal: 999999.99 sem utilização de virgulas.

[Veja exemplo](https://wiki.agilityflow.io/link/82#bkmrk-aprovando-uma-etapa-)

</td></tr><tr><td style="width: 61.7256%;">**await FormContext.DeleteEntityAsync(Guid formularioid)**</td><td style="width: 14.0138%;">void</td><td style="width: 44.0137%;">Deletar um um registro

</td></tr></tbody></table>

##### C# - Apresentar mensagem para o usuário

<table border="1" id="bkmrk-m%E3%A9todo-retorno-%E2%A0-f-2" style="border-collapse: collapse; width: 119.753%; height: 942px;"><tbody><tr style="height: 31px;"><td style="width: 61.7256%; height: 31px;">**Método**</td><td style="width: 14.0138%; height: 31px;">**Retorno**</td><td style="width: 44.0137%; height: 31px;"> </td></tr><tr style="height: 59px;"><td style="width: 61.7256%; height: 59px;">**FormContext.WarningMessage**(string message)

</td><td style="width: 14.0138%; height: 59px;">void</td><td style="width: 44.0137%; height: 59px;">Apresenta um aviso para o usuário

[veja detalhes aqui](https://wiki.agilityflow.io/link/82#bkmrk-a-execu%E3%A7%E3%A3o-do-c%E3%B3d)

</td></tr></tbody></table>

##### C# - Buscar informações do usuário logado

<table border="1" id="bkmrk-m%E3%A9todo-retorno-%E2%A0-f-3" style="border-collapse: collapse; width: 119.753%; height: 193px;"><tbody><tr style="height: 31px;"><td style="width: 61.7256%; height: 31px;">**Método**</td><td style="width: 14.0138%; height: 31px;">**Retorno**</td><td style="width: 44.0137%; height: 31px;"> </td></tr><tr style="height: 29px;"><td style="width: 61.7256%; height: 29px;">**FormContext.**GetUsuarioLogadoNome();  
</td><td style="width: 14.0138%; height: 29px;">string</td><td style="width: 44.0137%; height: 29px;">Nome Completo do usuário logado</td></tr><tr style="height: 29px;"><td style="width: 61.7256%; height: 29px;">**FormContext.**GetUsuarioLogadoPrimeiroNome();</td><td style="width: 14.0138%; height: 29px;">string</td><td style="width: 44.0137%; height: 29px;">Primeiro nome do usuário logado</td></tr><tr style="height: 46px;"><td style="width: 61.7256%; height: 46px;">**FormContext.**GetUsuarioLogadoPrimeiroESegundoNome();</td><td style="width: 14.0138%; height: 46px;">string</td><td style="width: 44.0137%; height: 46px;">Primeiro e Segundo nome do usuário logado</td></tr><tr style="height: 29px;"><td style="width: 61.7256%; height: 29px;">**FormContext.**GetUsuarioLogadoEmail();</td><td style="width: 14.0138%; height: 29px;">string</td><td style="width: 44.0137%; height: 29px;">E-mail do usuário logado</td></tr><tr style="height: 29px;"><td style="width: 61.7256%; height: 29px;">**FormContext.**GetUsuarioLogadoId();</td><td style="width: 14.0138%; height: 29px;">Guid</td><td style="width: 44.0137%; height: 29px;">Id do usuário logado</td></tr></tbody></table>

##### C# - Buscar variáveis de ambiente

<table border="1" id="bkmrk-m%E3%A9todo-retorno-%E2%A0-f-4" style="border-collapse: collapse; width: 119.753%; height: 942px;"><tbody><tr style="height: 31px;"><td style="width: 61.7256%; height: 31px;">**Método**</td><td style="width: 14.0138%; height: 31px;">**Retorno**</td><td style="width: 44.0137%; height: 31px;"> </td></tr><tr style="height: 153px;"><td style="width: 61.7256%; height: 153px;">**FormContext.GetEnvironmentVariable**(string nomeVariavel)

ou

**FormContext.GetEnvironmentVariable\_Text**(string nomeVariavel) \*\*

</td><td style="width: 14.0138%; height: 153px;">string</td><td style="width: 44.0137%; height: 153px;">Recupera o Valor de uma variável de ambiente.

\*\* Recupera a Descrição (texto), no caso de variáveis do Tipo "Query com Id + Descrição":

</td></tr></tbody></table>

##### C# - Formatação Numérica

<p class="callout info">***Se você está utilizando o método GetValue(..) para buscar o valor de um campo numérico, esse método já retornará o número formatado e não será necessário nenhuma formatação adicional.  
  
Se você está utilizando o método GetDecimal(..) ele não virá formatado pois ele retorna o tipo DECIMAL do C#, sendo assim, se você precisa do dado formatado você pode utilizar o GetText(..)***</p>

<table border="1" id="bkmrk-string-formatdecimal"><tbody><tr><td>string **FormContext.FormatDecimalToString**(object numDecimal, string mascaraTipo = "dec2")</td><td>formata object 999999999.55 para o formato da mascara de acordo com o idioma.

\- se for ingles, será 999,999,999.55  
\- se for portugues, será 999.999.999,55

</td></tr><tr><td>string **FormContext.FormatNumberToString\_EnglishFormat**(object num, \[optional\]int? qtdCasasDecimais)</td><td>converte decimal para string, porém sempre a string vem no formato Inglês.

coloca a a mesma qtd de casas decimais, caso o parâmetro qtdCasasDecimais estivar em branco

</td></tr></tbody></table>

##### C# - Gerar log

<table border="1" id="bkmrk-m%E3%A9todo-retorno-%E2%A0-f-5" style="border-collapse: collapse; width: 119.753%; height: 942px;"><tbody><tr style="height: 31px;"><td style="width: 61.7256%; height: 31px;">**Método**</td><td style="width: 14.0138%; height: 31px;">**Retorno**</td><td style="width: 44.0137%; height: 31px;"> </td></tr><tr style="height: 130px;"><td style="width: 61.7256%; height: 130px;">**FormContext.Log**(string log, string logTipo)

</td><td style="width: 14.0138%; height: 130px;">void</td><td style="width: 44.0137%; height: 130px;">Cria um log na tabela de log geral, o log pode ser consultado entrando na Área de Customização e clicando na opção "Log Geral &gt;&gt; consultar Log"

</td></tr></tbody></table>

##### C# - Métodos Úteis

<table border="1" id="bkmrk-m%E3%A9todo-retorno-%E2%A0-f-6" style="border-collapse: collapse; width: 119.753%; height: 942px;"><tbody><tr style="height: 31px;"><td style="width: 61.7256%; height: 31px;">**Método**</td><td style="width: 14.0138%; height: 31px;">**Retorno**</td><td style="width: 44.0137%; height: 31px;"> </td></tr><tr style="height: 177px;"><td style="width: 61.7256%; height: 177px;">**FormContext.GetUrlBase()**  
</td><td style="width: 14.0138%; height: 177px;"> </td><td style="width: 44.0137%; height: 177px;">Retorna a URL base da sua aplicação

exemplo:

[https://suaempresa.agilityflow.io/](https://suaempresa.agilityflow.io/)

\*A url sempre virá com uma barra no final **/**

</td></tr></tbody></table>

#### Método principal para utilização da Programação em C# na opção "Regra de Negócio"

A única regra é que o método se chame Execute, não tenha parâmetros de entrada e o retorno seja void.

Exemplo:

```C#
public void Execute(){            



  //aqui você pode programar   



}

  //aqui você pode programar outros métodos
```

#### Exemplos

##### Recuperando dados do banco de dados através de uma query SQL

```C#
//parametros da query
var paramsQuery = new List<NpgsqlParameter>();
paramsQuery.Add(new NpgsqlParameter("@param1", "xxx"));
paramsQuery.Add(new NpgsqlParameter("@param2", "yyy"));
paramsQuery.Add(new NpgsqlParameter("@param3", "zzz"));

//query usando (nolock) nas tabelas para evitar problema com a transação que está ativa
var sql = "select column1,column2,column3 from table (nolock) where column1 = @param1 or  column2 = @param2 or  column3 = @param3 ";

//executar no banco de dados
var dt = await FormContext.GetDataTableAsync(sql, paramsQuery.ToArray());

//percorrendo as linhas de retorno da tabela
foreach (DataRow dr in dt.Rows)
{
  if (dr["column1"] != DBNull.Value)
  	FormContext.WarningMessage(dr["column1"].ToString());
}
```

##### Modificando os campos do próprio formulário que está sendo salvo

```C#
//concatenando o texto "abcdef" ao campo de texto chamado "texto_simples" 
var texto_simples = FormContext.GetValueField("texto_simples");
texto_simples += " abcdef ";
FormContext.SetValue("texto_simples",texto_simples);

//colocando uma data fixa em um campo de data chamado "data_e_hora" 
var data_e_hora = "31/01/2023 22:55";
FormContext.SetValue("data_e_hora",data_e_hora);


//colocando um valor decimal fixo em um campo de data chamado "moeda" 
var moeda = "2000000.50";
FormContext.SetValue("moeda",moeda);



//somando 200 dias a um campo de data chamado "data_e_hora_2" 
var dt_data_e_hora = FormContext.GetDateTime("data_e_hora_2");
if(dt_data_e_hora != null){
  var nova_data = dt_data_e_hora.Value.AddDays(200);
  FormContext.SetValue("data_e_hora_2", nova_data);
}

//somando 900.12 a um campo de moeda chamado "moeda2" 
var num_moeda = FormContext.GetDecimal("moeda2");
if(num_moeda != null){
  var novo_valor = num_moeda.Value + 9000000.12m;

  FormContext.SetValue("moeda2",novo_valor);
}
```

##### Salvando/Criar um outro formulário através do método SaveEntityAsync

\* Para cadastrar valores numéricos, o números devem estar no formato com ponto no separador decimal: 999999.99 sem utilização de virgulas.

```C#
//guarda em uma variável o ID da  E S T R U T U R A  do formulário de pessoa
var idEstruturaFormulario_PESSOA = Guid.Parse("0b56b66a-4f6f-4ded-ad04-016d7c0724e1");

var values = new DataDictionary();
values.Add("nome", FormContext.GetValue("nome"));
values.Add("email", FormContext.GetValue("email"));


//salva a informação no banco de dados
await FormContext.SaveEntityAsync(idEstruturaFormulario_PESSOA, values);

```

##### Atualizar um outro formulário através do método SaveEntityAsync

\* Para cadastrar valores numéricos, o números devem estar no formato com ponto no separador decimal: 999999.99 sem utilização de virgulas.

```C#
//guarda em uma variável o ID da  E S T R U T U R A  do formulário de pessoa
var idEstruturaFormulario_PESSOA = Guid.Parse("0b56b66a-4f6f-4ded-ad04-016d7c0724e1");

var values = new DataDictionary();
values.Add("id", "33f6bdf8-26d9-42b9-94ae-ad44c62725b5"); //insere aqui o ID do registro que você deseja atualizar
values.Add("nome", FormContext.GetValue("nome"));
values.Add("email", FormContext.GetValue("email"));


//salva a informação no banco de dados
await FormContext.SaveEntityAsync(idEstruturaFormulario_PESSOA, values);

```

<p class="callout warning">Caso você queira atualizar informações do próprio formulário que está sendo salvo, utilize a função SetValue, descrita mais acima nos métodos da Classe FormContext</p>

##### Aprovar um outro formulário através do método ApproveEntityAsync

\* Para cadastrar valores numéricos, o números devem estar no formato com ponto no separador decimal: 999999.99 sem utilização de virgulas.

```C#
//guarda em uma variável o ID da  E S T R U T U R A  do formulário de pessoa
var idEstruturaFormulario_PESSOA = Guid.Parse("0b56b66a-4f6f-4ded-ad04-016d7c0724e1");

var values = new DataDictionary();
values.Add("nome", FormContext.GetValue("nome"));
values.Add("email", FormContext.GetValue("email"));



//salva a informação no banco de dados
await FormContext.ApproveEntityAsync(idEstruturaFormulario_PESSOA, values);

```

##### Salvando um outro formulário com Tabela Associativa através do método SaveEntityAsync

\* Para cadastrar valores numéricos, o números devem estar no formato com ponto no separador decimal: 999999.99 sem utilização de virgulas.

```C#
//guarda em uma variável o ID da  E S T R U T U R A  do formulário de pessoa
var idEstruturaFormulario_PESSOA = Guid.Parse("0b56b66a-4f6f-4ded-ad04-016d7c0724e1");

var values = new DataDictionary();
values.Add("nome", json["nome"].ToString());
values.Add("email", json["email"].ToString());


        //no caso do campo do formulário ser uma tabela associativa (tabela relacional N:N)
        var idCampoTabelaAssociativa = "70b6f362-2587-4fd2-a2fb-148bd0caf437";

        //itens da tabela associativa que serão adicionados
        var idItem1 = "51cf02f1-3787-4dca-8a2c-e219a5ce1298";
        var idItem2 = "f999f103-c775-4245-92d3-034cb3ded5e4";                          
        var idItem3 = "XXXXf103-c775-4245-92d3-034cb3ded5e4";                          
        var idItem4 = "YYYYf103-c775-4245-92d3-034cb3ded5e4";                          
        var idsJuntos_ConcatenadosComVirgula = idItem1 + "," + idItem2 + "," + idItem3 + "," + idItem4 + ",";

        //adiciona
        values.Add(idCampoTabelaAssociativa, idItem1); //adiciona idItem1
        values.Add(idCampoTabelaAssociativa, idItem2); //adiciona idItem2
        values.Add(idCampoTabelaAssociativa, idItem3); //adiciona idItem3
        values.Add(idCampoTabelaAssociativa, idItem4); //adiciona idItem4
        values.Add("tabela_associativa_added-"+idCampoTabelaAssociativa,idsJuntos_ConcatenadosComVirgula);// itens concatenados com virgula
        values.Add("tabela_associativa_removed-"+idCampoTabelaAssociativa,"");//em branco
        values.Add("tabela_associativa_colunas_adicionais-"+idCampoTabelaAssociativa,"");//em branco
        //---------------------------------------



//salva a informação no banco de dados
await FormContext.SaveEntityAsync(idEstruturaFormulario_PESSOA, values);

```

##### Para recuperar o Texto de um campo que seja uma Lista Dinâmica (Combo, Auto completar, Múltipla seleção, Radio):

Suponhamos que você tenha um formulário de Pedido e nesse formulário você tenha um campo chamado 'Produto'.  
Esse campo é do tipo 'Pesquisa com Auto Completar' e listará os 'Produtos' por 'Nome'.  
Quando o usuário salvar o formulário, no Json de envio não retornará o Nome do Produto, apenas o Id do produto selecionado (Esse id estará no formato de um GUID).  
Para recuperar o Nome do produto, você precisará executar o método **GetText** da seguinte forma:

```C#
var nomeProduto = FormContext.GetText("produto");
```

##### Recuperar os valores das "Variáveis de Ambiente"

Para saber mais sobre variáveis de ambiente entre em [Variáveis de ambiente](https://wiki.agilityflow.io/link/88#bkmrk-page-title)

```JavaScript
var valorDaVariavel = FormContext.GetEnvironmentVariable("var_nomeDaVariavel");
```

Recuperar a Descrição (texto), no caso de variáveis do Tipo "Query com Id + Descrição":

```JavaScript
var textDaVariavel = FormContext.GetEnvironmentVariable_Text("var_nomeDaVariavel");
```

##### Enviar Mensagem para o usuário: A execução do código abaixo apresentará uma mensagem para o usuário

```C#
FormContext.WarningMessage("Exemplo de mensagem para o usuário");
```

<p class="callout danger">O código C# se encerrará no exato momento em que for chamado o método para apresentação de mensagem.</p>

Retorno da mensagem

![](https://wiki.agilityflow.io/uploads/images/gallery/2019-09-Sep/scaled-840-0/image-1569710675959.png)

#### Envio de e-mail

Responsável pelo envio de e-mail

<table border="1" id="bkmrk-op%E3%A7%E3%A3o-retorno-%E2%A0-s" style="border-collapse: collapse; width: 121.652%; height: 137px;"><tbody><tr style="height: 31px;"><td style="width: 70.1206%; height: 31px;">**Método**</td><td style="width: 14.0139%; height: 31px;">**Retorno**</td><td style="width: 35.6186%; height: 31px;"> </td></tr><tr style="height: 31px;"><td style="width: 70.1206%; height: 31px;">**EmailSender.SendToGrupoUsuario**(Guid grupoUsuarioId, string subject, string htmlContent)</td><td style="width: 14.0139%; height: 31px;">void</td><td style="width: 35.6186%; height: 31px;">Enviar um e-mail para um determinado Grupo de Usuario</td></tr><tr style="height: 46px;"><td style="width: 70.1206%; height: 46px;">**EmailSender.SendEmail**(string toEmail, string subject, string htmlContent)</td><td style="width: 14.0139%; height: 46px;">void</td><td style="width: 35.6186%; height: 46px;">Enviar um e-mail </td></tr><tr style="height: 29px;"><td style="width: 70.1206%; height: 29px;">**EmailSender.SendEmail**(string toEmail, string subject, string htmlContent, string ccEmail**)**</td><td style="width: 14.0139%; height: 29px;">void</td><td style="width: 35.6186%; height: 29px;">Enviar um e-mail, com copia (CC)</td></tr></tbody></table>

##### Enviar e-mail para um Grupo de Usuário

Antes de iniciar, crie um "Grupo de Usuário" no menu "Segurança e Acesso". Depois de criado, associe os usuários que receberão e-mail ao novo grupo de usuário que você acabou de criar.

Pegue o ID desse novo Grupo de usuário. Você vai precisar dele para enviar o e-mail.

```C#
var grupoUsuarioId = Guid.Parse("af7c9275-0e23-4b64-a433-f238bb457005"); //substitua o ID "af7c9275-0e23-4b64-a433-f238bb457005" pelo Id do grupo de usuario que você deseja enviar o e-mail
var assunto = "Novo E-mail para um Grupo de usuario ";
var html = "Olá Grupo, <BR><BR> Teste para envio de e-mail para um Grupo de Usuário no AgilityFlow!";

EmailSender.SendToGrupoUsuario(grupoUsuarioId, assunto, html);
```

##### Enviar e-mail 

```C#
var htmlContent = "<strong>Olá,</strong> teste envio de e-mail.";
var emailTo = "john@email.com";
var subject = "Subject do E-mail";

EmailSender.SendEmail(emailTo, subject, htmlContent);
```

# Programação em C# - Na API de integração (POST)

As informações descritas abaixo referem-se as APIs de <span style="text-decoration: underline;">**POST**</span>

<p class="callout danger">IMPORTANTE: as variáveis e métodos descritos aqui só funcionarão na programação C# na **API de integração**. Para a programação C# nas Regras de Negócio de um formulário [clique aqui](https://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/programa%C3%A7%C3%A3o-em-c---na-regra-de-neg%C3%B3cio "Programação em C# - Na Regra de Negócio")</p>

O agilityflow permite a customização da API em C#, além de já disponibilizar diversas bibliotecas e funções para facilitar sua programação, incluindo acesso a dados, validações, envio de e-mail, notificação, entre outras.

<p class="callout info">Para cada requisição na API é criada uma transação de banco de dados, essa transação é única em toda execução da API e é gerenciada automaticamente pelo Agilityflow, caso você prefira, você pode fazer esse gerenciamento seguindo esses passos, [veja mais detalhes aqui](https://wiki.agilityflow.io/link/90#bkmrk-%E2%A0-15)</p>

Abaixo mostramos alguns exemplos, se o material abaixo não for suficiente , entre em contato com nossa equipe.

#### Variáveis disponíveis

<table border="1" id="bkmrk-vari%E3%A1vel-tipo-%E2%A0-fo" style="border-collapse: collapse; width: 147.516%; height: 41px;"><tbody><tr style="height: 31px;"><td style="width: 22.4663%; height: 31px;">**Variável**</td><td style="width: 26.6063%; height: 31px;">**Tipo**</td><td style="width: 127.347%; height: 31px;"> </td></tr><tr style="height: 400px;"><td style="width: 22.4663%; height: 10px;">content</td><td style="width: 26.6063%; height: 10px;">string</td><td style="width: 127.347%; height: 10px;">Conteúdo enviado no Body da API

No caso se ser enviado uma string com o JSON, por exemplo no formato:

 <span style="background-color: #f8f8f8; font-family: 'Lucida Console', 'DejaVu Sans Mono', 'Ubunto Mono', Monaco, monospace; font-size: 0.8em; white-space: pre;">{ nome: 'José', email: 'jose@xxxx.com'}</span>

<div></div>Você pode converter essa string para JSON e utilizá-la como object

`var json = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(content);`

</td></tr></tbody></table>

#### Classe JsonHelper e outras para auxiliar o tratamento de JSON

Para utilizar execute `JsonHelper.NomeDoMetodo(....)`

<table border="1" id="bkmrk-op%E3%A7%E3%A3o-retorno-%E2%A0-g" style="border-collapse: collapse; width: 121.652%; height: 303px;"><tbody><tr style="height: 31px;"><td style="width: 48.7627%; height: 31px;">**Método**</td><td style="width: 16.6063%; height: 31px;">**Retorno**</td><td style="width: 54.3841%; height: 31px;"> </td></tr><tr style="height: 31px;"><td style="width: 48.7627%; height: 31px;">**HasProperty**(dynamic json, string nomePropriedade)</td><td style="width: 16.6063%; height: 31px;">bool

(true or false)

</td><td style="width: 54.3841%; height: 31px;">Testa se o JSON tem uma determinada propriedade.

Por exemplo, a sua API espera receber o JSON

no formato:

 <span style="background-color: #f8f8f8; font-family: 'Lucida Console', 'DejaVu Sans Mono', 'Ubunto Mono', Monaco, monospace; font-size: 0.8em; white-space: pre;">{ <span style="color: #0000ff;">nome</span>: 'José', <span style="color: #0000ff;">email</span>: 'jose@xxxx.com'}</span>

Porém recebe o JSON formato:

 <span style="background-color: #f8f8f8; font-family: 'Lucida Console', 'DejaVu Sans Mono', 'Ubunto Mono', Monaco, monospace; font-size: 0.8em; white-space: pre;">{ <span style="color: #ff0000;">nomecompleto</span>: 'José da Silva', <span style="color: #ff0000;">idade</span>: '21'}</span>

Como a propriedade NOME e EMAIL não existem no JSON recebido, o seu programa pode dar erro. Para evitar o erro, utilize o método <span style="color: #0000ff;">HasProperty</span>(...)

Como no exemplo abaixo:

`if (json != null)`  
`{`  
  
`if (JsonHelper.HasProperty(json, "nome") && JsonHelper.HasProperty(json, "email") ){`  
  
`var nome =  json["nome"].ToString();`

`var email=  json["email"].ToString();`  
  
`}`  
  
`}`

</td></tr><tr><td style="width: 48.7627%;">`Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(content);`  
</td><td style="width: 16.6063%;">dynamic

</td><td style="width: 54.3841%;">converte o conteúdo string para json

`var content = "{ nome: 'José', email: 'jose@xxxx.com'}";`

`var json = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(content);`

`var nome =  json["nome"].ToString();`

</td></tr></tbody></table>

#### Métodos Disponíveis no contexto da API

<table border="1" id="bkmrk-m%E3%A9todo-retorno-%E2%A0-s" style="border-collapse: collapse; width: 119.753%; height: 599px;"><tbody><tr style="height: 31px;"><td style="width: 56.0466%; height: 31px;">**Método**</td><td style="width: 17.1002%; height: 31px;">**Retorno**</td><td style="width: 49.6927%; height: 31px;"> </td></tr><tr style="height: 82px;"><td style="width: 56.0466%; height: 82px;">**await ApiContext.GetDataTableAsync**(string sql, params DbParameter\[\] parameters)</td><td style="width: 17.1002%; height: 82px;">DataTable</td><td style="width: 49.6927%; height: 82px;">Recuperar informações dos bancos de dados através de uma query sql.

[Veja exemplo](https://wiki.agilityflow.io/link/90#bkmrk-recuperando-dados-do "Veja exemplo")

</td></tr><tr style="height: 31px;"><td style="width: 56.0466%; height: 31px;">**await ApiContext.SaveEntityAsync**(Guid estruturaformularioid\_ASerCriadoOuAtualizado, DataDictionary campos\_e\_valores)</td><td style="width: 17.1002%; height: 31px;">Guid</td><td style="width: 49.6927%; height: 31px;">Salva as informações de um formulário no bancos de dados.

Obs: Para cadastrar valores numéricos, o números devem estar no formato com ponto no separador decimal: 999999.99 sem utilização de virgulas. Caso seja necessário, utilizar o .ToString() para formatar um campo decimal, não use. Utilize a conversão usando o string.Format, como no exemplo abaixo:

`string.Format(new System.Globalization.CultureInfo("en-gb"), "{0:F2}", json["valor"]);`

[Veja exemplo](https://wiki.agilityflow.io/link/90#bkmrk-salvando-os-dados-re "Veja exemplo")

</td></tr><tr style="height: 31px;"><td style="width: 56.0466%; height: 31px;">**await ApiContext.ApproveEntityAsync**(Guid estruturaformularioid\_ASerAprovado, DataDictionary campos\_e\_valores)</td><td style="width: 17.1002%; height: 31px;">Guid</td><td style="width: 49.6927%; height: 31px;">Avança uma etapa em um formulário com Workflow.

As regras de usuário aprovador, permissão de aprovação e responsabilidade por uma etapa devem ser validadas antes desse método ser executado.

Obs: Para cadastrar valores numéricos, o números devem estar no formato com ponto no separador decimal: 999999.99 sem utilização de virgulas. Caso seja necessário, utilizar o .ToString() para formatar um campo decimal, não use. Utilize a conversão usando o string.Format, como no exemplo abaixo:

`string.Format(new System.Globalization.CultureInfo("en-gb"), "{0:F2}", json["valor"]);`

[Veja exemplo](https://wiki.agilityflow.io/link/90#bkmrk-aprovando-uma-etapa-)

</td></tr><tr><td style="width: 56.0466%;">**await ApiContext.DeleteEntityAsync(Guid formularioId)**</td><td style="width: 17.1002%;">void</td><td style="width: 49.6927%;">deletar um formulario

</td></tr><tr style="height: 130px;"><td style="width: 56.0466%; height: 130px;">**ApiContext.GetEnvironmentVariable**(string nomeVariavel)

ou

**ApiContext.GetEnvironmentVariable\_Text**(string nomeVariavel) \*\*

</td><td style="width: 17.1002%; height: 130px;">string</td><td style="width: 49.6927%; height: 130px;">Recupera o Valor de uma variável de ambiente.

\*\* Recupera a Descrição (texto), no caso de variáveis do Tipo "Que

</td></tr><tr style="height: 224px;"><td style="width: 56.0466%; height: 224px;">**await ApiContext.LogAsync(string log, string logTipo)**

</td><td style="width: 17.1002%; height: 224px;">void</td><td style="width: 49.6927%; height: 224px;">Cria um log na tabela de log geral, o log pode ser consultado entrando na Área de Customização e clicando na opção "Log Geral &gt;&gt; consultar Log"

\*\* Além do Log Padrão da API que o sistema gera, você pode gerar esses Logs customizados para o seu próprio controle.

</td></tr><tr style="height: 35px;"><td style="width: 56.0466%; height: 35px;">**await ApiContext.DbTransaction\_BeginTransactionAsync()**

**await ApiContext.DbTransaction\_CommitAsync()**

**await ApiContext.DbTransaction\_RollbackAsync()**

</td><td style="width: 17.1002%; height: 35px;">void</td><td style="width: 49.6927%; height: 35px;">Para gerenciar a transação de banco de dados manualmente. Leia os detalhes [aqui mais abaixo ](https://wiki.agilityflow.io/link/90#bkmrk-%E2%A0-15)

</td></tr><tr style="height: 35px;"><td style="width: 56.0466%; height: 35px;">**ApiContext.GetUrlBase()**

</td><td style="width: 17.1002%; height: 35px;">void</td><td style="width: 49.6927%; height: 35px;">Retorna a URL base da sua aplicação

exemplo:

[https://suaempresa.agilityflow.io/](https://suaempresa.agilityflow.io/)

\*A url sempre virá com uma barra no final **/**

</td></tr></tbody></table>

##### Recuperando dados do banco de dados através de uma query SQL

```C#
//parametros da query
var paramsQuery = new List<SqlParameter>();
paramsQuery.Add(new SqlParameter("@param1", "xxx"));
paramsQuery.Add(new SqlParameter("@param2", "yyy"));
paramsQuery.Add(new SqlParameter("@param3", "zzz"));

//query usando (nolock) nas tabelas para evitar problema com a transação que está ativa
var sql = "select column1,column2,column3 from table (nolock) where column1 = @param1 or  column2 = @param2 or  column3 = @param3 ";

//executar no banco de dados
var dt = await ApiContext.GetDataTableAsync(sql, paramsQuery.ToArray());

//percorrendo as linhas de retorno da tabela
foreach (DataRow dr in dt.Rows)
{
  if (dr["column1"] != DBNull.Value){
  	var xx = dr["column1"].ToString();
  }
}
```

##### Salvando os dados recebidos através do método SaveEntityAsync

\* Para cadastrar valores numéricos, o números devem estar no formato com ponto no separador decimal: 999999.99 sem utilização de virgulas.

```C#
public void Execute(){
        
  //opcional para registrar no log de controle
  await ApiContext.LogAsync("Entrou da API", "log_api_xpto");
  
            //converte o conteúdo enviado no body da API para JSON
            var json = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(content);
      
            //guarda em uma variável o ID da  E S T R U T U R A  do formulário de pessoa
            var idEstruturaFormulario_PESSOA = Guid.Parse("0b56b66a-4f6f-4ded-ad04-016d7c0724e1");
    
    
            if (json != null)
            {
    
                    //verifica se o JSON recebido contém a propriedade "nome", "email" e "cel" que são necessários p cadastro
                    if (JsonHelper.HasProperty(json, "nome") && JsonHelper.HasProperty(json, "email") && JsonHelper.HasProperty(json, "perfil")){
           
                        var values = new DataDictionary();
                        values.Add("nome", json["nome"].ToString());
                        values.Add("email", json["email"].ToString());
                      
                        //no caso do campo do formulário ser uma tabela associativa (tabela relacional N:N)
                        var idCampoTabelaAssociativa = "70b6f362-2587-4fd2-a2fb-148bd0caf437";
                        if (json["perfil"].ToString() == "todos_os_perfis" ) {
                          
                          var idPerfilAdmin = "51cf02f1-3787-4dca-8a2c-e219a5ce1298";
                          var idPerfilColaborador = "f999f103-c775-4245-92d3-034cb3ded5e4";                          
                          var idPerfisConcatenadosComVirgula = idPerfilAdmin + "," + idPerfilColaborador + ",";
                          
                          //adiciona os perfis
                          values.Add(idCampoTabelaAssociativa, idPerfilAdmin); //adiciona perfil de admin
                          values.Add(idCampoTabelaAssociativa, idPerfilColaborador); //adiciona perfil de colaborador
                          values.Add("tabela_associativa_added-"+idCampoTabelaAssociativa,idPerfisConcatenadosComVirgula);// perfis concatenados com virgula
                          values.Add("tabela_associativa_removed-"+idCampoTabelaAssociativa,"");//em branco, se fosse pra remover, era só colocar os perfis concatenados com virgula
                          //---------------------------------------

                        }
                        else if (json["perfil"].ToString() == "apenas_colaborador" ) {
                          
                          
                          var idPerfilColaborador = "f999f103-c775-4245-92d3-034cb3ded5e4";                        
                          var idPerfilConcatenadoComVirgula = idPerfilColaborador + ",";
                          
                          //adiciona o perfil
                          values.Add(idCampoTabelaAssociativa, idPerfilColaborador); //adiciona perfil de colaborador
                          values.Add("tabela_associativa_added-"+idCampoTabelaAssociativa,idPerfilConcatenadoComVirgula);// perfis concatenados com virgula
                           values.Add("tabela_associativa_removed-"+idCampoTabelaAssociativa,"");//em branco, se fosse pra remover, era só colocar os perfis concatenados com virgula
                          //---------------------------------------
                          
                          
                        }
                      
                        //salva a informação no banco de dados
                        await ApiContext.SaveEntityAsync(idEstruturaFormulario_PESSOA, values);
                        
                    }
                
            }
//opcional para registrar no log de controle
  await ApiContext.LogAsync("Saiu da API", "log_api_xpto");
    
    }
```

##### Aprovando uma etapa através do método ApproveEntityAsync

```C#
public void Execute(){

  //opcional para registrar no log de controle
  await ApiContext.LogAsync("Entrou da API", "log_api_xpto");
  
            //converte o conteúdo enviado no body da API para JSON
            var json = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(content);
      
            //guarda em uma variável o ID da  E S T R U T U R A  do formulário de pessoa
            var idEstruturaFormulario_PESSOA = Guid.Parse("0b56b66a-4f6f-4ded-ad04-016d7c0724e1");
    
    
            if (json != null)
            {
    
                    //verifica se o JSON recebido contém a propriedade "nome", "email" e "cel" que são necessários p cadastro
                    if (JsonHelper.HasProperty(json, "nome") && JsonHelper.HasProperty(json, "email") && JsonHelper.HasProperty(json, "perfil")){
           
                        var values = new DataDictionary();
                        values.Add("nome", json["nome"].ToString());
                        values.Add("email", json["email"].ToString());
                      	values.Add("id", json["id"].ToString());
                      
                        //no caso do campo do formulário ser uma tabela associativa (tabela relacional N:N)
                        var idCampoTabelaAssociativa = "70b6f362-2587-4fd2-a2fb-148bd0caf437";
                        if (json["perfil"].ToString() == "todos_os_perfis" ) {
                          
                          var idPerfilAdmin = "51cf02f1-3787-4dca-8a2c-e219a5ce1298";
                          var idPerfilColaborador = "f999f103-c775-4245-92d3-034cb3ded5e4";                          
                          var idPerfisConcatenadosComVirgula = idPerfilAdmin + "," + idPerfilColaborador + ",";
                          
                          //adiciona os perfis
                          values.Add(idCampoTabelaAssociativa, idPerfilAdmin); //adiciona perfil de admin
                          values.Add(idCampoTabelaAssociativa, idPerfilColaborador); //adiciona perfil de colaborador
                          values.Add("tabela_associativa_added-"+idCampoTabelaAssociativa,idPerfisConcatenadosComVirgula);// perfis concatenados com virgula
                          values.Add("tabela_associativa_removed-"+idCampoTabelaAssociativa,"");//em branco, se fosse pra remover, era só colocar os perfis concatenados com virgula
                          //---------------------------------------

                        }
                        else if (json["perfil"].ToString() == "apenas_colaborador" ) {
                          
                          
                          var idPerfilColaborador = "f999f103-c775-4245-92d3-034cb3ded5e4";                        
                          var idPerfilConcatenadoComVirgula = idPerfilColaborador + ",";
                          
                          //adiciona o perfil
                          values.Add(idCampoTabelaAssociativa, idPerfilColaborador); //adiciona perfil de colaborador
                          values.Add("tabela_associativa_added-"+idCampoTabelaAssociativa,idPerfilConcatenadoComVirgula);// perfis concatenados com virgula
                          values.Add("tabela_associativa_removed-"+idCampoTabelaAssociativa,"");//em branco, se fosse pra remover, era só colocar os perfis concatenados com virgula
                          //---------------------------------------
                          
                          
                        }
                      
                        //salva a informação no banco de dados
                        await ApiContext.ApproveEntityAsync(idEstruturaFormulario_PESSOA, values);
                        
                    }
                
            }
//opcional para registrar no log de controle
    await ApiContext.LogAsync("saiu da API", "log_api_xpto");
    
    }
```

##### Recuperar os valores das "Variáveis de Ambiente"

Para saber mais sobre variáveis de ambiente entre em [Variáveis de ambiente](https://wiki.agilityflow.io/link/88#bkmrk-page-title)

```JavaScript
var valorDaVariavel = ApiContext.GetEnvironmentVariable("var_nomeDaVariavel");
```

Recuperar a Descrição (texto), no caso de variáveis do Tipo "Query com Id + Descrição":

```JavaScript
var textDaVariavel = ApiContext.GetEnvironmentVariable_Text("var_nomeDaVariavel");
```

#### Envio de e-mail

Responsável pelo envio de e-mail

<table border="1" id="bkmrk-op%E3%A7%E3%A3o-retorno-%E2%A0-s" style="border-collapse: collapse; width: 121.652%; height: 303px;"><tbody><tr style="height: 31px;"><td style="width: 70.1206%; height: 31px;">**Método**</td><td style="width: 14.0139%; height: 31px;">**Retorno**</td><td style="width: 35.6186%; height: 31px;"> </td></tr><tr style="height: 31px;"><td style="width: 70.1206%; height: 31px;">**EmailSender.SendToGrupoUsuario**(Guid grupoUsuarioId, string subject, string htmlContent)</td><td style="width: 14.0139%; height: 31px;">void</td><td style="width: 35.6186%; height: 31px;">Enviar um e-mail para um determinado Grupo de Usuario</td></tr><tr><td style="width: 70.1206%;">**EmailSender.SendEmail**(string toEmail, string subject, string htmlContent)</td><td style="width: 14.0139%;">void</td><td style="width: 35.6186%;">Enviar um e-mail </td></tr><tr><td style="width: 70.1206%;">**EmailSender.SendEmail(**string toEmail, string subject, string htmlContent, string ccEmail)</td><td style="width: 14.0139%;">void</td><td style="width: 35.6186%;">Enviar um e-mail, com copia (CC)</td></tr></tbody></table>

##### Enviar e-mail para um Grupo de Usuário

Antes de iniciar, crie um "Grupo de Usuário" no menu "Segurança e Acesso". Depois de criado, associe os usuários que receberão e-mail ao novo grupo de usuário que você acabou de criar.

Pegue o ID desse novo Grupo de usuário. Você vai precisar dele para enviar o e-mail.

```C#
var grupoUsuarioId = Guid.Parse("af7c9275-0e23-4b64-a433-f238bb457005"); //substitua o ID "af7c9275-0e23-4b64-a433-f238bb457005" pelo Id do grupo de usuario que você deseja enviar o e-mail
var assunto = "Novo E-mail para um Grupo de usuario ";

var html = "Olá Grupo, <BR><BR> Teste para envio de e-mail para um Grupo de Usuário no AgilityFlow!";

EmailSender.SendToGrupoUsuario(grupoUsuarioId, assunto, html);
```

##### Enviar e-mail 

```C#
var htmlContent = "<strong>Olá,</strong> teste envio de e-mail.";
var emailTo = "john@email.com";
var subject = "Subject do E-mail";

EmailSender.SendEmail(emailTo, subject, htmlContent);
```

#### Método principal para utilização da Programação em C# na api de post

A única regra é que o método se chame Execute, não tenha parâmetros de entrada e o retorno seja void.

Exemplo:

```C#
public void Execute(){            



  //aqui você pode programar   



}
```

#### Gerenciar as transações de Banco de dados manualmente

Caso você escolha por gerenciar as transactions de banco de dados manualmente, você precisará obrigatoriamente utilizar as 3 funções abaixo:

<p class="callout warning">Atenção: Configuração recomendada apenas para especialista.</p>

1. **ApiContext.DbTransaction\_BeginTransaction()** Para abrir uma transação, antes de iniciar as alterações no banco de dados
2. **ApiContext.DbTransaction\_Commit()** Para finalizar e confirmar com sucesso as alterações no banco de dados
3. **ApiContext.DbTransaction\_Rollback()** Para finalizar e desfazer as alterações no banco de dados

Exemplo de uso:

<p class="callout danger">Atenção: Utilize as transactions sempre dentro de TRY e CATCH</p>

<p class="callout info">Podem ser abertas uma ou mais transações na mesma API. Você ficará responsável por todas as aberturas e encerramentos das transações criadas.</p>

```C#
public async Task RunAsync(){
        
            //converte o conteúdo enviado no body da API para JSON
            var json = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(content);
      
            //guarda em uma variável o ID da  E S T R U T U R A  do formulário de pessoa
            var idEstruturaFormulario_PESSOA = Guid.Parse("0b56b66a-4f6f-4ded-ad04-016d7c0724e1");
    
            try
            {
              
              await ApiContext.DbTransaction_BeginTransactionAsync(); //ABRE A TRANSAÇÃO, DENTRO DO TRY CATCH

              var values = new DataDictionary();
              values.Add("nome", "exemplo1_PRIMEIRA_transacao");
              
              await ApiContext.SaveEntityAsync(idEstruturaFormulario_PESSOA, values); //salva a informação no banco de dados
              
              await ApiContext.DbTransaction_CommitAsync(); //CONFIRMA A TRANSAÇÃO, DENTRO DO TRY CATCH

            }
            catch
            {              
              await ApiContext.DbTransaction_RollbackAsync(); //DESFAZ A TRANSAÇÃO, DENTRO DO CATCH em caso de erro
              throw;
            }
    
  
  			//mais código
  			//...
  			//mais código
  			//...
    		//mais código
  			//...
  			//mais código
  			//...
  
  
  
  
  			try
            {
              
              await ApiContext.DbTransaction_BeginTransactionAsync(); //ABRE A TRANSAÇÃO, DENTRO DO TRY CATCH

              var values2 = new DataDictionary();
              values2.Add("nome", "exemplo2_SEGUNDA_transacao");
              
              await ApiContext.SaveEntityAsync(idEstruturaFormulario_PESSOA, values2); //salva a informação no banco de dados
              
              await ApiContext.DbTransaction_CommitAsync(); //CONFIRMA A TRANSAÇÃO, DENTRO DO TRY CATCH

            }
            catch
            {              
              await ApiContext.DbTransaction_RollbackAsync(); //DESFAZ A TRANSAÇÃO, DENTRO DO CATCH em caso de erro
              throw;
            }
  	
  
    
    }
```

# Tabela de dados customizada através de programação: Query SQL, C#, HTML e CSS

Para acessar os detalhes desse conteúdo, [clique aqui](https://wiki.agilityflow.io/link/78#bkmrk-criar-html-com-tabel).

# Single Sign-On

Como configurar o Single Sign-On (SSO) utilizando o AD e o ADFS.

# Configurar integração com o AD (Active Directory)

Você pode utilizar os seus usuários do Active Directory para login no agilityflow, assim o usuário de rede será único, e fará um single sign-on nas aplicações do agilityflow.

Para isso iremos fornecedor 2 scripts ASP clássico e você deve configura-los no seu servidor. Abaixo segue os procedimentos para essa instalação.

O script será hospedado no servidor IIS e terá acesso ao Active Directory para autenticar usuários no Agilityflow.

Se você quiser configurar o SSO usando o padrão universal SAML, consulte nesse [link, sobre o uso do SAML no Agilityflow através do ADFS.](http://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/como-configurar-a-integra%C3%A7%C3%A3o-com-o-adfs "Como configurar a integração com o ADFS")

<p class="callout danger">**Recomendação importante:** Após finalizar a configuração do AD no Agilityflow. Faça o teste em uma guia anônima do seu navegador antes de fazer o logout da sua sessão atual do Agilityflow. Assim você conseguirá fazer as mudanças necessárias no Agilityflow caso sua configuração não esteja correta. Caso você faça o logout, entre em contato conosco para auxiliarmos no passo a passo.</p>

### Pré-requisitos

- Uma instância do Active Directory instalada no seu servidor. Você pode seguir as etapas fornecidas [neste artigo](https://docs.microsoft.com/pt-br/windows-server/identity/ad-ds/deploy/install-active-directory-domain-services--level-100-) para configurar e instalar o AD no seu servidor
- Garantir que todos os usuários do AD tenham o atributo de endereço de e-mail preenchido. O Agilityflow utiliza o **e-mail** e o **login** do usuário como identificador para autenticação. Portanto, além do login, é necessário que o usuário tenha o endereço de e-mail preenchido no Active Directory.

Caso você receba do Agilityflow a mensagem “**O usuário 'xxxx' não tem o e-mail cadastrado no AD.** ”, verifique se o endereço de e-mail está configurado para esse usuário no Active Directory, se não estiver, fale com o seu administrador de rede. Abaixo estão descritos os procedimentos para configuração do e-mail do usuário no AD.

Para preencher o e-mail do usuário no AD: acesse o seu Active Directory, no painel esquerdo clique em **Users**, agora no painel da direita, clique com o botão direito no usuário que deseja alterar o e-mail, clique em "**Properties**" e no campo "**E-mail**" inclua o e-mail do usuário. As imagens abaixo ilustram esse passo a passo:

<span style="color: #808080;">Selecione o usuário:</span>

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555530434826.png)

<span style="color: #808080;">Altere o e-mail:</span>

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555530449453.png)

<span style="color: #808080;">Clique em OK e o e-mail estará incluído nesse usuário. </span>

<span style="color: #808080;">Esse procedimento será necessário para todos os usuários que não estão com e-mail configurado no AD.</span>

#### PASSO 1: Instalando o Internet Information Services (IIS)

O Internet Information Server (Gerenciador do IIS) deve ser configurado no seu Windows Server para hospedar o arquivo de script ASP Clássico, que acessará as informações do usuário no Active Directory.

<p class="callout info">O IIS Server deve estar instalado no mesmo domínio do Active Directory que contém os usuários.</p>

Você pode seguir as etapas fornecidas [neste artigo](https://docs.microsoft.com/en-us/iis/get-started/whats-new-in-iis-8/installing-iis-8-on-windows-server-2012) para instalar o IIS no Windows Server 2012. Escolha as opções a seguir ao instalar a função IIS no servidor.

- **Web Server (IIS)**  
    
    - **Security**  
        
        - **Windows Authentication**
    - **Application Development**  
        
        - **ASP**
- **Management Tools**  
    
    - **IIS Management Console**

  
Você precisa do **Windows Authentication** e também do **ASP** no seu servidor para hospedar e rodar o script ASP clássico que forneceremos a seguir e que será o responsável pelo login dos usuários do Active Directory no Agilityflow. Portanto, se você já instalou o IIS, verifique se esses recursos estão instalados.

#### PASSO 2: Editando o arquivo de script ASP clássico

1\. Baixe os arquivos default.asp e config.asp que estão disponíveis na área de configuração do seu ambiente no agilityflow.

Os arquivos para download você encontra nesse link: [https://&lt;SEU\_AMBIENTE&gt;.agilityflow.io/configuration](https://<SEU_AMBIENTE>.agilityflow.io/configuration) ou através do menu: Customizar Agilityflow → Single Sign-On, AD e ADFS. → depois na ABA: "Autenticação de usuário" → "AD" você encontrará o link para download.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555365365543.png)

  
2\. Abra o arquivo config.asp e atribua esses valores às variáveis:

- **agilityflowUrl**: url onde o seu sistema do agilityflow está hospedado, geralmente as aplicações ficam na url: [https://&lt;SEU\_AMBIENTE&gt;.agilityflow.io/](https://<SEU_AMBIENTE>.agilityflow.io) . é importante que a url termine com a barra **/**
- **LDAP\_UserName\_WithAccessToReader**: Nome de usuário da conta do AD que tem pelo menos privilégio de leitura para todos os usuários no AD. (preencha com no formato: "dominioDaMinhaEmpresa\\usuarioadmin")
- **LDAP\_UserPassword\_WithAccessToReader**: Senha dessa conta de usuário
- **agilityflowADToken**: token de segurança gerado pelo agilityflow que será o código de segurança com o seu AD. Esse token pode ser copiado através do menu: Customizar Agilityflow → Single Sign-On, AD e ADFS → depois na ABA: "Autenticação de usuário" → "AD" copiei do campo "Token"

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555365432732.png)

#####   
Exemplo de preenchimento do arquivo config.asp

agilityflowUrl = "https://nomedaempresa.agilityflow.io"  
LDAP\_UserName\_WithAccessToReader = "dominioDaMinhaEmpresa\\usuarioadmin"  
LDAP\_UserPassword\_WithAccessToReader = "xxxxxxxxxx"  
agilityflowADToken = "xxxxxxxxxxxxxxxxxxxxxxxxxx"

#### PASSO 3: Configurando o script ASP no IIS

1. Crie um website ou um application dentro do seu website padrão no IIS. Para criar um novo website no IIS, consulte a seção Criar um novo website neste [artigo](https://support.microsoft.com/en-us/help/323972/how-to-set-up-your-first-iis-web-site).
2. Clique no website e clique duas vezes em **ASP** no painel direito. Defina a opção **Enable Parent Paths** para **true**. ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555360128859.png)
3. Clique no website novamente e clique duas vezes em **Authentication**. Clique com o botão direito do mouse em **Windows Authentication** e clique em **Enable**. Desative todos os outros tipos de autenticação. O IIS usará a autenticação integrada do Windows (**Integrated Windows Authentication**). Para tornar isso possível, o IIS Server deve ser instalado no domínio do Active Directory que contém os usuários.![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555359948043.png)
4. Agora clique com o botão direito do mouse no website, clique em **Explore** e cole os 2 arquivos - **default.asp** e **config.asp** que já estão configurados.

#### PASSO 4: Configurar o Single Sign-on no Agilityflow

1. Vá para o menu Customizar Agilityflow → Single Sign-On, AD e ADFS.
2. Na aba "Autenticação de usuário (Login) / Single Sign-On" no campo **Tipo de Autenticação** selecione **"AD"**
3. No campo "**URL para realizar o login**" - Digite o URL que o Agilityflow chamará quando os usuários tentarem fazer login. Essa URL deve apontar para o website com o script ASP que você acabou de criar, nos passos anteriores. Cole a URL de navegação do arquivo default.asp. Exemplo: se o seu website foi criado na URL: **https://www.xyz.com/agilityflowAuthService** então você deve preencher esse campo com o a URL: **https://www.xyz.com/agilityflowAuthService/default.asp** verifique se todas as chamadas do IIS feitas para esse script estão com  **Windows Authentication** e <span style="text-decoration: underline;">não</span> **Anonymous Authentication**.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555365662245.png)

Pronto, agora abra uma guia anônima do seu navegador e tente realizar o login no agilityflow.

Se você enfrentar algum problema durante a configuração, entre em contato conosco.

Pronto, as configurações foram finalizadas.

<p class="callout danger">**Recomendação importante:** Após finalizar a configuração do AD no Agilityflow. Faça o teste em uma guia anônima do seu navegador antes de fazer o logout da sua sessão atual do Agilityflow. Assim você conseguirá fazer as mudanças necessárias no Agilityflow caso sua configuração não esteja correta. Caso você faça o logout, entre em contato conosco para auxiliarmos no passo a passo.</p>

# Configurar integração com o ADFS (Active Directory Federation Services)

O agilityflow oferece suporte Single Sign-on (SSO) por meio do SAML 2.0. O ADFS é um serviço fornecido pela Microsoft como uma função padrão do Windows Server que fornece um login da Web usando as credenciais existentes do Active Directory.

Com essa configuração você pode utilizar os seus usuários do Active Directory para login no agilityflow, assim o usuário da rede será usado no single sign-on do agilityflow.

<p class="callout danger">**Recomendação importante:** Após finalizar a configuração do ADFS no agilityflow. Faça o teste em uma guia anônima do seu navegador antes de fazer o logout da sua sessão atual do agilityflow. Assim você conseguirá fazer as mudanças necessárias no agilityflow caso sua configuração não esteja correta. Caso você faça o logout, entre em contato conosco para auxiliarmos no passo a passo.</p>

### Pré-requisitos

1. Uma instância do Active Directory instalada no seu servidor. Você pode seguir as etapas fornecidas [neste artigo](https://docs.microsoft.com/pt-br/windows-server/identity/ad-ds/deploy/install-active-directory-domain-services--level-100-) para configurar e instalar o AD no seu servidor.
2. Uma instância do ADFS instalada no seu servidor. Você pode seguir as etapas fornecidas [neste artigo](https://docs.microsoft.com/en-us/previous-versions/dynamicscrm-2016/deployment-administrators-guide/gg188612(v=crm.8)) para configurar e instalar o ADFS no seu servidor
3. Garantir que todos os usuários do AD tenham o atributo de endereço de e-mail preenchido. O agilityflow utiliza o **e-mail** e o **login** do usuário como identificador para autenticação. Portanto, além do login, é necessário que o usuário tenha o endereço de e-mail preenchido no Active Directory.

Então, caso você receba do agilityflow a mensagem “**O usuário 'xxxx' não tem o e-mail cadastrado no AD.** ”, verifique se o endereço de e-mail está configurado para esse usuário no Active Directory, se não estiver, fale com o seu administrador de rede. Abaixo estão descritos os procedimentos para configuração do e-mail do usuário no AD.

Para preencher o e-mail do usuário no AD: acesse o seu Active Directory, no painel esquerdo clique em **Users**, agora no painel da direita, clique com o botão direito no usuário que deseja alterar o e-mail, clique em "**Properties**" e no campo "**E-mail**" inclua o e-mail do usuário. As imagens abaixo ilustram esse passo a passo:

Selecione o usuário:

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555530434826.png)

Altere o e-mail:

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555530449453.png)

Clique em OK e o e-mail estará incluído nesse usuário.

Esse procedimento será necessário para todos os usuários que não estão com e-mail configurado no AD.

### PASSO 1: Configurar o ADFS 

Neste ponto, você deve estar pronto para configurar a conexão do ADFS com sua conta do agilityflow. A conexão entre o ADFS e o agilityflow é definida usando um Relying Party Trust (RPT).

Abra o **AD FS Management**, no menu da esquerda, abra a guia **Trust Relationships**, clique com o botão direito em **Relying Party Trusts** e então clique em **Add Relying Party Trust**

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555532776403.png)

1\. Isso inicia o assistente de configuração do Relying Party Trust. Clique em **Start**.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555532938594.png)

2\. No passo **Select Data Source**, selecione a última opção: **Enter Data About the Party Manually.**

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555533229030.png)

3\. No passo **Specify Display Name**, insira um nome para esse Relying Party Trust. Informe o nome **agilityflow**.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555533356038.png)

4\. No passo **Choose Profile**, mantenha a opção **ADFS FS profile**

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555533571469.png)

  
5\. No passo **Configure Certificate**, mantenha as configurações da forma que estão e clique em **Next**.

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555533596127.png)

6\. No passo **Configure URL**, marque a opção **Enable support for the SAML 2.0 WebSSO protocol** e em **Relying party SAML 2.0 SSO service URL** informe **https://&lt;SEU\_AMBIENTE&gt;.agilityflow.io/<span style="color: #993300;">adfs</span>/**

![](https://wiki.agilityflow.io/uploads/images/gallery/2024-12-Dec/scaled-840-0/image-1734571700173.png)

7\. No passo **Configure identifiers** informe **https://&lt;SEU\_AMBIENTE&gt;.agilityflow.io/adfs/** em **Relying party trust identifier** e clique em **Add**, na sequencia, clique em **Next.**

![](https://wiki.agilityflow.io/uploads/images/gallery/2024-12-Dec/scaled-840-0/image-1734571752211.png)

  
8\. No passo **Configure Multi-factor Authentication Now?**, mantenha as configurações da forma que estão e clique em **Next.**

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555535330501.png)

9\. No passo **Choose Issuance Authorization Rules**, mantenha a opção **Permit all users to access the relying party** marcada e clique em **Next.**

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555535472973.png)

10\. No passo **Ready to Add Trust,** mantenha as configurações da forma que estão e clique em **Next.**

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555535590744.png)

11\. No passo **Finish,** mantenha marcada a opção **Open the Edit Claim Rules dialog for this relying party trust when the wizard closes** e clique em **Close**;

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555535621223.png)

12\. Na nova janela que abrirá, clique em **Add rule**

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555535839562.png)

13\. No passo **Choose Rule Type,** no campo **Claim rule Template** selecione a opção **Send LDAP Attributes as Claims** e clique em **Next.**

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555535939662.png)

14\. No passo **Configura Claim Rule** preencha da seguinte forma:

Em **Claim rule name** informe "**LDAP E-mail, Username".** Em **Attribute store** selecione **Active Directory.** Na tabela **Mapping of LDAP attributes to outgoing claim types** preencha da seguinte forma:

<table border="1" id="bkmrk-ldap-attribute-outgo" style="border-collapse: collapse; width: 55.679%;"><tbody><tr><td style="width: 24.641%;">**LDAP Attribute**</td><td style="width: 31.038%;">**Outgoing claim type**</td></tr><tr><td style="width: 24.641%;">SAM-Account-Name</td><td style="width: 31.038%;">Name ID</td></tr><tr><td style="width: 24.641%;">E-Mail-Addresses</td><td style="width: 31.038%;">E-Mail Address</td></tr></tbody></table>

Depois clique em **Finish e OK**

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555536727733.png)

  
15\. Depois de confirmar e fechar o **Claim Rules dialog,** Vá até a lista de **Relying Party Trusts** e clique com o botão direito em **agilityflow** e selecione a opção **Properties.**

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555537614370.png)

16\. Na aba **Advanced**, selecione **SHA-256** no campo **Secure hash algorithm.**

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555537243337.png)

17\. Na aba **Endpoints**, clique em **Add SAML** para adicionar um novo endpoint

![](https://wiki.agilityflow.io/uploads/images/gallery/2024-12-Dec/scaled-840-0/image-1734571919420.png)

18\. Na nova janela que abrirá chamada **Add an** **Endpoints**, preencha os campos da seguinte forma:

- Em **Endpoint type** escolha **SAML Logout**
- Em **Binding** mantenha a opção **POST**
- Em **Trusted URL** informe a URL concatenando as seguintes informações  
     1. O endereço da web do seu servidor ADFS, exemplo: "**https://www.seudominio.com"**  
     2. O endpoint SAML configurado no ADFS. Por padrão (se você não alterou essa configuração) será: **"/adfs/ls"**  
     3. E por fim, concatene os parâmetros "**?wa=wsignout1.0**"

 A sua url final deverá ficar parecida com essa : **https://www.seudominio.com/adfs/ls?wa=wsignout1.0**

Após isto, clique em **OK**;

![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555538989428.png)

19\. Isto conclui a configuração do ADFS, clique em Apply e depois em OK;

### PASSO 2: Configurar o Single Sign-on no agilityflow

<p class="callout danger">**Recomendação importante:** Após finalizar a configuração do ADFS no agilityflow. Faça o teste em uma guia anônima do seu navegador antes de fazer o logout da sua sessão atual do agilityflow. Assim você conseguirá fazer as mudanças necessárias no agilityflow caso sua configuração não esteja correta. Caso você faça o logout, entre em contato conosco para auxiliarmos no passo a passo.</p>

Acesse via browser a sua instância do agilityflow.

1. Vá para o menu Customizar agilityflow → Single Sign-On, AD e ADFS, será aberta a seguinte tela:![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555540620319.png)
2. Na aba "**Autenticação de usuário (Login) / Single Sign-On"** no campo **Tipo de Autenticação** selecione **"ADFS"**
3. No campo "**URL para realizar o login**" - Digite a URL do seu servidor ADFS que o agilityflow chamará quando os usuários tentarem fazer login. Essa URL geralmente termina em **IdpInitiatedSignOn.aspx**. Por exemplo, se o link de início for **https://www.seudominio.com/adfs/ls/**, a página de login será ****https://www.seudominio.com/adfs/ls/IdpInitiatedSignOn.aspx.****![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555601620553.png)
4. No campo "**Url para realizar o logoff**" insira a mesma URL que você inseriu no campo "**Trusted URL**", [descrito aqui nesse tópico ](http://wiki.agilityflow.io/link/83#bkmrk-em%E2%A0endpoint-type%E2%A0e)essa é a URL que o agilityflow chamará para o usuário fazer logout do ADFS. Essa URL geralmente termina em "**?wa=wsignout1.0**". Por exemplo, se o link de início for **https://www.seudominio.com/adfs/ls**, a página de logout será   
    ****[https://www.seudominio.com/adfs/ls?wa=wsignout1.0](https://www.seudominio.com/adfs/ls?wa=wsignout1.0)****![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555601745457.png)
5. Para o preenchimento do campo **Certificado (X. 509),** você precisará voltar ao seu servidor ADFS e seguir o seguintes passos: 
    1. Abra o seu Windows Server, abra **Administrative Tools** no menu Iniciar do Windows ou em **Control Panel** e abra o aplicativo **AD FS Management.**![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555542631397.png)
    2. No menu da esquerda, abra a guia **Service** → **Certificates**![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555542672859.png)
    3. No painel da direita, clique duas vezes no certificado Token-signing que você deseja usar.
        
        ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555542731675.png)
    4. Clique na aba **Details** e clique em **Copy to File**
        
        ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555542806518.png)
    5. Clique em **Next** no assistente de exportação e selecione a opção **Base-64 encoded** **X.509 (.CER)**
        
        ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555542839212.png)
    6. Salve o arquivo de certificado em seu sistema de arquivos local
    7. Abra o certificado que você acabou de salvar em um editor de texto.![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555542285695.png)
    8. Apague do conteúdo do certificado as linhas inicias e linhas finais  
        Linha inicial para apagar **"-----BEGIN CERTIFICATE-----"**   
        Linha final para apagar **"-----END CERTIFICATE-----"**  
        Essas informações não podem constar no campo **Certificado (X. 509)** do agilityflow
    9. Depois de apagar as duas linhas citadas acima, copie o conteúdo desse certificado que deve ser algo como esse abaixo:![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555542984262.png)
    10. Agora volte na sua instância do agilityflow e cole o conteúdo desse certificado no campo de texto ****Certificado (X. 509).**** ![](http://wiki.agilityflow.io/uploads/images/gallery/2019-04-Apr/scaled-840-0/image-1555601657409.png)

Salve e pronto, as configurações foram finalizadas.

Se você enfrentar algum problema durante a configuração, entre em contato conosco.

<p class="callout danger">**Recomendação importante:** Após finalizar a configuração do ADFS no agilityflow. Faça o teste em uma guia anônima do seu navegador antes de fazer o logout da sua sessão atual do agilityflow. Assim você conseguirá fazer as mudanças necessárias no agilityflow caso sua configuração não esteja correta. Caso você faça o logout, entre em contato conosco para auxiliarmos no passo a passo.</p>

# Outras Dicas



# Buscar o CEP nos Correios e preencher os campos de endereço automaticamente

Para facilitar o preenchimento dos campos de endereço é possível configurar para que o campo de CEP dispare uma consulta na base dos Correios e preencha os campos de endereço.

#### Informações que são possíveis preencher automaticamente através do CEP:

- Rua,
- Bairro,
- Cidade,
- Estado,
- Sigla do Estado,
- DDD da região,
- Número De - Até (Intervalo numérico da região)

### Configuração:

1\. Através do menu principal do sistema, entre na área de customização e configuração do Agilityflow

2\. Na área de customização, edite o formulário que deseja configurar a busca pelo CEP

3\. Já dentro do formulário acesse a área de customização em Javascript, como na imagem abaixo

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-01-Jan/scaled-840-0/image-1611871804622.png)

![](https://wiki.agilityflow.io/uploads/images/gallery/2021-01-Jan/scaled-840-0/image-1611872625262.png)

4\. Cole a função Javascript e altere apenas os parâmetros que estão <span style="color: #ff9900;">**em amarelo**</span> no código abaixo. Na tabela um pouco mais abaixo os parâmetros estão descritos com mais detalhes

```JavaScript
formContext.buscaCEP.configurar(
    'id_campo_cep',
    {
        uf_sigla: 'id_do_campo_uf_sigla',
        uf_nome: 'id_do_campo_uf_nome',
        logradouro: 'id_do_campo_logradouro',
        bairro: 'id_do_campo_bairro',
        cidade: 'id_do_campo_cidade',
        numero_de_ate: 'id_do_campo_numero_de_ate',
        ddd_da_regiao: 'id_do_campo_ddd_da_regiao'
    }
);


```

Parâmetros da função

<table border="1" id="bkmrk-parametro-%E2%A0-%E2%A0-reto" style="border-collapse: collapse; width: 99.8764%; height: 217px;"><tbody><tr><td style="width: 17.886%;">**Parametro**</td><td style="width: 23.0818%;"> </td><td style="width: 37.87%;"> </td><td style="width: 21.1621%;">**Retorno de exemplo**</td></tr><tr style="height: 31px;"><td style="width: 17.886%; height: 31px;">"**id\_campo\_cep**"</td><td style="width: 23.0818%;">obrigatório</td><td style="width: 37.87%; height: 31px;">Esse é o **campo principal**, troque esse parâmetro pelo id do campo que será digitado o CEP</td><td style="width: 21.1621%;"> </td></tr><tr style="height: 31px;"><td style="width: 17.886%; height: 31px;">uf\_sigla</td><td style="width: 23.0818%;">pode estar em branco</td><td style="width: 37.87%; height: 31px;">Troque esse parâmetro pelo id do campo que deve ser preenchido a **SIGLA do Estado**

</td><td style="width: 21.1621%;">SP

</td></tr><tr style="height: 31px;"><td style="width: 17.886%; height: 31px;">uf\_nome</td><td style="width: 23.0818%;">pode estar em branco</td><td style="width: 37.87%; height: 31px;">Troque esse parâmetro pelo id do campo que deve ser preenchido com o nome completo do **Estado**</td><td style="width: 21.1621%;">São Paulo</td></tr><tr style="height: 31px;"><td style="width: 17.886%; height: 31px;">logradouro</td><td style="width: 23.0818%;">pode estar em branco</td><td style="width: 37.87%; height: 31px;">Troque esse parâmetro pelo id do campo que deve ser preenchido com o **Logradouro (Avenida, Rua etc..)**</td><td style="width: 21.1621%;">Avenida Paulista</td></tr><tr style="height: 31px;"><td style="width: 17.886%; height: 31px;">bairro</td><td style="width: 23.0818%;">pode estar em branco</td><td style="width: 37.87%; height: 31px;">Troque esse parâmetro pelo id do campo que deve ser preenchido com o **Bairro**</td><td style="width: 21.1621%;">Bela Vista</td></tr><tr style="height: 31px;"><td style="width: 17.886%; height: 31px;">cidade</td><td style="width: 23.0818%;">pode estar em branco</td><td style="width: 37.87%; height: 31px;">Troque esse parâmetro pelo id do campo que deve ser preenchido com a **Cidade**</td><td style="width: 21.1621%;">São Paulo</td></tr><tr style="height: 31px;"><td style="width: 17.886%; height: 31px;">numero\_de\_ate</td><td style="width: 23.0818%;">pode estar em branco</td><td style="width: 37.87%; height: 31px;">Troque esse parâmetro pelo id do campo que deve ser preenchido com a **Número**

<span style="color: #ff0000;">**Importante**: esse campo não deve ter máscara numérica, pois ele retorna um intervalo De XXX até YYY</span>

</td><td style="width: 21.1621%;">de 1047 a 1865 - lado ímpar</td></tr><tr><td style="width: 17.886%;">ddd\_da\_regiao</td><td style="width: 23.0818%;">pode estar em branco</td><td style="width: 37.87%;">Troque esse parâmetro pelo id do campo que deve ser preenchido com o **DDD** da região, por exemplo, no caso de São Paulo, ele retornará 11</td><td style="width: 21.1621%;">11</td></tr></tbody></table>

**5. Publique o seu formulário e teste.**

 **Pronto**, já deve estar funcionando.

### Callbacks para customização avançada:

Existem 3 callbacks que você pode chamar no Javascript:

- callback\_before - Antes de fazer a busca -
- callback\_onSucess - No sucesso do retorno
- callback\_onError - No Erro da busca

Abaixo está o exemplo do código que você pode utilizar

```JavaScript
formContext.buscaCEP.configurar(
    'id_campo_cep',
    {
        uf_sigla: 'id_do_campo_uf_sigla',
        uf_nome: 'id_do_campo_uf_nome',
        logradouro: 'id_do_campo_logradouro',
        bairro: 'id_do_campo_bairro',
        cidade: 'id_do_campo_cidade',
        numero_de_ate: 'id_do_campo_numero_de_ate',
        ddd_da_regiao: 'id_do_campo_ddd_da_regiao'
    },
    {        
        callback_before: function() {
            alert('before')
        },
        callback_onSucess: function (dados) {
            alert('callback_onSucess')
            console.log(dados)
        },
        callback_onError: function () {
            alert('error')
        }

    }
);


```

Ficou alguma dúvida ? Fale com a gente

# Automatizar a criação de tarefas em um Quadro de Tarefas ao salvar um formulário

O agilityflow através de sua Regras de Negócios pré-definidas, consegue te ajudar na automatização de processos.  
No vídeo abaixo apresentamos como criar uma tarefa em um quadro, com data de entrega e responsável ao salvar um formulário.

<iframe allowfullscreen="allowfullscreen" height="426" src="//www.youtube.com/embed/HrdOOIHTdHc" width="760"></iframe>

# Problema de acentuação no retorno de um CSHtml que é usado com Javacript

Em algumas situações será necessário tratar caso a caso a acentuação de textos no CSHTML.  
Para isso utilize a função nativa do .NET (C#):

`Html.Raw(...)`

Exemplo de uso, imaginamos que toda vez que o usuário entrar em um formulário a descrição do produto seja apresentado em um alert em javascript:

Para isso, criamos um cshtml, e adicionamos no formulário com o seguinte código.

```C#
@{
    /*
     * FUNÇÃO EM C# PARA BUSCAR A DESCRIÇÃO NO BANCO DE DADOS
     */
    var id_produto = Model.FormularioCamposPreenchidos["produto"];
	var descricao = "";
    if(id_produto != null && id_produto.ToString() != string.Empty){
        
        var query = @"select isnull(p.descricao,'') descricao from x_tbl_produtos p where p.deletado = 0 and p.id = '"+id_produto+"' ";
        var dt = await PageContext.GetDataTableAsync(query);

        if(dt.Rows.Count > 0)
        {
            var dr = dt.Rows[0];           
            descricao = dr["descricao"].ToString().Replace("'","");
        }
    }

   /*
     * ABAIXO ESTÁ A FUNÇÃO EM JAVASCRIPT APRESENTAR A DESCRIÇÃO EM UM ALERT
     */
}
<script>
    DOM.ready(function () {
    	 //nesse momento eu quero apresenta um alert com a descrição do produto, para garantir que a acentuação esteja correta, utilizo Html.Raw
         alert('@Html.Raw(descricao)');
    });
</script>


```

# Database Performance



# SQL Server - Performance / Index

Help about order by index:

[https://www.mssqltips.com/sqlservertip/1337/building-sql-server-indexes-in-ascending-vs-descending-order/](https://www.mssqltips.com/sqlservertip/1337/building-sql-server-indexes-in-ascending-vs-descending-order/)

Nonclustered Indexa

[https://learn.microsoft.com/en-us/sql/relational-databases/indexes/create-nonclustered-indexes?view=sql-server-ver16](https://learn.microsoft.com/en-us/sql/relational-databases/indexes/create-nonclustered-indexes?view=sql-server-ver16)

# Sincronizaçao de Contatos com a sua conta no Google

**Sincronização de Contatos no AgilityFlow com o Google Contatos**

O AgilityFlow oferece uma funcionalidade avançada que permite aos usuários realizar a sincronização de seus contatos de forma prática e eficiente com o Google Contatos. Essa integração simplifica o gerenciamento de informações de contatos, proporcionando uma experiência mais fluída e organizada para os usuários.

**Como funciona a integração com o Google Contatos no AgilityFlow:**

1. **Acesso à Configuração:** Ao acessar as configurações do AgilityFlow, os usuários encontrarão a opção de integração com o Google Contatos. Essa seção é projetada para ser intuitiva, facilitando a configuração da sincronização.
2. **Autorização do Google:** Para iniciar o processo de integração, será necessário conceder permissões ao AgilityFlow para acessar os contatos no Google. Ao clicar na opção de sincronização, os usuários serão redirecionados para a tela de consentimento do Google.
    
    **Tela de Consentimento:** Nessa tela, o usuário verá uma descrição clara das permissões que o AgilityFlow solicita para realizar a sincronização de contatos. Isso pode incluir acesso básico a informações de contatos, como nomes e endereços de e-mail. O usuário deve revisar essas permissões e, se concordar, autorizar a integração.
3. **Configuração de Sincronização:** Após a autorização, os usuários podem personalizar as configurações de sincronização de contatos. Isso pode incluir opções para escolher grupos específicos de contatos a serem sincronizados, definir a frequência da sincronização automática, e outras preferências personalizadas.
4. **Sincronização Automática e Manual:** Uma vez configurada, a sincronização pode ocorrer automaticamente em intervalos definidos ou ser iniciada manualmente pelos usuários. Isso garante flexibilidade para atender às necessidades individuais de cada usuário.

Essa integração simplificada com o Google Contatos no AgilityFlow proporciona uma gestão eficiente dos contatos, eliminando a necessidade de atualizações manuais e oferecendo uma visão unificada e atualizada de todas as informações de contato. A interface amigável e a transparência no processo de consentimento garantem uma experiência de usuário segura e descomplicada.

<p class="callout warning">**Importante:** o agilityflow não remove nenhum contato da sua lista do Google Contatos e não atualiza nenhum contato que não tenha sido gerado pela nossa base de dado</p>

# Bulk Update - Atualização de dados em Massa

  
Com o exemplo abaixo é possível atualizar varios dados de um ou mais forms com apenas 1 clique.

##### Criar um form com as informações que estarão no **Where** do Bulk Update e também os campos que deverão ser atualizados.

Exemplo:

![](https://wiki.agilityflow.io/uploads/images/gallery/2024-03-Mar/scaled-840-0/image-1710517405846.png)

##### Criar uma regra de negócio ao "Salvar" da seguinte forma:

![](https://wiki.agilityflow.io/uploads/images/gallery/2024-03-Mar/scaled-840-0/image-1710517460238.png)

##### Abaixo está o código C# para colocar no item de programação da Regra de Negócio(acima) responsável por executar o Bulk Update (Atualização em massa):

<p class="callout danger">**IMPORTANTÍSSIMO**: os scripts do SqlScript, atualizam o registro na RAIZ, isso é, **direto no banco de dados**, sendo assim, não executa nenhuma trigger, regra de negocio, controle de alteração, log de alteração etc.. que esteja vinculado(a) aos dados que estão sendo atualizados. **TENHA CUIDADO.**</p>

<p class="callout danger">**ATENÇÃO**: as informações dos formulários são sempre gravados em 2 tabelas. (1) tbl\_formulario e (2) a tabela "oficial" de cada estrutura de formulário, então é OBRIGATÓRIO, atualizar os dados nas 2 estruturas conforme exemplo abaixo. Na tbl\_formulario é criado um JSON com todos os dados, então o que vc precisa atualizar é a propriedade dentro do json do formulario que fica na coluna tbl\_formulario **frm\_json (o exemplo abaixo mostra como fazer essa atualização)**</p>

```C#
public async Task ExecuteAsync()
{                
    var where_status = FormContext.GetValue("where_status");
    var organization = FormContext.GetValue("organization");
    var update_to_status  = FormContext.GetValue("update_to_status");
    var update_to_substatus  = FormContext.GetValue("update_to_substatus");

    /*
     *  O AgilityFlow grava todas as informações em JSON na tabela TBL_FORMULARIO
     *  e também grava na tabela única da entidade.
     *  Para fazer o bulk update, é necessário atualizar as 2 tabelas.
     *  Importante também registrar que esse procedimento não executará nenhuma regra de negócio da aplicação.
     */

    // SQL update para atualizar o JSON na tbl_formulario
    var sql_tbl_form = @$"
        UPDATE tbl_formulario
        SET frm_json = jsonb_set(
                        jsonb_set(frm_json::jsonb, '{{status}}', to_jsonb(@update_to_status)),
                        '{{sub_status}}', to_jsonb(@update_to_substatus)
                     )
        WHERE frm_id IN (
            SELECT id FROM x_tbl_message_queue 
            WHERE organization = @organization 
            AND status = @where_status
        );";

    // SQL update para atualizar na tabela única da entidade 
    var sql_tbl_message = @$"
        UPDATE x_tbl_message_queue 
        SET status = @update_to_status, sub_status = @update_to_substatus  
        WHERE organization = @organization 
        AND status = @where_status;";

    var sql = $"{sql_tbl_form} {sql_tbl_message}";

    // Criando os parâmetros explicitamente
    var parameters = new DbParameter[]
    {
        new NpgsqlParameter("@update_to_status", update_to_status),
        new NpgsqlParameter("@update_to_substatus", update_to_substatus),
        new NpgsqlParameter("@organization", organization),
        new NpgsqlParameter("@where_status", where_status)
    };

    await FormContext.SqlScript.ExecuteAsync(sql, parameters);
}

```

# Timezone (Fuso Horario do sistema)

<p class="callout info">A plataforma pode ser configurada para visualizar as **horas em qualquer Timezone**</p>

O **servidor** está configurado **SEMPRE** para **UTC**.

O **banco de dados** grava todas as informações **SEMPRE** como **UTC**.

A plataforma pode ser configurada para visualizar as horas em qualquer Timezone (a nível de tenant).

Cada usuario pode ter o seu próprio Timezone para visualizaão dos dados e a plataforma também terá um timezone padrão.

Por exemplo. Se sua equipe está em São Paulo - Brasil e outra em NY - Estados Unidos, vc pode configurar uma timezone padrão para a plataforma, exemplo, America/Sao\_Paulo e também pode configurar para que cada usuario visualize a hora de acordo com sua localidade. Independente da forma que visualizará a informação será salva no banco de dados como UTC.

Importante dizer é que no **C#**, em caso de uso do `DateTime.Now` ou derivados. A data sempre estará em UTC. Para converter, use a extensão `.ToUserTimeZone`

Exemplo:

```C#
//exemplo: retorna 22/07/2024 22:37:00
var utcDate = DateTime.Now; 

//exemplo: caso o TimeZone do user seja America/Sao_Paulo (-3) retornaria 22/07/2024 19:37:00
var userTimezoneDate = DateTime.Now.ToUserTimeZone(); 
```

#### Api e Api User

<p class="callout info">Nas execuções de API sempre prevalecerá o Timezone definido no momento do cadastrado no User API</p>

Em caso de Api, você pode definir o Timezone da execução no cadastro do **Usuario de API,** será esse timezone que o sistema considerará ao executar uma API

**Acesse o Cadastro de Usuário de Api (Api User) e defina o timezone como na imagem abaixo:**

![](https://wiki.agilityflow.io/uploads/images/gallery/2024-07-Jul/scaled-840-0/image-1721682431281.png)

#### Programação na API com C# (Custom code)

Na Api **C#**, em caso de uso do `DateTime.Now` ou derivados. A data sempre estará em UTC. Para converter para a Timezone do User que está executando a API, utilize a extensão `.ToUserTimeZone` como no exemplo abaixo.

```C#
//exemplo: retorna 22/07/2024 22:37:00
var utcDate = DateTime.Now; 

//exemplo: caso o TimeZone do user seja America/Sao_Paulo (-3) retornaria 22/07/2024 19:37:00
var userTimezoneDate = DateTime.Now.ToUserTimeZone(); 
```

No método C# `ApiContext.SaveEntityAsync`, o sistema automaticamente irá converter as datas recebidas por parametro para UTC no momento de salvar no banco de dados, então é importante que a API receba a data no Timezone definido nas configurações do Usuário de API. Exemplo:

Se vc tem uma entidaide chamada Tarefa, e nessa tarefa você tem um campo de Data de entrega que vc gostaria que fosse a data 27/12/2024 23:55:55 no horario de São Paulo.

1\. Você deve configurar o seu **Usuario de API** para ter o TimeZone de **São Paulo.**

2\. Você deve mandar a data com o horario **27/12/2024 23:55:55**

3\. Você não deve se preocupar com a conversão para UTC ao salvar no banco de dados, pois a conversão será feita automaticamente pelo sistema.

# Alterar via C# o valor de um campo ao salvar um formulário

Caso vc precise aplicar algumas regras como mudar o valor de um campo via C# ao salvar um formulário, você pode aplicar as seguintes regras:

Crie uma regra como na imagem abaixo

![](https://wiki.agilityflow.io/uploads/images/gallery/2024-07-Jul/scaled-840-0/image-1722351854154.png)

Dentro da regra, adicione uma opção de Programação via C# como na imagem abaixo

![](https://wiki.agilityflow.io/uploads/images/gallery/2024-07-Jul/scaled-840-0/image-1722351884727.png)

Esse é um código de exemplo:

```C#
// Declaração padrão do método assíncrono chamado ExecuteAsync
public async Task ExecuteAsync(){                
                
    // Verifica se NAO é um formulario novo
    if(!IsNovoFormulario){
       
        // Declaração de uma variável chamada new_sub_status e atribui a ela o valor enviado pelo usuario naquele momento
        var new_sub_status = FormContext.GetValue("sub_status");
        // Declaração de uma variável chamada old_sub_status e inicializa com uma string vazia que colocaremos a informação antiga que ja constava do banco de dados
        var old_sub_status = "";
        
        // Cria uma lista de parâmetros para a consulta SQL (Postgresql)
        var paramsQuery = new List<NpgsqlParameter>();
        // Adiciona um novo parâmetro NpgsqlParameter à lista com o nome "@frm_id" e o valor IdFormulario
        paramsQuery.Add(new NpgsqlParameter("@frm_id", IdFormulario));
        
        // Declaração de uma string contendo a consulta SQL
        var sql = "select sub_status from x_tbl_message_queue_sub_status where id = @frm_id limit 1 ";
        // Executa a consulta SQL de forma assíncrona e armazena o resultado em um DataTable
        var dt = await FormContext.GetDataTableAsync(sql, paramsQuery.ToArray());
     
        // Itera sobre as linhas do DataTable encontrada (sempre será 1, limit 1
        foreach (DataRow dr in dt.Rows)
        {
            // Verifica se o valor da coluna "sub_status" não é DBNull
            if (dr["sub_status"] != DBNull.Value)
                // Atribui o valor da coluna "sub_status" à variável old_sub_status
                old_sub_status = dr["sub_status"].ToString();
        }
        //criei aqui uma regrinha simples só pra demonstração:
      
        // Verifica se old_sub_status termina com "1"
        if(old_sub_status.EndsWith("1")){
            // Define o valor de "sub_status" no FormContext com new_sub_status concatenado com " 2"
            FormContext.SetValue("sub_status", new_sub_status + " 2");
        }else{
            // Define o valor de "sub_status" no FormContext com new_sub_status concatenado com " 1"
            FormContext.SetValue("sub_status", new_sub_status + " 1");
        }
 
    } // Fim do bloco if
                
} // Fim do método ExecuteAsync

```

# Alerta para o usuario ao salvar um formulário (usando c#)

Caso vc precise aplicar algumas regras como enviar uma msg de alerta para o usuario ao salvar um formulário, você pode aplicar as seguintes regras:

<p class="callout warning">Ao enviar uma mensagem de Warning usando o FormContext.WarningMessage("Mensagem de exemplo") o sistema interrompe o salvamento</p>

Crie uma regra como na imagem abaixo

![](https://wiki.agilityflow.io/uploads/images/gallery/2024-07-Jul/scaled-840-0/image-1722352409072.png)

Dentro da regra, adicione uma opção de Programação via C# como na imagem abaixo

![]()

```C#
            public async Task ExecuteAsync(){                

				FormContext.WarningMessage("Mensagem de exemplo");
                                    
            }
```

# Erro: Can't write CLR type System.String with handler type UuidHandler

Alguns campos no Postgresql são do tipo UUID, como LIsta Dinamica, Autocomplete, Radio button, entre outros.

Se vc tentar enviar um valor em branco ou diferente de um UUID para esse tipo de campo pode aparecer essa mensagem.

Obrigatoriamente enviar um valor no formato UUID / GUID

Sugestão:

Se for por exemplo pra deixar um status em branco.

Cria um status "\[em branco\]" na tabela de relacionamento e usa o ID desse novo status para salvar no campo UUID

# Evento javascript após o subsmit post do formulario (onAfterPostEvent)

Esse evento dispara sempre após o submit de um formulário.

**Nome do evento:**  onAfterPostEvent

#### Como escutar o evento de retorno de um submit no form?

```JavaScript

  //ouvindo o evento de retorno
  document.addEventListener('onAfterPostEvent', function(event) {

    //para validar se foi sucesso ou falha, usar a seguinte variavel
    console.log('success', event.detail.success);

    //enviamos mais alguns detalhes
    console.log('response', event.detail.response);
    
    //formAction, com essa variavel é possivel saber se foi um post para salvar, deletar, descartar rascunho, salvar rascunho etc..
    //olhar todas as opções de formAction na documentação mais abaixo
    console.log('formAction', event.detail.formAction);
        

  });

```

#### Como forçar o salvamento e escutar o evento de retorno de um submit no form?

```JavaScript
function ForceSaveForm(){

  //ouvindo o evento de retorno
  document.addEventListener('onAfterPostEvent', function(event) {

    //para validar se foi sucesso ou falha, usar a seguinte variavel
    console.log('success', event.detail.success);

    //enviamos mais alguns detalhes
    console.log('response', event.detail.response);
    
    //formAction, com essa variavel é possivel saber se foi um post para salvar, deletar, descartar rascunho, salvar rascunho etc..
    //olhar todas as opções de formAction na documentação mais abaixo
    console.log('formAction', event.detail.formAction);
        

  });
  
  
  //solicitar o salvamento do iframe pai
  //ESSA FUNÇÃO SÓ É NECESSARIO CASO VOCÊ QUERIA FORÇAR O SALVAR
  formContext.form.save();    


}
```

#### Como forçar o salvamento e escutar o evento de retorno de um submit no form pai?

```JavaScript
function SaveParentForm(){

  //recuperando o iframe pai
  var iframePai = getIframePaiIntance()

  //ouvindo o evento de retorno
  iframePai.document.addEventListener('onAfterPostEvent', function(event) {

    //para validar se foi sucesso ou falha, usar a seguinte variavel
    console.log('success', event.detail.success);

    //enviamos mais alguns detalhes
    console.log('response', event.detail.response);
    
    //formAction, com essa variavel é possivel saber se foi um post para salvar, deletar, descartar rascunho, salvar rascunho etc..
    //olhar todas as opções de formAction na documentação mais abaixo
    console.log('formAction', event.detail.formAction);
        

  });
  
  //solicitar o salvamento do iframe pai 
  //ESSA FUNÇÃO SÓ É NECESSARIO CASO VOCÊ QUERIA FORÇAR O SALVAR
  iframePai.formContext.form.save();

}
```

#### O parametro numérico "formAction" que retorna no evento pode ser:

<div id="bkmrk-action_salvar-%3D-1%3B-a">- ACTION\_SALVAR = 1;
- ACTION\_SALVAR\_RASCUNHO = 2;
- ACTION\_DESCARTAR\_RASCUNHO = 3;
- ACTION\_APROVAR = 4;
- ACTION\_REPROVAR = 5;
- ACTION\_RETORNAR = 6;
- ACTION\_DELETAR = 7;
- ACTION\_SALVAR\_FORMULARIO\_FILHO = 8;
- ACTION\_DELETAR\_FORMULARIO\_FILHO = 9;
- ACTION\_DESCARTAR\_ALTERACOES\_FORMULARIO\_FILHO = 10;
- ACTION\_SOLICITAR\_TROCA\_APROVADOR\_ETAPA\_DINAMICA = 11;
- ACTION\_SALVAR\_DEFINICAO\_APROVADOR\_ETAPA\_DINAMICA = 12;

</div><div id="bkmrk-"></div><div id="bkmrk--0"></div><div id="bkmrk--1"></div><div id="bkmrk--2"></div><div id="bkmrk--3"></div><div id="bkmrk--4"></div><div id="bkmrk--5"></div><div id="bkmrk--6"></div><div id="bkmrk--7"></div><div id="bkmrk--8"></div>

# Forçar o salvamento de um Form

#### Como forçar o salvamento no submit do form

```JavaScript
function forceSaveForm(){
  
    //solicitar o salvamento 
  formContext.form.save();    

}
```

#### Como forçar o salvamento no submit do form **pai**

```JavaScript
function forceSaveParentForm(){
  
  var iframePai = getIframePaiIntance()
  
  //solicitar o salvamento do iframe pai 
  iframePai.formContext.form.save();    

}
```

#### Como forçar o salvamento e escutar o evento de retorno

```JavaScript
function forceSaveForm(){
  
  
    //ouvindo o evento de retorno
  document.addEventListener('onAfterPostEvent', function(event) {

    //para validar se foi sucesso ou falha, usar a seguinte variavel
    console.log('success', event.detail.success);

    //enviamos mais alguns detalhes
    console.log('response', event.detail.response);
    
    //formAction, com essa variavel é possivel saber se foi um post para salvar, deletar, descartar rascunho, salvar rascunho etc..
    //olhar todas as opções de formAction na documentação mais abaixo
    console.log('formAction', event.detail.formAction);
        

  });
  
  
  
    //solicitar o salvamento do iframe pai 
  formContext.form.save();    

}
```

#### O parametro numérico "formAction" que retorna no evento são:

<div id="bkmrk-action_salvar-%3D-1%3B-a">- ACTION\_SALVAR = 1;
- ACTION\_SALVAR\_RASCUNHO = 2;
- ACTION\_DESCARTAR\_RASCUNHO = 3;
- ACTION\_APROVAR = 4;
- ACTION\_REPROVAR = 5;
- ACTION\_RETORNAR = 6;
- ACTION\_DELETAR = 7;
- ACTION\_SALVAR\_FORMULARIO\_FILHO = 8;
- ACTION\_DELETAR\_FORMULARIO\_FILHO = 9;
- ACTION\_DESCARTAR\_ALTERACOES\_FORMULARIO\_FILHO = 10;
- ACTION\_SOLICITAR\_TROCA\_APROVADOR\_ETAPA\_DINAMICA = 11;
- ACTION\_SALVAR\_DEFINICAO\_APROVADOR\_ETAPA\_DINAMICA = 12;

</div><div id="bkmrk-"></div><div id="bkmrk--0"></div><div id="bkmrk--1"></div><div id="bkmrk--2"></div><div id="bkmrk--3"></div>

# Listagem: Como habiltar para atualizar a cada X segundos (Auto Refresh, Atualização Automática, Atualização Recorrente)

Para habilitar a atualização recorrente a cada X segundo utilize a função javascript abaixo dentro do formulário:

```JavaScript
listContext.table.setRecurrentRefresh(15);
```

#####  

ou

```JavaScript
listContext.table.setAutoRefresh(15);
```

#####  

##### Exemplo de como ficaria a configuração para atualizar a cada 15 segundos na listagem de um Formulário

![](https://wiki.agilityflow.io/uploads/images/gallery/2024-08-Aug/scaled-840-0/image-1723563986720.png)

# Ativar e Inativar campos do formulario via Javascript

<div id="bkmrk-as-fun%E3%A7oes-abaixo-t">  
<div>As funçoes abaixo te auxiliam a inativar e ativar os campos de um formulario:</div>  
  
<div>**Inativar um campo:**</div>`formcontext.field.disable("idDoCampo")`   
  
<div>**Ativar um campo:**</div><div>`formcontext.field.enable("campo")`</div>  
<div>**Inativar mais de um campo:**</div><div>`formcontext.field.disable(["campo","campo","campo"])`</div>  
<div>**Ativar mais de um campo:**</div><div>`formcontext.field.enable(["campo","campo","campo"])`</div>  
<div>**Inativar todos os campos:**</div><div>`formcontext.field.disableAll()`</div>  
<div>**Ativar todos os campos:**</div><div>`formcontext.field.enableAll()`</div></div>

# Esconder e Mostrar campos do formulario via Javascript (visível e invisível)

<div id="bkmrk-as-fun%E3%A7oes-abaixo-t">  
<div>As funçoes abaixo te auxiliam a esconder e mostrar os campos de um formulario:</div>  
  
<div>**Esconder um campo:**</div>`formcontext.field.hide("idDoCampo")`   
  
<div>**Mostrar um campo:**</div><div>`formcontext.field.show("campo")`</div>  
<div>**Esconder mais de um campo:**</div><div>`formcontext.field.hide(["campo","campo","campo"])`</div>  
<div>**Mostrar mais de um campo:**</div><div>`formcontext.field.show(["campo","campo","campo"])`</div>  
<div>**Esconder todos os campos:**</div><div>`formcontext.field.hideAll()`</div>  
<div>**Mostrar todos os campos:**</div><div>`formcontext.field.showAll()`</div></div>

# Esconder, Mostrar e Remover o toolbar de botões do formulario via Javascript

<div id="bkmrk-as-fun%E3%A7%E3%B5es-abaixo-"><div>As funções abaixo te auxiliam a esconder e mostrar e remover o toolbar de botões de um formulario:</div></div><div id="bkmrk-"></div><div id="bkmrk-o-toolbar-%E3%A9-%E3%A9-essa">O toolbar é é essa area onde estão os boõtes do formulário, como na imagem abaixo onde aparecem os Botões Salvar, Salvar em Rascunho e Consultar.</div>![](https://wiki.agilityflow.io/uploads/images/gallery/2024-09-Sep/scaled-840-0/image-1725386235303.png)

**Para Esconder a barra de botões:**   
`formcontext.form.toolbar.hide()`

**Para Mostrar a barra de botões:**  
`formcontext.form.toolbar.show()`

**Para Remover a barra de botões:**  
`formcontext.form.toolbar.remove()`

# Colocar ou Retirar a Obrigatoriedade de um Campo no Formulário via JavaScript

Nesta seção, você aprenderá a marcar um campo como obrigatório e a remover ou restaurar essa obrigatoriedade conforme necessário, utilizando JavaScript.

<p class="callout danger">É importante para todo o campo que você deseja trabalhar com obrigatoriedade, que ele esteja por padrão marcado como obrigatório no formulário, sendo assim, acesse as configurações do formulario, acesse o campo e o marque como Obrigatório na seção de validação.</p>

#### Pré requisito para uso das funções descritas aqui nesse documento:

Para todo o campo que você deseja trabalhar com obrigatoriedade condicional, que ele esteja por padrão marcado como obrigatório no formulário, sendo assim, acesse as configurações do formulario, acesse o campo e o marque como Obrigatório na seção de validação.

### **Como funciona?** 

Para atingir o objetivo de tirar ou remover a obrigatoriedade em deteminada situação, vou deve usar as funções abaixo, lembrando que por padrão o campo deve estar inicialmente marcado como Obrigatório

#### Removendo a Obrigatoriedade de um Campo

Se houver a necessidade de remover a obrigatoriedade de um campo em determinadas situações, você pode utilizar a função `ignoreRequired` do objeto `formContext.field.required`. Esta função desativa temporariamente a obrigatoriedade de um campo.

Exemplo de uso no Javascript:  
`formContext.field.required.ignoreRequired("campoTexto");`

Neste exemplo, o campo de texto identificado por `"campoTexto"` deixará de ser obrigatório.

####  

#### Restaurando a Obrigatoriedade de um Campo

Se, em algum momento, precisar restaurar a obrigatoriedade de um campo, utilize a função `unsetIgnoreRequired` do mesmo objeto. Isso faz com que o campo volte a ser obrigatório.

<div id="bkmrk-exemplo-de-uso-no-ja-0"><div>Exemplo de uso no Javascript:</div><div>`formContext.<span class="hljs-property">field</span>.<span class="hljs-property">required</span>.<span class="hljs-title function_">unsetIgnoreRequired</span>(<span class="hljs-string">"campoTexto"</span>);`</div></div>Este código restaura a obrigatoriedade do campo de texto identificado por `"campoTexto"`.

# Verificação de Estado de Formulários. Como saber se é um novo formulário ou um rascunho via javascript?

Esta documentação explica como utilizar as funções `formContext.form.isNew()` e `formContext.form.isDraft()` para determinar o estado de um formulário, ou seja, se ele é um novo formulário, um rascunho ou uma edição de um rascunho.

<p class="callout warning">Essa funçao javascript deve ser utilizado dentro de um formulario na customização de código em Javascript.</p>

## Objetivo

O objetivo dessas funções é ajudar a identificar o estado atual do formulário e executar ações específicas com base em seu estado. Os estados podem ser:

- **Novo Formulário**: O formulário acabou de ser criado e nunca foi salvo.
- **Rascunho**: O formulário foi salvo como rascunho e pode estar em edição.
- **Edição de um Rascunho**: O formulário está sendo editado e é uma versão salva anteriormente como rascunho.

## Funções Utilizadas

### `formContext.form.isNew()`

Essa função retorna um valor booleano que indica se o formulário atual é **novo**.

- **true**: Se o formulário é novo (nunca foi salvo).
- **false**: Se o formulário já foi salvo previamente.

### `formContext.form.isDraft()`

Essa função também retorna um valor booleano e indica se o formulário está em **estado de rascunho**.

- **true**: Se o formulário é um rascunho.
- **false**: Se o formulário não é um rascunho.

## Exemplo de Uso

Aqui está um exemplo prático de como utilizar as funções `isNew()` e `isDraft()`:

```JavaScript
var isNewForm = formContext.form.isNew();
var isDraftForm = formContext.form.isDraft();

if(isNewForm){
    console.log('This is a new form');
}

if(isDraftForm){
    console.log('This is a draft form');
}

if(isNewForm && !isDraftForm){
    console.log('This is a new form and not a draft form');
}

if(!isNewForm && isDraftForm){
    console.log('This is an edition form and a draft form');
}

if(!isNewForm && !isDraftForm){
    console.log('This is an edition form and not a draft form');
}

```

### Explicação do Código

1. **Verificando se é um Novo Formulário:**
    
    ```JavaScript
    if (isNewForm) {
        console.log('This is a new form');
    }
    
    ```
    
    Aqui, se a função `isNew()` retornar `true`, significa que o formulário é novo e nunca foi salvo. O código exibe a mensagem "This is a new form".
2. **Verificando se é um Rascunho:**
    
    ```JavaScript
    if (isDraftForm) {
        console.log('This is a draft form');
    }
    
    ```
    
    Se a função `isDraft()` retornar `true`, significa que o formulário está em estado de rascunho. O código exibe a mensagem "This is a draft form".
3. **Verificando se o Formulário é Novo e Não é um Rascunho:**
    
    ```JavaScript
    if (isNewForm && !isDraftForm) {
        console.log('This is a new form and not a draft form');
    }
    
    ```
    
    Essa condição verifica se o formulário é novo (`isNewForm === true`) e não está em estado de rascunho (`isDraftForm === false`). Neste caso, o código exibe "This is a new form and not a draft form".
4. **Verificando se o Formulário é uma Edição de um Rascunho:**
    
    ```JavaScript
    if (!isNewForm && isDraftForm) {
        console.log('This is an edition form and edition of a draft form');
    }
    
    ```
    
    Essa condição verifica se o formulário já foi salvo antes (`isNewForm === false`) e está em estado de rascunho (`isDraftForm === true`). Ou seja, é uma edição de um formulário previamente salvo como rascunho.
5. **Verificando se o Formulário é uma Edição (sem rascunho):**
    
    ```JavaScript
    if (!isNewForm && !isDraftForm) {
        console.log('This is an edition form and not a draft form');
    }
    
    ```
    
    Essa condição verifica se o formulário já foi salvo antes (`isNewForm === false`) e não está em estado de rascunho (`isDraftForm === false`). Ou seja, é uma edição de um formulário e nao está salvo como rascunho.

##  

## Resumo

Essas duas funções são essenciais para verificar o estado atual de um formulário, e a partir delas, você pode:



- Saber se o formulário é novo e nunca foi salvo.
- Determinar se o formulário foi salvo como rascunho.
- Diferenciar entre novos formulários, rascunhos, edições e edições de rascunhos.

Com base nessas informações, você pode executar ações específicas, como mostrar mensagens, habilitar/desabilitar funcionalidades, ou realizar diferentes tipos de validações.

# Como permitir um usuário Gerenciar Usuário, Perfil e Grupo de Usuario não tendo o perfil MASTER

Crie um perfil com as funcionalidades abaixo e associe o perfil ao usuario que terá essa permissão:

- Funcionalidades Por PErfil de Acesso
- Grupo de Usuario
- Perfil de acesso
- Usuário

![](https://wiki.agilityflow.io/uploads/images/gallery/2024-09-Sep/scaled-840-0/image-1725728075959.png)

Ao logar, o usuario com esse perfil associado visualizará as opções de Gerenciamento de Usuario, Perfil e Grupo de usuario dentro do Menu Segurança e Acesso, como na imagem abaixo:

![](https://wiki.agilityflow.io/uploads/images/gallery/2024-09-Sep/scaled-840-0/image-1725728087536.png)

# Como customizar a mensagem de sucesso ou falha após o submit post do Formulário (via javascript)

Acesse a customização de um formulário. Ao acessar, entre na Aba "Configurações", em seguida, expanda "Outras Configurações" e defina um nome para a função javascript que será executada após o post.

O nome da função javascript deve ser preenchida no campo "**Executar a função Javascript abaixo após salvar ou executar qualquer ação bem-sucedida no formulário:"** como mostra em azul na imagem abaixo.

![](https://wiki.agilityflow.io/uploads/images/gallery/2024-09-Sep/scaled-840-0/image-1725736529593.png)

zoom do campo da imagem anterior:

![](https://wiki.agilityflow.io/uploads/images/gallery/2024-09-Sep/scaled-840-0/image-1725736687373.png)

No exemplo, foi definido o nome "executeAfterPost" para o nome da função javascript.

Abaixo segue um exemplo da função e a explicação comentada em cada linha.

<p class="callout warning">**ATENÇÃO**: nessa função é necessário testar se o formAction é a opção salvar. o formAction é retornado como parametro da função. Para checar utilize a função js **formContext.form.action.isSave(formAction)**</p>

```JavaScript
function executeAfterPost(formId, response, formAction) {
    
    //verifica se é o formAction de Salvar (essa função pode ser chamada em varios formAction, por isso é  imoprtante checar se é salvar)
    if (formContext.form.action.isSave(formAction)) {

        //testar se deu sucesso no envio do form
        if(response.success){
            
          	//funçao para desabilitar a mensagem nativa do sistema
        	formContext.form.disableNativeSuccessMsg();
          
            //colocar a msg de sucesso
            formContext.msg.success('Salvouu legal com sucesso', 'Sucesso');
          
        }
        
        
    }
}
```

# Estrutura de Armazenamento dos campos no banco de dados

No sistema, os campos são armazenados em dois locais diferentes, em um JSON com todos os campos juntos e na tabela da entidade.

1. **JSON do Formulário**
    
    
    - O sistema gera um JSON contendo todos os dados de cada formulário, incluindo os campos numéricos, inteiros e de data e hora, e armazena esse JSON na tabela `tbl_formulario`.
    - Esse JSON serve como um registro completo das informações enviadas pelo usuário, sendo útil também para auditoria de dados.
2. **Tabela da Entidade - Campo VARCHAR**
    
    
    - Este campo armazena o valor recebido em "string", sem conversões. O tipo VARCHAR foi mantido por questões de compatibilidade com o sistema legado.
3. **Tabela da Entidade - Campos tipados**
    
    
    - Campos booleanos, são gravados como smallint (0 ou 1), com exceção do campo "deletado", esse esta gravado como true or false
    - Campos com tipos específicos, como numéricos, inteiros e de data e hora, têm uma coluna adicional que armazena o valor tipado e convertido: 
        - **Numéricos e Inteiros**: Os campos numéricos possuem o sufixo `__number__` e os inteiros seguem a mesma estrutura, facilitando operações e consultas. Exemplo: `campo__number__`. O tipo do campo é numeric no postgresql
        - **Data e Hora (Datetime)**: Os campos de data e hora possuem o sufixo `__datetime__`. Exemplo: `campo__datetime__`. o tipo do campo é `date` para campos que sõ tem Data e `timestamp` para campos com date e hora

### Observações Importantes

- **Exibição de Dados**: Na listagem, é sempre utilizado o campo com o sufixo tipado (`__number__` ou `__datetime__`), pois ele contém o valor devidamente convertido, garantindo precisão nas operações.
- **Máscara de Formatação no Formulário**: No formulário de entrada de dados, uma máscara em JavaScript é aplicada ao `campo`, formatando o valor conforme o padrão do JSON. Essa máscara pode causar discrepâncias se houver uma incompatibilidade entre os formatos de entrada e o armazenamento no PostgreSQL.

### Possíveis Problemas e Soluções

- **Diferença no Valor Armazenado**: Para valores numéricos, caso o valor enviado pela API contenha vírgulas (por exemplo, "3,31"), pode ocorrer uma interpretação incorreta durante a conversão para o formato numérico, transformando o valor `3,31` em `331`.
- **Recomendações**: Nas Apis, e regras, sempre manter o padrao no formato ingles 99999.99 com ponto. Sugere-se validar e formatar os dados enviados para garantir que o sistema receba sempre o formato correto. A padronização dos dados de entrada evita diferenças entre os valores no campo VARCHAR e nos campos tipados com sufixo.

# Executar uma Api do proprio agilityflow dentro de um Form ou dentro de uma outra Api

### No FormContext

#### Chamando uma Api Post e <span style="text-decoration: underline;">**não**</span> aguardando a resposta <span style="color: #339966; background-color: #ccffcc;">**(Assincronamente)**.</span>

```C#
public async Task ExecuteAsync(){    
                
                
                 await FormContext.InternalApi.ExecutePostAsynchronouslyAsync("rest-api/teste", 
                            new { valorr= 334455.66, email="exemplo@email.com.br" },
                            new ExecutePostAsynchronouslyOptions() {
                                AuthUser = "MUDAR AQUI PELO API USER LOGIN",
                                AuthKey = "MUDAR AQUI PELO API USER KEY",
                            }); 
  
}
```

#### Chamando uma Api Post e aguardando a resposta <span style="color: #33cccc; background-color: #ccffff;">**(Sincronamente)**.</span>

```C#
public async Task ExecuteAsync(){    
                
                
                 var result = await FormContext.InternalApi.ExecutePostSynchronouslyAsync("rest-api/teste", 
                            new { valorr= 33445566.77, email="exemplo@email.com.br" },
                            new ExecutePostSynchronouslyOptions() {
                                AuthUser = "MUDAR AQUI PELO API USER LOGIN",
                                AuthKey = "MUDAR AQUI PELO API USER KEY",
                            });    
  
  				//verificar se foi sucesso ou nao
                var isSuccess = result.IsSuccess;
                
  				//se quiser o retorno no formato string
                var str = result.GetString();
  
  				//se quiser o retorno no formato Json
                var json = result.GetJson();
                            
                FormContext.Log($"isSuccess: {isSuccess} | - str: {str}" ,"debug");
  
}
```


### No PageContext

#### Chamando uma Api Post e <span style="text-decoration: underline;">**não**</span> aguardando a resposta <span style="color: #339966; background-color: #ccffcc;">**(Assincronamente)**.</span>

```C#
public async Task ExecuteAsync(){    
                
                
                 await PageContext.InternalApi.ExecutePostAsynchronouslyAsync("rest-api/teste", 
                            new { valorr= 334455.66, email="exemplo@email.com.br" },
                            new ExecutePostAsynchronouslyOptions() {
                                AuthUser = "MUDAR AQUI PELO API USER LOGIN",
                                AuthKey = "MUDAR AQUI PELO API USER KEY",
                            }); 
  
}
```

#### Chamando uma Api Post e aguardando a resposta <span style="color: #33cccc; background-color: #ccffff;">**(Sincronamente)**.</span>

```C#
public async Task ExecuteAsync(){    
                
                
                 var result = await PageContext.InternalApi.ExecutePostSynchronouslyAsync("rest-api/teste", 
                            new { valorr= 33445566.77, email="exemplo@email.com.br" },
                            new ExecutePostSynchronouslyOptions() {
                                AuthUser = "MUDAR AQUI PELO API USER LOGIN",
                                AuthKey = "MUDAR AQUI PELO API USER KEY",
                            });    
  
  				//verificar se foi sucesso ou nao
                var isSuccess = result.IsSuccess;
                
  				//se quiser o retorno no formato string
                var str = result.GetString();
  
  				//se quiser o retorno no formato Json
                var json = result.GetJson();
                            
                FormContext.Log($"isSuccess: {isSuccess} | - str: {str}" ,"debug");
  
}
```

###  

###  

### No ApiContext

<p class="callout warning">**IMPORTANTE**: Caso o usuário da API que está consumindo esta outra API tenha acesso a ambas, não será necessário fornecer os parâmetros AuthUser e AuthKey.</p>

#### Chamando uma Api Post e <span style="text-decoration: underline;">**não**</span> aguardando a resposta <span style="color: #339966; background-color: #ccffcc;">**(Assincronamente)**.</span>

```C#
public async Task RunAsync(){    
                
                
                 await ApiContext.InternalApi.ExecutePostAsynchronouslyAsync("rest-api/teste", 
                            new { valorr= 334455.66, email="exemplo@email.com.br" },
                            new ExecutePostAsynchronouslyOptions() {
                              
                            /* ATENÇÃO: Caso o usuário da API que está consumindo esta outra API
                            tenha acesso a ambas, não será necessário 
                            fornecer os parâmetros AuthUser e AuthKey.*/                              
                                AuthUser = "MUDAR AQUI PELO API USER LOGIN",
                                AuthKey = "MUDAR AQUI PELO API USER KEY",
                            }); 
  
}
```

#### Chamando uma Api Post e aguardando a resposta <span style="color: #33cccc; background-color: #ccffff;">**(Sincronamente)**.</span>

```C#
public async Task RunAsync(){    
                
                
                 var result = await ApiContext.InternalApi.ExecutePostSynchronouslyAsync("rest-api/teste", 
                            new { valorr= 33445566.77, email="exemplo@email.com.br" },
                            new ExecutePostSynchronouslyOptions() {
                              
                            /* ATENÇÃO: Caso o usuário da API que está consumindo esta outra API
                            tenha acesso a ambas, não será necessário 
                            fornecer os parâmetros AuthUser e AuthKey.*/                                
                                AuthUser = "MUDAR AQUI PELO API USER LOGIN",
                                AuthKey = "MUDAR AQUI PELO API USER KEY",
                              
                            });    
  
  				//verificar se foi sucesso ou nao
                var isSuccess = result.IsSuccess;
                
  				//se quiser o retorno no formato string
                var str = result.GetString();
  
  				//se quiser o retorno no formato Json
                var json = result.GetJson();
                            
                FormContext.Log($"isSuccess: {isSuccess} | - str: {str}" ,"debug");
  
}
```

# Forçar via Javascript o Salvamento do Formulário

#### Forçar o salvamento via Javascript:

`formContext.form.save()`

####  

#### Forçar o salvamento via Javascript:

`formContext.parentWindow.formContext.form.save()formContext.form.save()`

# Manipular o formulário "pai", dentro de um formulário filho

No formContext do javascript existe uma propriedade chamada `parentWindow` ou `parentFrame`:

`formContext.parentWindow`

Dessa forma você terá acesso a todas os javascript e objetos do formulário pai.

Por exemplo, para buscar um campo do formulario pai:

`var value = formContext.parentWindow.formContext.field.getValue("campoid")`

Para salvar o formulário pai via javascript:

`formContext.parentWindow.formContext.form.save()`

# Evento javascript ondataloaded na Lista Dinamica

No exemplo abaixo considere uma Lista Dinamica com o id "orcamento":

```javascript
$('#orcamento').on('ondataloaded', function (data) {

  var orcamento = formContext.field.getValue('orcamento');
  if (orcamento == "") {
  
  }

});
```

# Como criar itens / tarefas automaticamente nos Checklists dos formulários?

Com esse exemplo, vc será capaz de criar itens / tarefas na aba Checklists dos formulários.

Como na imagem abaixo:

[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-01/scaled-1680-/image.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-01/image.png)

Nesse exemplo, vamos inserir registros em 2 tabelas.

1. **<span style="text-decoration: underline;">tbl\_formulario\_checklist</span>** Essa tabela tabela conteém o nome do checklist e a relação com o formulario que será apresentado
2. <span style="text-decoration: underline;">**tbl\_formulario\_checklist\_item**</span> Essa tabela contém todas os itens de um checklist

No exemplo, eu criei 2 forms, sendo o form <span style="text-decoration: underline;">**Inspeção**</span> um Workflow e o <span style="text-decoration: underline;">**Inspeção Itens**</span> sendo filho do <span style="text-decoration: underline;">**Inspeção**</span>

<table border="1" id="bkmrk-inspe%C3%A7%C3%A3o-form-onde-a" style="border-collapse: collapse; width: 100%;"><colgroup><col style="width: 33.3333%;"></col><col style="width: 33.3333%;"></col><col style="width: 33.3333%;"></col></colgroup><tbody><tr><td>Inspeção</td><td>Form onde ao salvar será criada as task</td><td>x\_inspection</td></tr><tr><td>Inspeção Itens </td><td>Form onde está tudo que foi inspecionado.

Os itens que estiverem PENDING, será gerado uma tarefa no checklist do form ao aprovar.

</td><td>x\_inspection\_item</td></tr></tbody></table>

As etapas do Workflow são:

1. Solicitação de inspeção
2. Execução da Inspeção
3. **\[Business Rules\]** Criação do Checklist de Pendências
4. Execução da Lista de Pendências
5. Finalização

Abaixo está o código utilizado na Regra de Negócio do FormContext que deve foi adicionada dentro da etapa <span style="text-decoration: underline;">**\[Business Rules\] Criação do Checklist de Pendências**</span> do Workflow, logo após a etapa de Execução da Inspeção.

```c#
            public async Task ExecuteAsync(){                
                  
                
                var userId = FormContext.GetUsuarioLogadoId();
                var recordId = FormContext.FormId;
                var checklistId = System.Guid.NewGuid();
                var inspectionTypeId = Guid.Parse(FormContext.GetValue("inspection_type_id"));
                
               
               
                var paramsQuery = new List<NpgsqlParameter>();
                paramsQuery.Add(new NpgsqlParameter("@id", checklistId));
                paramsQuery.Add(new NpgsqlParameter("@formularioId", IdFormulario));
                paramsQuery.Add(new NpgsqlParameter("@recordId", recordId));
                paramsQuery.Add(new NpgsqlParameter("@userId", userId));
                paramsQuery.Add(new NpgsqlParameter("@inspectionTypeId", inspectionTypeId));
                
                await FormContext.SqlScript.ExecuteAsync(@"
                    insert into tbl_formulario_checklist (
                        id,
                        efr_id, 
                        frm_id,
                        tmp_form_id, 
                        nome, 
                        ordem, 
                        log_data_criacao,
                        log_usu_criacao
                    ) 
                    select  
                        @id, 
                        @formularioId, 
                        @recordId, 
                        uuid_generate_v4(), 
                        ""name"" || ' - verify while inspecting', 
                        1, 
                        CURRENT_DATE,  
                        @userId
                    from x_inspection_type where id = @inspectionTypeId limit 1
                    ", paramsQuery.ToArray());
                    
                    
                var paramsQueryItem = new List<NpgsqlParameter>();
                paramsQueryItem.Add(new NpgsqlParameter("@checklistId", checklistId));
                paramsQueryItem.Add(new NpgsqlParameter("@userId", userId));
                paramsQueryItem.Add(new NpgsqlParameter("@inspectionTypeId", inspectionTypeId));
                
                
                await FormContext.SqlScript.ExecuteAsync(@"
                    insert into tbl_formulario_checklist_item (
                        id,
                        id_checklist, 
                        checked,
                        nome, 
                        ordem, 
                        log_data_criacao,
                        log_usu_criacao
                    ) 
                    select uuid_generate_v4(), @checklistId, 0, ""name"", 1, CURRENT_DATE, @userId 
                    FROM x_inspection_item
                    where inspection_type_id = @inspectionTypeId and status = 'pending'
                    limit 200", paramsQueryItem.ToArray());
                
                
                
                
                
                
            }
```

# Customização e estilização dos botões do formulário

Através da tela de configuração do formulario, você pode customizar os icones, as cores e o local onde o botão pode aparecer em um formulário, e o resultado fica como o mostrado na imagem abaixo

[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-01/scaled-1680-/yLBimage.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-01/yLBimage.png)

# Como ocultar um campo do formulário quando ele estiver em modo público?

### Usando CSS

Suponhamos que você tenha um formulário chamado **Solicitação de Orçamento** e deseja ocultar os campos **Status** e **Identity** apenas quando esse Formulário estiver sendo apresentado no "modo/ambiente" **Público (Website, Form Público, Portal Público)**, basta aplicar o CSS abaixo.

Levando em consideração que na estrutura do formulário, todos os elementos que compõem os campos possuem a classe CSS no formato `.item-[id do campo]`. Isso significa que, para ocultar um campo específico, você pode utilizar essa classe no seletor CSS.

Quando o formulário estiver no modo público, a tag `<html>` conterá a classe `public-portal`. Com isso, você pode esconder os campos desejados da seguinte forma:

<div class="contain-inline-size rounded-md border-[0.5px] border-token-border-medium relative bg-token-sidebar-surface-primary dark:bg-gray-950" id="bkmrk-"></div>```css
html.public-portal .item-identity{
    display: none
}

html.public-portal .item-status{
    display: none
}
```

Dessa forma, sempre que o formulário estiver público, os campos **Status** e **Identity** serão ocultados automaticamente.

### Usando Javascript

```javascript
//Qualquer uma dessas funções javascript pode te ajudar

//a função javascript retorna se o form está no modo Publico ou não 
var isPublicPortal = formContext.isPublicPortal();

//OU 

//a função javascript retorna se o form está no modo Publico ou não 
var isPublicForm = formContext.isPublicForm();
```

# Criando ações complexas no botão de um formulário

### Opção 1, usando o c# direto no cshtml

Nesse exemplo vamos supor que temos 2 formulários

1. Solicitção de Orçamento
2. Orçamento

Dentro do Solicitação de Orçamento você tem um botão chamado "Criar Orçamento" e ao clicar nesse Criar orçamento você quer criar um novo Formulário de Orçamento.

No Formulário Solciitação de Orçamento, crie um **javascript** como esse exemplo:

```javascript
function criarOrcamento() {
    formContext.loadAjax("criarOrcamento", {
        onSuccess: function (e) {
            //pageMsg.showMsgSuccess("Orcamento criado", "Sucesso");

            var jsonResult = JSON.parse(e);
            
            if (!jsonResult.success) {
                pageMsg.showMsgError(jsonResult.msg, "Falha");
            } else {

              var idEstruturaFormToRedirect = "74ad209b-ee6a-4ae3-9920-2caad2bc7451";
                window.location.href = formContext.url.getBaseUrl() + "#/fluxo/index/" +idEstruturaFormToRedirect+ "/" + jsonResult.idOrcamento;   
            }

        },
        onError: function (err) {
            pageMsg.showMsgError("Erro ao criar o Orcamento", "Falha");
        }
    });
}
```

No onclick do botão "Criar Orçamento" chame a função javascript

```javascript
criarOrcamento()
```

Agora crie um Componente Cshtml, chamando **CriarOrcamento**

Dentro do componente coloque uma programação em C#.

**C#**

```c#
@{
    var success = false;
    var msg = "";
    var tel = PageContext.GetValue("seu_telefone");
    Guid? idOrcamento = null;

    if (!string.IsNullOrWhiteSpace(tel))
    {
        // Verifica se o cliente já existe
        var query = $"SELECT id FROM x_tbl_clientes WHERE telefone = '{tel}' AND deletado = false LIMIT 1";
        var dtCliente = await PageContext.GetDataTableAsync(query);
        var clienteExiste = dtCliente.Rows.Count > 0;
        Guid idCliente;

        //se o cliente ainda nao existir, cria um cliente
        if (!clienteExiste)
        {
            var idFormularioCliente = Guid.Parse("cb4019ad-c731-42b9-8624-bb9c0fe5bf78");
            var valuesCliente = new DataDictionary
            {
                { "nome", PageContext.GetValue("seu_nome") },
                { "email", PageContext.GetValue("email") },
                { "instagram", PageContext.GetValue("instagram") },
                { "telefone", tel }
            };

            idCliente = await PageContext.SaveEntityAsync(idFormularioCliente, valuesCliente);
        }
        else
        {
            idCliente = Guid.Parse(dtCliente.Rows[0]["id"].ToString());
        }

        // Criação do orçamento
        var idFormularioOrcamento = Guid.Parse("74ad209b-ee6a-4ae3-9920-2caad2bc7451");
        var valuesOrcamento = new DataDictionary
        {
            { "solicitacao", PageContext.FormId },
            { "radiosolicitacao", "dcef9208-3a3e-3f34-90f9-e514af597d93" },
            { "numero_convidado_adultos", PageContext.GetValue("qtd_adultos") },
            { "numero_convidado_criancas", PageContext.GetValue("qtd_criancas") },
            { "datahora", PageContext.GetValue("datahora_do_evento") },
            { "local", PageContext.GetValue("local_do_evento") },
            { "status", "6d5257d2-034a-459a-b57a-cc4800e74fb0" },
            { "tipo_de_orcamento", PageContext.GetValue("tipo_de_evento") },
            { "cliente", idCliente.ToString() }
        };

        idOrcamento = await PageContext.SaveEntityAsync(idFormularioOrcamento, valuesOrcamento);
        success = true;
    }
    else
    {
        msg = "O telefone não pode estar em branco";
    }
}
{"success": @success.ToString().ToLower(), "msg": "@msg", "idOrcamento": "@idOrcamento" }

```

### Opção 2, usando regra de negócio

Nesse exemplo vamos supor que temos 2 formulários

1. Solicitção de Orçamento
2. Orçamento

Dentro do Solicitação de Orçamento você tem um botão chamado "Criar Orçamento" e ao clicar nesse Criar orçamento você quer salvar o formulário de Solicitação de Orçamento mudando o status dele para "Orçamento Criado" e ao mesmo tempo, já criar um novo Formulário de Orçamento.

**Importante**, coloque uma regra no formulário de Solicitação de Orçamento pra deixar invisível o botão de "Criar Orçamento" sempre que já tiver um orçamento criado, ou seja, que o status seja igual ao "Orçamento Criado";

No Formulário Solciitação de Orçamento, crie um **javascript** como esse exemplo:

```javascript
function criarOrcamento() {
    pageMsg.showMsgSuccess("Criando orçamento...");
    formContext.field.setValue("status", "041cc896-6048-4b56-a9ac-033f6144253c");//coloca o status "orçamento em criação", supondo que o staus "orçamento em criação" é esse id 041cc896-6048-4b56-a9ac-033f6144253c
    setTimeout(function () { 
        formContext.form.save();

    }, 500); //espera 500ms pra seguir o salvamento
}





```

No onclick do botão "Criar Orçamento" chame a função javascript

```javascript
criarOrcamento()
```

Agora nas regras de negocio, crie uma regra para criar um registro novo de orçamento ao SALVAR.

Coloque um If pra enviar o orçamento apenas se o status seja "orçamento em criação"

Dentro do if coloque uma programação em C#.

**C#**

```c#
@{

    //muda o status da SOlicitçaão de ORçamento pra "Orçamento Criado"
    FormContext.SetValue("status", "9041cc899-7045-cb56-b9ac-033f61442599");//coloca o status "orçamento criado", supondo que o staus "orçamento criado" é esse id 9041cc899-7045-cb56-b9ac-033f61442599


  
    var tel = FormContext.GetValue("seu_telefone");
    if (!string.IsNullOrWhiteSpace(tel))
    {
        // Verifica se o cliente já existe
        var query = $"SELECT id FROM x_tbl_clientes WHERE telefone = '{tel}' AND deletado = false LIMIT 1";
        var dtCliente = await FormContext.GetDataTableAsync(query);
        var clienteExiste = dtCliente.Rows.Count > 0;
        Guid idCliente;

        //se o cliente ainda nao existir, cria um cliente
        if (!clienteExiste)
        {
            var idFormularioCliente = Guid.Parse("cb4019ad-c731-42b9-8624-bb9c0fe5bf78");
            var valuesCliente = new DataDictionary
            {
                { "nome", FormContext.GetValue("seu_nome") },
                { "email", FormContext.GetValue("email") },
                { "instagram", FormContext.GetValue("instagram") },
                { "telefone", tel }
            };

            idCliente = await FormContext.SaveEntityAsync(idFormularioCliente, valuesCliente);
        }
        else
        {
            idCliente = Guid.Parse(dtCliente.Rows[0]["id"].ToString());
        }

        // Criação do orçamento
        var idFormularioOrcamento = Guid.Parse("74ad209b-ee6a-4ae3-9920-2caad2bc7451");
        var valuesOrcamento = new DataDictionary
        {
            { "solicitacao", FormContext.FormId },
            { "radiosolicitacao", "dcef9208-3a3e-3f34-90f9-e514af597d93" },
            { "numero_convidado_adultos", FormContext.GetValue("qtd_adultos") },
            { "numero_convidado_criancas", FormContext.GetValue("qtd_criancas") },
            { "datahora", FormContext.GetValue("datahora_do_evento") },
            { "local", FormContext.GetValue("local_do_evento") },
            { "status", "6d5257d2-034a-459a-b57a-cc4800e74fb0" },
            { "tipo_de_orcamento", FormContext.GetValue("tipo_de_evento") },
            { "cliente", idCliente.ToString() }
        };

    }
    else
    {
        FormContext.WarningMessage("O telefone não pode estar em branco");
    }
}
```

# Ao salvar um form, pausar ação do sistema e atualizar a tela

Configure o nome da função javascript para ser chamada após qualquer ação de sucesso no formulário, como na imagem abaixo:

[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-02/scaled-1680-/image.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-02/image.png)

Na customização javascript coloque esse código. agora ao salvar, o form continuará na mesma tela, apresentará uma msg de sucesso e fará um refresh da página

```c#
function afterOnSave(formId, response, formAction) {

      if(formAction != 1) return; //1 é salvar 

      formContext.msg.showMsgSuccess("Form salvo com sucesso", "Ok");

      //ao salvar um novo, nao sair do lightbox que da aberto mas abrir um novo
      setTimeout(function () { window.location = window.location }, 300);
  
      return false;
}
```

Para saber mais sobre esse [evento javascript que ocorre após o subsmit post do formulario (onAfterPostEvent), clique aqui](https://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/evento-javascript-ap%C3%B3s-o-subsmit-post-do-formulario-%28onafterpostevent%29 "Evento javascript após o subsmit post do formulario (onAfterPostEvent)")

# [Form] Como abrir outra página ou um lightbox / modal a partir estando em um Form ou Workflow

```javascript

function openLightBox(tamanho, url) {
    var __baseUrl = customPageContext.url.getBaseUrl();

    url = __baseUrl + url; 
    formContext.openLightBox(url, tamanho)
}



//Abrir lightbox tela cheia
//Abrir um custom page
openLightBox('fullscreen', 'custompage/6d6d2752-5fcd-4303-aa1b-1ab9e32b38d3') 

//Abrir lightbox tamanho grande
//Abrir um form de cadastro
openLightBox('g', 'fluxo/index/0153b02c-d4d8-4747-9a69-45aafa113f81/1f25c74f-a048-4d83-86eb-f31b9608b615') 

//Abrir lightbox tamanho médio
//Abrir um list de um form
openLightBox('m', 'fluxo/list/0153b02c-d4d8-4747-9a69-45aafa113f81') 

//Abrir lightbox tamanho pequeno
//abrir um board
openLightBox('p', '/b/YKYZ92/custom-code') 
```

# Leitura de E-mail Automatizada e Monitoramento de Caixa de Entrada

O **AgilityFlow** permite a automação do monitoramento de uma caixa de e-mail (por exemplo, `atendimento@yyy.com`). Sempre que uma nova mensagem for recebida, o sistema pode acionar eventos automaticamente, como:

- Cadastro de um formulário
- Acionamento de uma API
- Execução de uma tarefa
- Entre outras automações personalizadas

## **Como Configurar**

Para habilitar essa funcionalidade, entre em contato com o seu especialista AgilityFlow.

# [Global Code] Como criar uma Classe Global em C#?

\#GlobalCode

<p class="callout danger">IMPORTANTE: a class não pode ser instanciada diretamente, <s>ex: new MyClass()</s> utilize CreateInstanceMyClass() que é gerado automaticamente</p>

<p class="callout danger">IMPORTANTE: a class não pode ter construtor definido</p>


### Como definir e instanciar uma classe C# que está definida no Global Code?

Entre em **Global Code** na área de configuração, na aba C# GlobalClass e clique em Novo C#.

Crie um C# chamado "Document"

[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-02/scaled-1680-/RjTimage.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-02/RjTimage.png)

No código C#, copie e cole o código abaixo, repare que foi criado manualmente o metodo fora da classe chamado CreateDocument com 2 parametros que instancia a classe Document, através dele criaremos a instancia quando formos usar a classe Document, mas o Agilityflow também gera um metodo padrão chamado **<span style="text-decoration: underline;">CreateInstanceDocument</span>** sem parametro para gerar a instancia, caso você precise.

<p class="callout info"><span style="text-decoration: underline;">Importante</span>: para toda classe criada no agilityflow, o sistema gera automaticamente um metodo de criação da instancia dessa classe com o nome CreateInstanceXXXXX onde o XXXX é o nome da classe, se for uma classe chamada Document, ele cria **Document CreateInstanceDocument()**, sempre sem parametros de entrada</p>

```c#
//crie uma classe
public class Document{
    public string Title {get;set;}
    public string Description {get;set;}



    public async Task<List<UserClass>> ListUserExamplesAsync(){
        var userNames = new List<UserClass>();

        var dt = await GlobalContext.GetDataTableAsync("select coalesce(usu_nome,'') as name from tbl_usuario where deletado = false limit 5");

        for(var i = 0; i < dt.Rows.Count; i++){

           //repare que pra criar a instancia da classe UserClass, eu utilizo o metodo CreateInstance
            var userClass = CreateInstance<UserClass>();
            userClass.Name = dt.Rows[i]["name"].ToString();
            userNames.Add(userClass);
        }

        return userNames;
    }
}

public class UserClass{
    public string Name {get;set;}
}

//caso queira, crie um metodo para fazer a instancia dessa classe
public Document CreateDocument(string title, string description ){

    var doc = CreateInstance<Document>();
    doc.Title = title; 
    doc.Description = description;

     return doc;
}
```

### **Como instanciar uma classe do Global Code entre outras classes do Global Code?**

Suponahmos que você tenha uma classe chamada OutraClasseGlobal no Global Code

```c#
public class OutraClasseGlobal{

  public string Nome {get;set;}

}
```

Para instanciar essa classe OutraClasseGlobal dentro do pŕoprio Global Code você tem as opções abaixo:

##### <u>CreateInstance&lt;T&gt;()</u>

```c#
public class MinhaClasseGlobal{

  public void Metodo()[

    var classe2 = CreateInstance<OutraClasseGlobal>();
    
  }

}
```

### **Como usar em outras partes do sistema essa classe C# Global (em outros contextos) ?**

Por ser uma classe Global, você pode utilizar em qualquer lugar que possa executar C# no sistema, exemplos: Apis, Forms, Reports, Kanban, etc..

Para Utilizar, por exemplo dentro de um Cshtml de um form, você tem essas opções:

##### <span style="text-decoration: underline;">**Opção 01:**</span> Chamando o metodo que o agilityflow gera automaticamente <span style="color: rgb(0, 0, 0); background-color: rgb(53, 152, 219);">**(recomendado)**</span>:

<p class="callout info"><span style="text-decoration: underline;">Importante</span>: para toda classe criada no agilityflow, o sistema gera automaticamente um metodo de criação da instancia dessa classe com o nome CreateInstanceXXXXX onde o XXXX é o nome da classe, se for uma classe chamada Document, ele cria **Document CreateInstanceDocument()**</p>

```c#
@{       
        //instanciando uma class q foi declarada dentro do Global dinamicamente
        var documentClass01 = GlobalClass.CreateInstanceDocument();

        var json = JsonConvert.SerializeObject( new { documentClass01 }); 

}
@json

```

##### <span style="text-decoration: underline;">**Opção 02:**</span> Chamando o metodo nativo do agiltyflow para instanciar classes:

```c#
@{       
        //instanciando uma class q foi declarada dentro do Global dinamicamente
        var documentClass02 = GlobalClass.CreateInstance("Document"); 

        var json = JsonConvert.SerializeObject( new { documentClass02 }); 

}
@json

```

##### <span style="text-decoration: underline;">**Opção 03:**</span> Caso você crie um metodo manualmente que intancie a classe**,** exemplo o metodo criado no exemplo anterior  **CreateDocument (**que você mesmo criou) :

```c#
@{       
        //instanciando uma class q foi declarada dentro do Global dinamicamente
        var documentClass01 = GlobalClass.CreateDocument("string title", "string description");

        var json = JsonConvert.SerializeObject( new { documentClass01 }); 

}
@json

```

## Regras e Limitações:

- Para toda classe criada no agilityflow, o sistema gera automaticamente um metodo de criação da instancia dessa classe como nome CreateInstanceXXXXX onde o XXXX é o nome da classe, se for uma classe chamada Document, ele cria **Document CreateInstanceDocument()**, porém sempre sem parametros de entrada, você pode gerar manualmente um **metodo com o mesmo nome mas com outros parametros de entrada, exemplo Document CreateDocument(string title, string description )**  
    A classe não deve ter construtor, para instanciar, utilize o metodo **CreateInstance&lt;MyClass&gt;()**
- Fora da área do C# do Global Code, você não tem acesso ao "Tipo" da classe que você criar. Então fora do seu class c# de Global Code você nao vai conseguir usar esse "Tipo",ex: como<span style="color: rgb(224, 62, 45);"> **ToList&lt;MyClass&gt;()** </span>ou por exemplo em uma referencia implicita no foreach,:
- ```c#
    
    
    //forma ERRADA se estiver FORA e consumindo o GlobalCode, (se estiver dentro do GlobalCode, você pode referenciar normalmente)
    //referenciar explicitamente o UserClass no foreach
    var userExamples = await GlobalClass.ListUserExamplesAsync();
    foreach(UserClass user in userExamples){
       <text>
           @user.Name
       </text>            
    }
    
    
    
    
    //forma CORRETA se estiver FORA e consumindo o GlobalCode,  (se estiver dentro do GlobalCode, você pode referenciar normalmente)
    //referenciar implicitamente o UserClass no foreach, usando var ou dynamic
    var userExamples = await GlobalClass.ListUserExamplesAsync();
    foreach(var user in userExamples){
       <text>
           @user.Name
       </text>            
    }
    ```

# [Custom Page] Como criar uma Classe em C# no Custom Page?

\#CustomPage

<p class="callout danger">IMPORTANTE: a class não pode ser instanciada diretamente, <s>ex: new MyClass()</s> utilize CreateInstanceMyClass() que é gerado automaticamente</p>

<p class="callout danger">IMPORTANTE: a class não pode ter construtor definido</p>


### Como definir e instanciar uma classe C# ?

<p class="callout info"><span style="text-decoration: underline;">Importante</span>: para toda classe criada no agilityflow, o sistema gera automaticamente um metodo de criação da instancia dessa classe com o nome CreateInstanceXXXXX onde o XXXX é o nome da classe, se for uma classe chamada Document, ele cria **Document CreateInstanceDocument()**, sempre sem parametros de entrada</p>

```c#
//crie uma classe
public class Document{
    public string Title {get;set;}
    public string Description {get;set;}



    public async Task<List<UserClass>> ListUserExamplesAsync(){
        var userNames = new List<UserClass>();

        var dt = await CustomPageContext.GetDataTableAsync("select coalesce(usu_nome,'') as name from tbl_usuario where deletado = false limit 5");

        for(var i = 0; i < dt.Rows.Count; i++){

           //repare que pra criar a instancia da classe UserClass, eu utilizo o metodo CreateInstance
            var userClass = CreateInstance<UserClass>();
            userClass.Name = dt.Rows[i]["name"].ToString();
            userNames.Add(userClass);
        }

        return userNames;
    }
}

public class UserClass{
    public string Name {get;set;}
}

//caso queira, crie um metodo para fazer a instancia dessa classe
public Document CreateDocument_01(string title, string description ){

    var doc = CreateInstance<Document>();
    doc.Title = title; 
    doc.Description = description;

     return doc;
}
```

### **Como instanciar uma classe do Custom Page entre outras classes do Custom Page?**

Suponahmos que você tenha uma classe chamada OutraClasseNoCustomPage no Custom Page

```c#
public class OutraClasseNoCustomPage{

  public string Nome {get;set;}

}
```

Para instanciar essa classe OutraClasseNoCustomPage dentro do pŕoprio Custom Page você tem as opções abaixo:

##### <u>CreateInstance&lt;T&gt;()</u>

```c#
public class MinhaClasseCustomPage{

  public void Metodo()[

    var classe2 = CreateInstance<OutraClasseNoCustomPage>();
    
  }

}
```

### **Como usar no CShtml a Classe C# criada?** 

##### <u>CreateInstanceXXXXX()</u>

<p class="callout info"><span style="text-decoration: underline;">Importante</span>: para toda classe criada no agilityflow, o sistema gera automaticamente um metodo de criação da instancia dessa classe com o nome CreateInstanceXXXXX onde o XXXX é o nome da classe, se for uma classe chamada Document, ele cria **Document CreateInstanceDocument()**</p>

```c#
@{       
        //instanciando uma class q foi declarada dentro do CustomPage dinamicamente
        var documentClass01 = CustomPageClass.CreateInstanceDocument();

        var json = JsonConvert.SerializeObject( new { documentClass01 }); 

}
@json

```

##### <span style="text-decoration: underline;">**Opção 02:**</span> Chamando o metodo nativo do agiltyflow para instanciar classes:

```c#
@{       
        //instanciando uma class q foi declarada dentro do CustomPage dinamicamente
        var documentClass02 = CustomPageClass.CreateInstance("Document"); 

        var json = JsonConvert.SerializeObject( new { documentClass02 }); 

}
@json

```

##### <span style="text-decoration: underline;">**Opção 03:**</span> Caso você crie um metodo manualmente que intancie a classe**,** exemplo o metodo criado no exemplo anterior  **CreateDocument\_01 (**que você mesmo criou) :  


<p class="callout info">O método **CreateDocument\_01 você que precisaria criar (exemplo criado acima)**  
</p>

```c#
@{       
        //instanciando uma class q foi declarada dentro do CustomPage dinamicamente
        var documentClass01 = CustomPageClass.CreateDocument_01("string title", "string description");

        var json = JsonConvert.SerializeObject( new { documentClass01 }); 

}
@json

```

## Regras e Limitações:

- Para toda classe criada no agilityflow, o sistema gera automaticamente um metodo de criação da instancia dessa classe como nome CreateInstanceXXXXX onde o XXXX é o nome da classe, se for uma classe chamada Document, ele cria **Document CreateInstanceDocument()**, porém sempre sem parametros de entrada, você pode gerar manualmente um **metodo com o mesmo nome mas com outros parametros de entrada, exemplo Document CreateDocument(string title, string description )**  
    A classe não deve ter construtor, para instanciar, utilize o metodo **CreateInstance&lt;MyClass&gt;()**
- Fora da área do C# do Custom Page, você não tem acesso ao "Tipo" da classe que você criar. Então fora do seu class c# de Custom Page você nao vai conseguir usar esse "Tipo",ex: como<span style="color: rgb(224, 62, 45);"> **ToList&lt;MyClass&gt;()** </span>ou por exemplo em uma referencia implicita no foreach,:
- ```c#
    
    
    //forma ERRADA se estiver FORA e consumindo o CustomPage, (se estiver dentro do CustomPage, você pode referenciar normalmente)
    //referenciar explicitamente o UserClass no foreach
    var userExamples = await CustomPageClass.ListUserExamplesAsync();
    foreach(UserClass user in userExamples){
       <text>
           @user.Name
       </text>            
    }
    
    
    
    
    //forma CORRETA se estiver FORA e consumindo o CustomPage,  (se estiver dentro do CustomPage, você pode referenciar normalmente)
    //referenciar implicitamente o UserClass no foreach, usando var ou dynamic
    var userExamples = await CustomPageClass.ListUserExamplesAsync();
    foreach(var user in userExamples){
       <text>
           @user.Name
       </text>            
    }
    ```

# [Global Code] Como buscar no banco de dados em uma C# class global

\#GlobalCode

### Como fazer query?

Entre em **Global Code** na área de configuração, na aba C# GlobalClass e clique em Novo C#.

Crie um C# chamado "GetData"

No código C#, coloque o código abaixo, crie apenas um metodo que faça uma query na tabela de usuarios

```c#
//nesse exemplo eu faço uma query na tabela de usuarios
public async Task<List<string>> GetUsersAsync(){

     var userNames = new List<string>();

    var dt = await GlobalContext.GetDataTableAsync("select coalesce(usu_nome,'') as name from tbl_usuario where deletado = false limit 10");

    for(var i = 0; i < dt.Rows.Count;i++){
        userNames.Add(dt.Rows[i]["name"].ToString());
    }
 
    return userNames;   
}
```

#### Como usar no sistema essa classe C# Global?

Por ser uma classe Global, você pode utilizar em qualquer lugar que possa executar C# no sistema, exemplos: Apis, Forms, Reports, Kanban, etc..

Para Utilizar, por exemplo dentro de um Cshtml de um form:

<span style="text-decoration: underline;">**Opção 02:**</span> Chamando o metodo nativo do agiltyflow para instanciar classes:

```c#
@{       
        var users = await GlobalClass.GetUsersAsync();

        var json = JsonConvert.SerializeObject( new { users }); 

}
@json

```

# [Global Code] Como customizar CSS, Javascript e C# Globalmente

\#GlobalCode

Todas as opções mostradas na imagem abaixo podem ser customizadas no Agilityflow.

No caso de **C#**, por ser Global, você pode criar classes e metodos e utiliza-los em qualquer lugar que possa executar C# no sistema, exemplos: Apis, Forms, Reports, Kanban, etc..

Em todos as opçoes abaixo você pode customizar o **CSS** e o **Javascript**. Por exemplo, se na opção Forms, você definir uma função javascript essa função estará disponível em todos os formulários do seu sistema, assim também funciona para o CSS.

[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-02/scaled-1680-/U6jimage.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-02/U6jimage.png)

### Funções e Métodos Nativos em C#

Dezenas de métodos nativos estão disponiveis para sua customização na classe **<span style="text-decoration: underline;">GlobalCotext</span>**.

### Funções e Métodos Nativos em Javascript

Dezenas de métodos nativos estão disponiveis para sua customização na classe <span style="text-decoration: underline;">**globalCotext**</span>.

# [Custom Page] Quais são as funções nativas do AgilityFlow disponíveis no JavaScript para utilizar em uma Custom Page? customPageContext

## Introdução

Este script fornece um conjunto de funções para manipulação de contexto de página, carregamento dinâmico de componentes e arquivos, manipulação de mensagens, conversão de números e datas, e interação com URLs base.

<div id="bkmrk-">---

</div>## Constantes

### `emptyGuid`

Uma string que representa um GUID vazio:

```
var emptyGuid = "00000000-0000-0000-0000-000000000000";
```

<div id="bkmrk--1">---

</div>## Estrutura Principal

### `customPageContext`

Objeto que gerencia funções relacionadas ao contexto da página.

#### `parentFrame`

Identifica e armazena a referência do iframe pai.

```
customPageContext.parentFrame
```

#### `isMobile()`

Retorna `true` se o dispositivo for móvel.

```
customPageContext.isMobile();
```

#### `redirectTo(url)`

Redireciona a página para a URL informada.

```
customPageContext.redirectTo('https://example.com');
```

#### `openLightBox(link, tamanholightbox, titulo)`

Abre um lightbox com a URL especificada.

```
customPageContext.openLightBox('/pagina.html', 'm', 'Exemplo');
```

<div id="bkmrk--2">---

</div>## **Carregamento de Componentes CSHTML**

Funções para carregar componentes de forma dinâmica:

```
customPageContext.loadCsHtmlComponent(componentName, options);
customPageContext.loadHtmlComponent(componentName, options);
customPageContext.loadPartialView(componentName, options);
customPageContext.loadViewComponent(componentName, options);
customPageContext.loadAjax(componentName, options);
customPageContext.loadAjaxComponent(componentName, options);
```

Veja um exemplo de uso para Inserir, Atualizar ou deletar um registro em um Formulário, [clicando aqui](https://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/custom-page-como-inserir-atualizar-e-deletar-um-registro-em-um-determinado-form-estando-em-um-custom-page)

Exemplo passando parâmetros para o cshtml:

```javascript
function loadPartialToUpdateRegister() {

    var cshtmlPartialName = "[coloque aqui o nome do partial cshtml que vc fez as regras de atualizar]";
    customPageContext.loadCsHtmlComponent(cshtmlPartialName,
        {
            placeholderId: 'result_cshtml', //parametro opcional, se o cshtml retornar algum html e vc quiser, vc pode colocar o retorno dentro de algum placeholder, div, etc..
            extraData: {
                idRegistro: $('#guidRegistro').val(), 
                nome: $('#nome').val(), 
                email: $('#email').val()
            },
            onSuccess: function (result) {
                customPageContext.msg.success("Executado com sucesso", "Confirmação");
            },
            onError: function (error) {
                customPageContext.msg.error("Execução não realizada", "Erro");
                console.log('error', error)                
            }
        
        }
     )
}
```

<div id="bkmrk--3">---

</div>## **Carregamento de Arquivos JavaScript**

### `addJavascriptFile(options)`

Adiciona um arquivo JavaScript à página de forma assíncrona e executa um callback após o carregamento.

- **Parâmetros:**
    
    
    - `options` (Object): Objeto com as propriedades:
        
        
        - `file_url` (String): URL do arquivo JavaScript.
        - `callback_onload` (Function): Função a ser executada após o carregamento do arquivo.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    customPageContext.addJavascriptFile({
        file_url: "https://www.exemplo.com/script.js",
        callback_onload: function() {
            console.log("Script carregado!");
        }
    });
    ```


## **Manipulação de URLs**

### `url.getBaseUrl()`

Retorna a URL base do sistema.

- **Retorno:**
    
    
    - String com a URL base.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    console.log("URL base:", customPageContext.url.getBaseUrl());
    ```

---

### `url.getStaticFileUrl()`

Retorna a URL base para arquivos estáticos.

- **Retorno:**
    
    
    - String com a URL de arquivos estáticos.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    console.log("URL de arquivos estáticos:", customPageContext.url.getStaticFileUrl());
    ```

---

## **Idioma Atual**

### `currentLanguage.get()`

Retorna o idioma atual do sistema.

- **Retorno:**
    
    
    - String com o código do idioma (ex: `'pt-BR'`, `'en-US'`).
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    console.log("Idioma atual:", customPageContext.currentLanguage.get());
    ```

---

### `currentLanguage.isEnglish()`

Verifica se o idioma atual é inglês.

- **Retorno:**
    
    
    - `true` se for inglês.
    - `false` caso contrário.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    if (customPageContext.currentLanguage.isEnglish()) {
        console.log("Idioma atual é inglês.");
    }
    ```

---

### `currentLanguage.getIIF_TextFromCurrentLanguage(text_ptBR, text_ENG, text_ESP)`

Retorna o texto correspondente ao idioma atual.

- **Parâmetros:**
    
    
    - `text_ptBR` (String): Texto em português.
    - `text_ENG` (String): Texto em inglês.
    - `text_ESP` (String): Texto em espanhol.
- **Retorno:**
    
    
    - String com o texto no idioma atual.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    const texto = customPageContext.currentLanguage.getIIF_TextFromCurrentLanguage("Olá", "Hello", "Hola");
    console.log(texto); // Retorna "Olá" se o idioma for português.
    ```

---

## **Mensagens**

O módulo `customPageContext.msg` fornece funções para exibir e ocultar mensagens de alerta, erro, sucesso e aviso no sistema. Abaixo estão as funcionalidades disponíveis.

---

### **Ocultar Mensagens**

### `hide(forcarFechar)`

Oculta todas as mensagens exibidas.

- **Parâmetros:**
    
    
    - `forcarFechar` (Boolean): Força o fechamento das mensagens.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    customPageContext.msg.hide(true); // Oculta todas as mensagens, forçando o fechamento.
    ```

---

### **Exibir Mensagens**

### `show(type, msg, title, options)`

Exibe uma mensagem de alerta, erro, sucesso ou aviso.

- **Parâmetros:**
    
    
    - `type` (String): Tipo da mensagem. Valores possíveis:
        
        
        - `'warning'`: Mensagem de aviso.
        - `'error'`: Mensagem de erro.
        - `'success'`: Mensagem de sucesso.
    - `msg` (String): Texto da mensagem.
    - `title` (String): Título da mensagem.
    - `options` (Object): Opções adicionais para personalização da mensagem.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    customPageContext.msg.show("success", "Operação realizada com sucesso!", "Sucesso", { timeout: 5000 });
    ```

---

### `warning(msg, title, options)`

Exibe uma mensagem de aviso.

- **Parâmetros:**
    
    
    - `msg` (String): Texto da mensagem.
    - `title` (String): Título da mensagem.
    - `options` (Object): Opções adicionais.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    customPageContext.msg.warning("Atenção: Este campo é obrigatório.", "Aviso");
    ```

---

### `error(msg, title)`

Exibe uma mensagem de erro.

- **Parâmetros:**
    
    
    - `msg` (String): Texto da mensagem.
    - `title` (String): Título da mensagem.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    customPageContext.msg.error("Ocorreu um erro ao salvar o formulário.", "Erro");
    ```

---

### `success(msg, title, options)`

Exibe uma mensagem de sucesso.

- **Parâmetros:**
    
    
    - `msg` (String): Texto da mensagem.
    - `title` (String): Título da mensagem.
    - `options` (Object): Opções adicionais.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    customPageContext.msg.success("Formulário salvo com sucesso!", "Sucesso", { timeout: 3000 });
    ```

---

### **Funções Legadas de Mensagens**

As funções abaixo são mantidas para compatibilidade com versões anteriores, mas é recomendado utilizar as funções acima (`show`, `warning`, `error`, `success`).

### `hideMsgs()`

Oculta todas as mensagens exibidas.

- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    customPageContext.msg.hideMsgs();
    ```

---

### `showMsgWarning(msg, title, options)`

Exibe uma mensagem de aviso (legado).

- **Parâmetros:**
    
    
    - `msg` (String): Texto da mensagem.
    - `title` (String): Título da mensagem.
    - `options` (Object): Opções adicionais.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    customPageContext.msg.showMsgWarning("Atenção: Este campo é obrigatório.", "Aviso");
    ```

---

### `showMsgError(msg, title)`

Exibe uma mensagem de erro (legado).

- **Parâmetros:**
    
    
    - `msg` (String): Texto da mensagem.
    - `title` (String): Título da mensagem.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    customPageContext.msg.showMsgError("Ocorreu um erro ao salvar o formulário.", "Erro");
    ```

---

### `showMsgSuccess(msg, title, options)`

Exibe uma mensagem de sucesso (legado).

- **Parâmetros:**
    
    
    - `msg` (String): Texto da mensagem.
    - `title` (String): Título da mensagem.
    - `options` (Object): Opções adicionais.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    customPageContext.msg.showMsgSuccess("Formulário salvo com sucesso!", "Sucesso", { timeout: 3000 });
    ```

---

### **Exemplos de Uso de Mensagem**

##### Exibindo uma mensagem de sucesso:

```
customPageContext.msg.success("Dados salvos com sucesso!", "Sucesso", { timeout: 5000 });
```

##### Exibindo uma mensagem de erro:

```
customPageContext.msg.error("Erro ao processar a solicitação.", "Erro");
```

##### Ocultando todas as mensagens:

<div class="md-code-block" id="bkmrk-javascript-copy-2"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
</div></div></div></div></div>```
customPageContext.msg.hide(true);
```


## **Manipulação de Números**

### `number.convertString_toNumber(strValueToConvert, qtdCasasDecimais)`

Converte uma string formatada em número.

- **Parâmetros:**
    
    
    - `strValueToConvert` (String): Valor em formato de string.
    - `qtdCasasDecimais` (Number): Quantidade de casas decimais.
- **Retorno:**
    
    
    - Número convertido.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    const numero = customPageContext.number.convertString_toNumber("1.000,50", 2);
    console.log(numero); // Retorna 1000.50
    ```

---

### `number.convertNumber_toStringFormatted(numberToConvert, qtdCasasDecimais)`

Converte um número em uma string formatada de acordo com o idioma.

- **Parâmetros:**
    
    
    - `numberToConvert` (Number): Número a ser convertido.
    - `qtdCasasDecimais` (Number): Quantidade de casas decimais.
- **Retorno:**
    
    
    - String formatada.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring">  
    </div></div></div></div>```
    const texto = customPageContext.number.convertNumber_toStringFormatted(1000.50, 2);
    console.log(texto); // Retorna "1.000,50" em português.
    ```

---


## **Manipulação de Datas**

### `isCurrentMonthAndYear(data)`

Verifica se a data fornecida pertence ao mês e ano atuais.

- **Parâmetros:**
    
    
    - `data` (String): Data no formato `DD/MM/YYYY`.
- **Retorno:**
    
    
    - `true` se a data for do mês e ano atuais.
    - `false` caso contrário.
- **Exceções:**
    
    
    - Lança um `TypeError` se a data estiver em um formato inválido.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring"> </div></div></div></div>```
    customPageContext.datetime.validation.isCurrentMonthAndYear("25/10/2023"); // Retorna true se outubro de 2023 for o mês e ano atuais.
    ```

---

### `compare(date1, compare, date2)`

Compara duas datas com base no operador especificado.

- **Parâmetros:**
    
    
    - `date1` (String): Primeira data no formato `DD/MM/YYYY`.
    - `compare` (String): Operador de comparação. Valores possíveis:
        
        
        - `'greater'` ou `'>'`
        - `'greater-or-equal'` ou `'>='`
        - `'less'` ou `'<'`
        - `'less-or-equal'` ou `'<='`
        - `'equal'` ou `'=='`
    - `date2` (String): Segunda data no formato `DD/MM/YYYY`.
- **Retorno:**
    
    
    - `true` ou `false`, dependendo da comparação.
- **Exceções:**
    
    
    - Lança um `TypeError` se as datas estiverem em formato inválido ou se o operador de comparação não for reconhecido.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring"> </div></div></div></div>```
    customPageContext.datetime.validation.compare("25/10/2023", "greater", "20/10/2023"); // Retorna true.
    ```

---

### `compareDatetime(datetime1, compare, datetime2)`

Compara duas datas e horários com base no operador especificado.

- **Parâmetros:**
    
    
    - `datetime1` (String): Primeira data e horário no formato `DD/MM/YYYY HH:mm`.
    - `compare` (String): Operador de comparação. Valores possíveis:
        
        
        - `'greater'` ou `'>'`
        - `'greater-or-equal'` ou `'>='`
        - `'less'` ou `'<'`
        - `'less-or-equal'` ou `'<='`
        - `'equal'` ou `'=='`
    - `datetime2` (String): Segunda data e horário no formato `DD/MM/YYYY HH:mm`.
- **Retorno:**
    
    
    - `true` ou `false`, dependendo da comparação.
- **Exceções:**
    
    
    - Lança um `TypeError` se os dados estiverem em formato inválido ou se o operador de comparação não for reconhecido.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring"> </div></div></div></div>```
    customPageContext.datetime.validation.compareDatetime("25/10/2023 14:30", "greater", "25/10/2023 12:00"); // Retorna true.
    ```

---

### `compareToday(compare, date2)`

Compara a data atual com uma data fornecida.

- **Parâmetros:**
    
    
    - `compare` (String): Operador de comparação. Valores possíveis:
        
        
        - `'greater'` ou `'>'`
        - `'greater-or-equal'` ou `'>='`
        - `'less'` ou `'<'`
        - `'less-or-equal'` ou `'<='`
        - `'equal'` ou `'=='`
    - `date2` (String): Data no formato `DD/MM/YYYY`.
- **Retorno:**
    
    
    - `true` ou `false`, dependendo da comparação.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring"> </div></div></div></div>```
    customPageContext.datetime.validation.compareToday("less", "30/10/2023"); // Retorna true se a data atual for menor que 30/10/2023.
    ```

---

## **Adição de Tempo**

### `day(data, days)`

Adiciona dias a uma data.

- **Parâmetros:**
    
    
    - `data` (String): Data no formato `DD/MM/YYYY` ou `DD/MM/YYYY HH:mm`.
    - `days` (Number): Número de dias a serem adicionados.
- **Retorno:**
    
    
    - Data resultante no mesmo formato da entrada.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring"> </div></div></div></div>```
    customPageContext.datetime.add.day("25/10/2023", 5); // Retorna "30/10/2023".
    ```

---

### `month(data, months)`

Adiciona meses a uma data.

- **Parâmetros:**
    
    
    - `data` (String): Data no formato `DD/MM/YYYY` ou `DD/MM/YYYY HH:mm`.
    - `months` (Number): Número de meses a serem adicionados.
- **Retorno:**
    
    
    - Data resultante no mesmo formato da entrada.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring"> </div></div></div></div>```
    customPageContext.datetime.add.month("25/10/2023", 2); // Retorna "25/12/2023".
    ```

---

### `year(data, years)`

Adiciona anos a uma data.

- **Parâmetros:**
    
    
    - `data` (String): Data no formato `DD/MM/YYYY` ou `DD/MM/YYYY HH:mm`.
    - `years` (Number): Número de anos a serem adicionados.
- **Retorno:**
    
    
    - Data resultante no mesmo

---

### `hour(data, hours)`

Adiciona horas a uma data e horário.

- **Parâmetros:**
    
    
    - `data` (String): Data e horário no formato `DD/MM/YYYY HH:mm`.
    - `hours` (Number): Número de horas a serem adicionadas.
- **Retorno:**
    
    
    - Data e horário resultante no formato `DD/MM/YYYY HH:mm`.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring"> </div></div></div></div>```
    customPageContext.datetime.add.hour("25/10/2023 14:30", 3); // Retorna "25/10/2023 17:30".
    ```

---

### `minute(data, minutes)`

Adiciona minutos a uma data e horário.

- **Parâmetros:**
    
    
    - `data` (String): Data e horário no formato `DD/MM/YYYY HH:mm`.
    - `minutes` (Number): Número de minutos a serem adicionados.
- **Retorno:**
    
    
    - Data e horário resultante no formato `DD/MM/YYYY HH:mm`.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring"> </div></div></div></div>```
    customPageContext.datetime.add.minute("25/10/2023 14:30", 15); // Retorna "25/10/2023 14:45".
    ```

---

## **Obtenção de Datas**

### `getLastDayOfCurrentMonth()`

Retorna o último dia do mês atual.

- **Retorno:**
    
    
    - Data no formato `DD/MM/YYYY`.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring"> </div></div></div></div>```
    customPageContext.datetime.getLastDayOfCurrentMonth(); // Retorna "31/10/2023" se outubro for o mês atual.
    ```

---

### `getLastDayOfMonth(data)`

Retorna o último dia do mês da data fornecida.

- **Parâmetros:**
    
    
    - `data` (String): Data no formato `DD/MM/YYYY`.
- **Retorno:**
    
    
    - Data no formato `DD/MM/YYYY`.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring"> </div></div></div></div>```
    customPageContext.datetime.getLastDayOfMonth("25/10/2023"); // Retorna "31/10/2023".
    ```

---

## **Data e Horário Atuais**

### `getDateNow()`

Retorna a data e horário atuais.

- **Retorno:**
    
    
    - Objeto `Date` representando a data e horário atuais.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring"> </div></div></div></div>```
    customPageContext.datetime.getDateNow(); // Retorna a data e horário atuais.
    ```

---

### `getFormattedDateTime()`

Retorna a data e horário atuais formatados.

- **Retorno:**
    
    
    - String no formato `DD/MM/YYYY HH:mm`.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring"> </div></div></div></div>```
    customPageContext.datetime.getFormattedDateTime(); // Retorna "25/10/2023 14:30".
    ```

---

### `getFormattedDate()`

Retorna a data atual formatada.

- **Retorno:**
    
    
    - String no formato `DD/MM/YYYY`.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring"> </div></div></div></div>```
    customPageContext.datetime.getFormattedDate(); // Retorna "25/10/2023".
    ```

# [Custom Page] Como apresentar mensagens para o usuario

\#CustomPage

Abaixo exemplos em javascript para apresentação de mensanges para o usuário

[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-02/scaled-1680-/BIkimage.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-02/BIkimage.png)

```javascript
function alerta() {
    alert('mensagem de alerta 1');
}
```

[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-02/scaled-1680-/zcUimage.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-02/zcUimage.png)

```javascript
function confirma() {

    if (confirm("confirma msm?")) {
        alert('confirmado');
    } else {
        alert('nao confirmado');
    }   
    
}
```

[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-02/scaled-1680-/MsHimage.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-02/MsHimage.png)

```javascript
//função para apresentar uma mensage de sucesso
function showSuccess() {
    customPageContext.msg.success("msg", "msg title");
}
```

[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-02/scaled-1680-/qHMimage.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-02/qHMimage.png)

```javascript
//função para apresentar uma mensage de atenção
function showWarning() {
    customPageContext.msg.warning("msg", "msg title");
}

```

[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-02/scaled-1680-/RQdimage.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-02/RQdimage.png)

```javascript
//função para apresentar uma mensage de erro
function showError() {
    customPageContext.msg.error("msg", "msg title");
}
```

Abaixo um exemplo para forçar esconder uma mensagem

```javascript
function hideMsgs() {
    customPageContext.msg.hideMsgs();
}
```

# [Custom Page] Como buscar a data atual

Em Javascript

```javascript
function logdate() {
    alert(GetDateNow())
}
```

Em C#

```c#
DateTime.Now.ToUserTimeZone()
```

# [Custom Page] Como abrir outra página ou um lightbox / modal a partir do Custom Page

\#CustomPage

Para abrir um lightbox usando Javascript:

```javascript
function openLightBox(tamanho, titulo) {
    customPageContext.openLightBox('about:blank', tamanho, titulo)
}

//Abrir lightbox tela cheia
openLightBox('fullscreen');

//Abrir lightbox tamanho grande
openLightBox('g');

//Abrir lightbox tamanho médio
openLightBox('m');

//Abrir lightbox tamanho pequeno
openLightBox('p');
```

Para redirecionar para outra página usando Javascript:

```javascript
customPageContext.redirectTo(url);
```

<div id="bkmrk-">  
</div>

# [Custom Page] Buscar informações do banco de dados através (Query)

No Page&lt;body&gt; ou em um partial cshtml utilize o código C# abaixo para fazer uma query na tabela de usuários e lista-los

```javascript
@{  
    var userNames = new List<string>();

    var dt = await CustomPageContext.GetDataTableAsync("select coalesce(usu_nome,'') as name from tbl_usuario where deletado = false limit 5");

    for(var i = 0; i < dt.Rows.Count; i++){
        userNames.Add(dt.Rows[i]["name"].ToString());
    }
  }

@Html.Raw(string.Join("<br>", userNames))
```

# [Global Code] Como declarar uma variável publica em todo o sistema

No C# do Global Code:

```c#
//usando a keyword PUBLIC + tipo + nome da varaiavel que quer criar
public string EssaEhUmaVariavelGlobal = "legal";
```

Nas demais classes C# ou cshtml do sistema que queiram consumir essa variavel:

```c#
string valorDaVariavel_EssaEhUmaVariavelGlobal = GlobalClass.EssaEhUmaVariavelGlobal;
```

# [Custom Page] Como inserir, atualizar e deletar um registro em um determinado Form estando em um Custom Page

## Para Inserir (Insert)

#### Insert usando C#

```c#
public class ExemploMinhaClasseCsharp{

      public async Task<Guid> InserirRegistroAsync(string nome, string email){

        //troque o valor da variavel estruturaformularioidASerCriadoOuAtualizado para o Id do Form que você quer inserir um registro  
        var estruturaformularioidASerCriadoOuAtualizado = Guid.Parse("0153b02c-d4d8-4747-9a69-45aafa113f81");

        //preencher a collection valuesToSave com os valores para o form que quer salvar    
        var valuesToSave = new DataDictionary();
        valuesToSave.Add("name", nome);
        valuesToSave.Add("value1", email);
    
        var createdId = await CustomPageContext.SaveEntityAsync(estruturaformularioidASerCriadoOuAtualizado, valuesToSave);
    
       return createdId;
     }

  
}

public ExemploMinhaClasseCsharp CreateInstanceExemploMinhaClasseCsharp(){
    var obj = CreateInstance<ExemploMinhaClasseCsharp>();
    return obj;
}
```


##### Agora você precisa chamar esse metodo dentro do seu page&lt;body&gt; ou no partial cshtml.

```c#
@{
    var obj = CustomPageClass.CreateInstanceExemploMinhaClasseCsharp();
    var idCriado = await obj.InserirRegistroAsync("joao", "joao@joao.com");
}
idCriado: @idCriado
```


#### Insert usando cshtml

```c#
@{
    //troque o valor da variavel estruturaformularioidASerCriadoOuAtualizado para o Id do Form que você quer inserir um registro  
      var estruturaformularioidASerCriadoOuAtualizado = Guid.Parse("0153b02c-d4d8-4747-9a69-45aafa113f81");

      //preencher a collection valuesToSave com os valores para o form que quer salvar    
      var valuesToSave = new DataDictionary();
      valuesToSave.Add("name", nome);
      valuesToSave.Add("value1", email);
  
      var createdId = await CustomPageContext.SaveEntityAsync(estruturaformularioidASerCriadoOuAtualizado, valuesToSave);
  
}
Id Form Criado: @createdId

```

## Para Atualizar (Update)

#### Update usando C#

```c#
public class ExemploMinhaClasseCsharp{

      public async Task AtualizarRegistroAsync(Guid idRegistro, string nome, string email){

        //troque o valor da variavel estruturaformularioidASerCriadoOuAtualizado para o Id do Estrutura do Formulario que você quer atualizar um registro  
        var estruturaformularioidASerCriadoOuAtualizado = Guid.Parse("0153b02c-d4d8-4747-9a69-45aafa113f81");

        //preencher a collection valuesToSave com os valores para o form que quer salvar    
        var valuesToSave = new DataDictionary();
        valuesToSave.Add("id", idRegistro);
        valuesToSave.Add("name", nome);
        valuesToSave.Add("value1", email);
    
        await CustomPageContext.SaveEntityAsync(estruturaformularioidASerCriadoOuAtualizado, valuesToSave);
    
     }

  
}

public ExemploMinhaClasseCsharp CreateInstanceExemploMinhaClasseCsharp(){
    var obj = CreateInstance<ExemploMinhaClasseCsharp>();
    return obj;
}
```


##### Agora você precisa chamar esse metodo dentro do seu page&lt;body&gt; ou no partial cshtml.

```c#
@{
    var obj = CustomPageClass.CreateInstanceExemploMinhaClasseCsharp();

    var idRegistro = CustomPageContext.GetParam("idRegistro");
    await obj.AtualizarRegistroAsync(Guid.Parse(idRegistro), "joao", "joao@joao.com");
}
Form Atualizado
```

Uma das formas para Passar o Id do Registro que deve ser atualizado, você pode utilizar a função abaixo no javascript:

```javascript
function loadPartialToUpdateRegister() {

    var cshtmlPartialName = "[coloque aqui o nome do partial cshtml que vc fez as regras de atualizar]";
    customPageContext.loadCsHtmlComponent(cshtmlPartialName,
        {
            placeholderId: 'result_cshtml', //parametro opcional, se o cshtml retornar algum html e vc quiser, vc pode colocar o retorno dentro de algum placeholder, div, etc..
            extraData: {
                idRegistro: $('#guidRegistro').val(), //supondo que vc tenha um campo (guidRegistro) na tela com o GUID preenchido ref ao id do registro que quer atualizar
            },
            onSuccess: function (result) {
                customPageContext.msg.success("Atualização com sucesso", "Confirmação");
            },
            onError: function (error) {
                customPageContext.msg.error("Atualização nao realizada", "Erro");
                console.log('error', error)                
            }
        
        }
     )
}
```


#### Update usando cshtml

```c#
@{
      var idRegistro = CustomPageContext.GetParam("idRegistro");
  
        //troque o valor da variavel estruturaformularioidASerCriadoOuAtualizado para o Id do Estrutura do Formulario que você quer atualizar um registro  
      var estruturaformularioidASerCriadoOuAtualizado = Guid.Parse("0153b02c-d4d8-4747-9a69-45aafa113f81");

      //preencher a collection valuesToSave com os valores para o form que quer salvar    
      var valuesToSave = new DataDictionary();
      valuesToSave.Add("id", idRegistro);
      valuesToSave.Add("name", nome);
      valuesToSave.Add("value1", email);
  
      await CustomPageContext.SaveEntityAsync(estruturaformularioidASerCriadoOuAtualizado, valuesToSave);
  
}
Form Atualizado


```

Uma das formas para Passar o Id do Registro que deve ser atualizado, você pode utilizar a função abaixo no javascript:

```javascript
function loadPartialToUpdateRegister() {

    var cshtmlPartialName = "[coloque aqui o nome do partial cshtml que vc fez as regras de atualizar]";
    customPageContext.loadCsHtmlComponent(cshtmlPartialName,
        {
            placeholderId: 'result_cshtml', //parametro opcional, se o cshtml retornar algum html e vc quiser, vc pode colocar o retorno dentro de algum placeholder, div, etc..
            extraData: {
                idRegistro: $('#guidRegistro').val(), //supondo que vc tenha um campo (guidRegistro) na tela com o GUID preenchido ref ao id do registro que quer atualizar
            },
            onSuccess: function (result) {
                customPageContext.msg.success("Atualização com sucesso", "Confirmação");
            },
            onError: function (error) {
                customPageContext.msg.error("Atualização nao realizada", "Erro");
                console.log('error', error)                
            }
        
        }
     )
}
```

## Para Deletar (Delete)

#### Delete usando C#

```c#
public class ExemploMinhaClasseCsharp{

      public async Task DeletarRegistroAsync(Guid idRegistro){

        await CustomPageContext.DeleteAsync(idRegistro);
    
     }

  
}

public ExemploMinhaClasseCsharp CreateInstanceExemploMinhaClasseCsharp(){
    var obj = CreateInstance<ExemploMinhaClasseCsharp>();
    return obj;
}
```


##### Agora você precisa chamar esse metodo dentro do seu page&lt;body&gt; ou no partial cshtml.

```c#
@{
    var obj = CustomPageClass.CreateInstanceExemploMinhaClasseCsharp();

    var idRegistro = CustomPageContext.GetParam("idRegistro");
    await obj.DeletarRegistroAsync(Guid.Parse(idRegistro));
}
Form Deletado
```

Uma das formas para Passar o Id do Registro que deve ser atualizado, você pode utilizar a função abaixo no javascript:

```javascript
function loadPartialToDeleteRegister() {

    var cshtmlPartialName = "[coloque aqui o nome do partial cshtml que vc fez as regras de deletar]";
    customPageContext.loadCsHtmlComponent(cshtmlPartialName,
        {
            placeholderId: 'result_cshtml', //parametro opcional, se o cshtml retornar algum html e vc quiser, vc pode colocar o retorno dentro de algum placeholder, div, etc..
            extraData: {
                idRegistro: $('#guidRegistro').val(), //supondo que vc tenha um campo (guidRegistro) na tela com o GUID preenchido ref ao id do registro que quer deletar
            },
            onSuccess: function (result) {
                customPageContext.msg.success("Removido com sucesso", "Confirmação");
            },
            onError: function (error) {
                customPageContext.msg.error("Remoção nao realizada", "Erro");
                console.log('error', error)                
            }
        
        }
     )
}
```


#### Delete usando cshtml

```c#
@{
      var idRegistro = CustomPageContext.GetParam("idRegistro");
  
      await CustomPageContext.DeleteAsync(idRegistro);
  
}
Form Atualizado


```

Uma das formas para Passar o Id do Registro que deve ser atualizado, você pode utilizar a função abaixo no javascript:

```javascript
function loadPartialToDeleteRegister() {

    var cshtmlPartialName = "[coloque aqui o nome do partial cshtml que vc fez as regras de deletar]";
    customPageContext.loadCsHtmlComponent(cshtmlPartialName,
        {
            placeholderId: 'result_cshtml', //parametro opcional, se o cshtml retornar algum html e vc quiser, vc pode colocar o retorno dentro de algum placeholder, div, etc..
            extraData: {
                idRegistro: $('#guidRegistro').val(), //supondo que vc tenha um campo (guidRegistro) na tela com o GUID preenchido ref ao id do registro que quer deletar
            },
            onSuccess: function (result) {
                customPageContext.msg.success("Removido com sucesso", "Confirmação");
            },
            onError: function (error) {
                customPageContext.msg.error("Remoção nao realizada", "Erro");
                console.log('error', error)                
            }
        
        }
     )
}
```

# [Custom Page] Como abrir outra página ou um lightbox / modal a partir do Custom Page

```javascript

function openLightBox(tamanho, url) {
    var __baseUrl = customPageContext.url.getBaseUrl();

    url = __baseUrl + url; 
    customPageContext.openLightBox(url, tamanho)
}



//Abrir lightbox tela cheia
//Abrir um custom page
openLightBox('fullscreen', 'custompage/6d6d2752-5fcd-4303-aa1b-1ab9e32b38d3') 

//Abrir lightbox tamanho grande
//Abrir um form de cadastro
openLightBox('g', 'fluxo/index/0153b02c-d4d8-4747-9a69-45aafa113f81/1f25c74f-a048-4d83-86eb-f31b9608b615') 

//Abrir lightbox tamanho médio
//Abrir um list de um form
openLightBox('m', 'fluxo/list/0153b02c-d4d8-4747-9a69-45aafa113f81') 

//Abrir lightbox tamanho pequeno
//abrir um board
openLightBox('p', '/b/YKYZ92/custom-code') 
```

# [Form] Quais são as funções nativas do AgilityFlow disponíveis no JavaScript para utilizar em um Formulário? formContext

O módulo `formContext` fornece uma série de funções utilitárias para manipulação de formulários, campos, datas, mensagens e outras funcionalidades no contexto de um formulário personalizado. Abaixo estão as funcionalidades disponíveis, organizadas por categoria.

---

**Verificações de Contexto**

#### `parentFrame`

Identifica e armazena a referência do iframe pai.

```
formContext.parentFrame
```

<div aria-live="polite" class="cm-announced" id="bkmrk-com-essa-op%C3%A7%C3%A3o-voc%C3%AA-">Com essa opção você pode ter acesso ao contexto do form pai que abriu o form atual por exemplo.</div><div aria-live="polite" class="cm-announced" id="bkmrk--1"></div><div aria-live="polite" class="cm-announced" id="bkmrk-sendo-assim-voc%C3%AA-pod">Sendo assim você poderia utilizar todas as funções disponíveis no form pai, exemplo:</div>```javascript
formContext.parentFrame.formContext.field.getValue("xxx")
```

### `isMobile()`

Verifica se o dispositivo é móvel.

- **Retorno:**
    
    
    - `true` se for um dispositivo móvel.
    - `false` caso contrário.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    if (formContext.isMobile()) {
        console.log("Dispositivo móvel detectado.");
    }
    ```

---

### `isPublicPortal()`

Verifica se o formulário está sendo exibido em um portal público.

- **Retorno:**
    
    
    - `true` se for um portal público.
    - `false` caso contrário.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    if (formContext.isPublicPortal()) {
        console.log("Formulário em portal público.");
    }
    ```

---


### `isPublicForm()`

Verifica se o formulário é público (mesma lógica de `isPublicPortal`).

- **Retorno:**
    
    
    - `true` se for um formulário público.
    - `false` caso contrário.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    if (formContext.isPublicForm()) {
        console.log("Formulário público detectado.");
    }
    ```

---

## **Redirecionamento**

### `redirectTo(url)`

Redireciona para uma URL especificada.

- **Parâmetros:**
    
    
    - `url` (String): URL para redirecionamento.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.redirectTo("https://www.exemplo.com");
    ```

---

## **Abrir Lightbox**

### `openLightBox(link, tamanholightbox, titulo)`

Abre uma lightbox com o conteúdo da URL especificada.

- **Parâmetros:**
    
    
    - `link` (String): URL a ser carregada na lightbox.
    - `tamanholightbox` (String): Tamanho da lightbox. Valores possíveis: `'p'`, `'m'`, `'g'`, `'fullscreen'`, `'fullscreen-headerless'`.
    - `titulo` (String): Título da lightbox.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.openLightBox("https://www.exemplo.com", "m", "Título da Lightbox");
    ```

---

## **Carregamento de Arquivos JavaScript**

### `addJavascriptFile(options)`

Adiciona um arquivo JavaScript à página de forma assíncrona e executa um callback após o carregamento.

- **Parâmetros:**
    
    
    - `options` (Object): Objeto com as propriedades:
        
        
        - `file_url` (String): URL do arquivo JavaScript.
        - `callback_onload` (Function): Função a ser executada após o carregamento do arquivo.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.addJavascriptFile({
        file_url: "https://www.exemplo.com/script.js",
        callback_onload: function() {
            console.log("Script carregado!");
        }
    });
    ```

---

## **Busca de CEP**

### `buscaCEP.configurar(idCampoCep, idCamposPreenchiveis, callbacks)`

Configura a busca de CEP para campos específicos.

- **Parâmetros:**
    
    
    - `idCampoCep` (String): ID do campo de CEP.
    - `idCamposPreenchiveis` (String): ID dos campos a serem preenchidos com os dados do CEP.
    - `callbacks` (Object): Callbacks para eventos relacionados à busca de CEP.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.buscaCEP.configurar("cep", "endereco", {
        onSuccess: function(data) {
            console.log("CEP encontrado:", data);
        }
    });
    ```

---

## **Carregamento de Componentes CSHTML**

### `loadCsHtmlComponent(componentName, options)`

Carrega um componente CSHTML via AJAX.

- **Parâmetros:**
    
    
    - `componentName` (String): Nome do componente.
    - `options` (Object): Opções adicionais para o carregamento.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```javascript
    function loadPartial() {
    
        var cshtmlPartialName = "[coloque aqui o nome do partial cshtml que vc fez as regras de atualizar]";
        formContext.loadCsHtmlComponent(cshtmlPartialName,
            {
                placeholderId: 'result_cshtml', //parametro opcional, se o cshtml retornar algum html e vc quiser, vc pode colocar o retorno dentro de algum placeholder, div, etc..
                extraData: {
                    idRegistro: $('#guidRegistro').val(), 
                    nome: $('#nome').val(), 
                    email: $('#email').val()
                },
                onSuccess: function (result) {
                    formContext.msg.success("Executado com sucesso", "Confirmação");
                },
                onError: function (error) {
                    formContext.msg.error("Execução não realizada", "Erro");
                    console.log('error', error)                
                }
            
            }
         )
    }
    ```

---

## **Manipulação de URLs**

### `url.getBaseUrl()`

Retorna a URL base do sistema.

- **Retorno:**
    
    
    - String com a URL base.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    console.log("URL base:", formContext.url.getBaseUrl());
    ```

---

### `url.getStaticFileUrl()`

Retorna a URL base para arquivos estáticos.

- **Retorno:**
    
    
    - String com a URL de arquivos estáticos.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    console.log("URL de arquivos estáticos:", formContext.url.getStaticFileUrl());
    ```

---

## **Idioma Atual**

### `currentLanguage.get()`

Retorna o idioma atual do sistema.

- **Retorno:**
    
    
    - String com o código do idioma (ex: `'pt-BR'`, `'en-US'`).
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    console.log("Idioma atual:", formContext.currentLanguage.get());
    ```

---

### `currentLanguage.isEnglish()`

Verifica se o idioma atual é inglês.

- **Retorno:**
    
    
    - `true` se for inglês.
    - `false` caso contrário.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    if (formContext.currentLanguage.isEnglish()) {
        console.log("Idioma atual é inglês.");
    }
    ```

---

### `currentLanguage.getIIF_TextFromCurrentLanguage(text_ptBR, text_ENG, text_ESP)`

Retorna o texto correspondente ao idioma atual.

- **Parâmetros:**
    
    
    - `text_ptBR` (String): Texto em português.
    - `text_ENG` (String): Texto em inglês.
    - `text_ESP` (String): Texto em espanhol.
- **Retorno:**
    
    
    - String com o texto no idioma atual.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    const texto = formContext.currentLanguage.getIIF_TextFromCurrentLanguage("Olá", "Hello", "Hola");
    console.log(texto); // Retorna "Olá" se o idioma for português.
    ```

---

## **Mensagens**

O módulo `formContext.msg` fornece funções para exibir e ocultar mensagens de alerta, erro, sucesso e aviso no sistema. Abaixo estão as funcionalidades disponíveis.

---

### **Ocultar Mensagens**

### `hide(forcarFechar)`

Oculta todas as mensagens exibidas.

- **Parâmetros:**
    
    
    - `forcarFechar` (Boolean): Força o fechamento das mensagens.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.msg.hide(true); // Oculta todas as mensagens, forçando o fechamento.
    ```

---

### **Exibir Mensagens**

### `show(type, msg, title, options)`

Exibe uma mensagem de alerta, erro, sucesso ou aviso.

- **Parâmetros:**
    
    
    - `type` (String): Tipo da mensagem. Valores possíveis:
        
        
        - `'warning'`: Mensagem de aviso.
        - `'error'`: Mensagem de erro.
        - `'success'`: Mensagem de sucesso.
    - `msg` (String): Texto da mensagem.
    - `title` (String): Título da mensagem.
    - `options` (Object): Opções adicionais para personalização da mensagem.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.msg.show("success", "Operação realizada com sucesso!", "Sucesso", { timeout: 5000 });
    ```

---

### `warning(msg, title, options)`

Exibe uma mensagem de aviso.

- **Parâmetros:**
    
    
    - `msg` (String): Texto da mensagem.
    - `title` (String): Título da mensagem.
    - `options` (Object): Opções adicionais.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.msg.warning("Atenção: Este campo é obrigatório.", "Aviso");
    ```

---

### `error(msg, title)`

Exibe uma mensagem de erro.

- **Parâmetros:**
    
    
    - `msg` (String): Texto da mensagem.
    - `title` (String): Título da mensagem.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.msg.error("Ocorreu um erro ao salvar o formulário.", "Erro");
    ```

---

### `success(msg, title, options)`

Exibe uma mensagem de sucesso.

- **Parâmetros:**
    
    
    - `msg` (String): Texto da mensagem.
    - `title` (String): Título da mensagem.
    - `options` (Object): Opções adicionais.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.msg.success("Formulário salvo com sucesso!", "Sucesso", { timeout: 3000 });
    ```

---

### **Funções Legadas de Mensagens**

As funções abaixo são mantidas para compatibilidade com versões anteriores, mas é recomendado utilizar as funções acima (`show`, `warning`, `error`, `success`).

### `hideMsgs()`

Oculta todas as mensagens exibidas.

- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.msg.hideMsgs();
    ```

---

### `showMsgWarning(msg, title, options)`

Exibe uma mensagem de aviso (legado).

- **Parâmetros:**
    
    
    - `msg` (String): Texto da mensagem.
    - `title` (String): Título da mensagem.
    - `options` (Object): Opções adicionais.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.msg.showMsgWarning("Atenção: Este campo é obrigatório.", "Aviso");
    ```

---

### `showMsgError(msg, title)`

Exibe uma mensagem de erro (legado).

- **Parâmetros:**
    
    
    - `msg` (String): Texto da mensagem.
    - `title` (String): Título da mensagem.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.msg.showMsgError("Ocorreu um erro ao salvar o formulário.", "Erro");
    ```

---

### `showMsgSuccess(msg, title, options)`

Exibe uma mensagem de sucesso (legado).

- **Parâmetros:**
    
    
    - `msg` (String): Texto da mensagem.
    - `title` (String): Título da mensagem.
    - `options` (Object): Opções adicionais.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.msg.showMsgSuccess("Formulário salvo com sucesso!", "Sucesso", { timeout: 3000 });
    ```

---

### **Exemplos de Uso de Mensagem**

##### Exibindo uma mensagem de sucesso:

```
formContext.msg.success("Dados salvos com sucesso!", "Sucesso", { timeout: 5000 });
```

##### Exibindo uma mensagem de erro:

```
formContext.msg.error("Erro ao processar a solicitação.", "Erro");
```

##### Ocultando todas as mensagens:

<div class="md-code-block" id="bkmrk-javascript-copy-2"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
</div></div></div></div></div>```
formContext.msg.hide(true);
```


## **Manipulação de Números**

### `number.convertString_toNumber(strValueToConvert, qtdCasasDecimais)`

Converte uma string formatada em número.

- **Parâmetros:**
    
    
    - `strValueToConvert` (String): Valor em formato de string.
    - `qtdCasasDecimais` (Number): Quantidade de casas decimais.
- **Retorno:**
    
    
    - Número convertido.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    const numero = formContext.number.convertString_toNumber("1.000,50", 2);
    console.log(numero); // Retorna 1000.50
    ```

---

### `number.convertNumber_toStringFormatted(numberToConvert, qtdCasasDecimais)`

Converte um número em uma string formatada de acordo com o idioma.

- **Parâmetros:**
    
    
    - `numberToConvert` (Number): Número a ser convertido.
    - `qtdCasasDecimais` (Number): Quantidade de casas decimais.
- **Retorno:**
    
    
    - String formatada.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring">  
    </div></div></div></div>```
    const texto = formContext.number.convertNumber_toStringFormatted(1000.50, 2);
    console.log(texto); // Retorna "1.000,50" em português.
    ```

---


## **Manipulação de Datas**

### `isCurrentMonthAndYear(data)`

Verifica se a data fornecida pertence ao mês e ano atuais.

- **Parâmetros:**
    
    
    - `data` (String): Data no formato `DD/MM/YYYY`.
- **Retorno:**
    
    
    - `true` se a data for do mês e ano atuais.
    - `false` caso contrário.
- **Exceções:**
    
    
    - Lança um `TypeError` se a data estiver em um formato inválido.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring">javascript</div><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">Copy</div></div></div></div></div>```
    formContext.datetime.validation.isCurrentMonthAndYear("25/10/2023"); // Retorna true se outubro de 2023 for o mês e ano atuais.
    ```

---

### `compare(date1, compare, date2)`

Compara duas datas com base no operador especificado.

- **Parâmetros:**
    
    
    - `date1` (String): Primeira data no formato `DD/MM/YYYY`.
    - `compare` (String): Operador de comparação. Valores possíveis:
        
        
        - `'greater'` ou `'>'`
        - `'greater-or-equal'` ou `'>='`
        - `'less'` ou `'<'`
        - `'less-or-equal'` ou `'<='`
        - `'equal'` ou `'=='`
    - `date2` (String): Segunda data no formato `DD/MM/YYYY`.
- **Retorno:**
    
    
    - `true` ou `false`, dependendo da comparação.
- **Exceções:**
    
    
    - Lança um `TypeError` se as datas estiverem em formato inválido ou se o operador de comparação não for reconhecido.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring">javascript</div><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">Copy</div></div></div></div></div>```
    formContext.datetime.validation.compare("25/10/2023", "greater", "20/10/2023"); // Retorna true.
    ```

---

### `compareDatetime(datetime1, compare, datetime2)`

Compara duas datas e horários com base no operador especificado.

- **Parâmetros:**
    
    
    - `datetime1` (String): Primeira data e horário no formato `DD/MM/YYYY HH:mm`.
    - `compare` (String): Operador de comparação. Valores possíveis:
        
        
        - `'greater'` ou `'>'`
        - `'greater-or-equal'` ou `'>='`
        - `'less'` ou `'<'`
        - `'less-or-equal'` ou `'<='`
        - `'equal'` ou `'=='`
    - `datetime2` (String): Segunda data e horário no formato `DD/MM/YYYY HH:mm`.
- **Retorno:**
    
    
    - `true` ou `false`, dependendo da comparação.
- **Exceções:**
    
    
    - Lança um `TypeError` se os dados estiverem em formato inválido ou se o operador de comparação não for reconhecido.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring">javascript</div><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">Copy</div></div></div></div></div>```
    formContext.datetime.validation.compareDatetime("25/10/2023 14:30", "greater", "25/10/2023 12:00"); // Retorna true.
    ```

---

### `compareToday(compare, date2)`

Compara a data atual com uma data fornecida.

- **Parâmetros:**
    
    
    - `compare` (String): Operador de comparação. Valores possíveis:
        
        
        - `'greater'` ou `'>'`
        - `'greater-or-equal'` ou `'>='`
        - `'less'` ou `'<'`
        - `'less-or-equal'` ou `'<='`
        - `'equal'` ou `'=='`
    - `date2` (String): Data no formato `DD/MM/YYYY`.
- **Retorno:**
    
    
    - `true` ou `false`, dependendo da comparação.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring">javascript</div><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">Copy</div></div></div></div></div>```
    formContext.datetime.validation.compareToday("less", "30/10/2023"); // Retorna true se a data atual for menor que 30/10/2023.
    ```

---

## **Adição de Tempo**

### `day(data, days)`

Adiciona dias a uma data.

- **Parâmetros:**
    
    
    - `data` (String): Data no formato `DD/MM/YYYY` ou `DD/MM/YYYY HH:mm`.
    - `days` (Number): Número de dias a serem adicionados.
- **Retorno:**
    
    
    - Data resultante no mesmo formato da entrada.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring">javascript</div><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">Copy</div></div></div></div></div>```
    formContext.datetime.add.day("25/10/2023", 5); // Retorna "30/10/2023".
    ```

---

### `month(data, months)`

Adiciona meses a uma data.

- **Parâmetros:**
    
    
    - `data` (String): Data no formato `DD/MM/YYYY` ou `DD/MM/YYYY HH:mm`.
    - `months` (Number): Número de meses a serem adicionados.
- **Retorno:**
    
    
    - Data resultante no mesmo formato da entrada.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring">javascript</div><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">Copy</div></div></div></div></div>```
    formContext.datetime.add.month("25/10/2023", 2); // Retorna "25/12/2023".
    ```

---

### `year(data, years)`

Adiciona anos a uma data.

- **Parâmetros:**
    
    
    - `data` (String): Data no formato `DD/MM/YYYY` ou `DD/MM/YYYY HH:mm`.
    - `years` (Number): Número de anos a serem adicionados.
- **Retorno:**
    
    
    - Data resultante no mesmo

---

### `hour(data, hours)`

Adiciona horas a uma data e horário.

- **Parâmetros:**
    
    
    - `data` (String): Data e horário no formato `DD/MM/YYYY HH:mm`.
    - `hours` (Number): Número de horas a serem adicionadas.
- **Retorno:**
    
    
    - Data e horário resultante no formato `DD/MM/YYYY HH:mm`.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring">javascript</div><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">Copy</div></div></div></div></div>```
    formContext.datetime.add.hour("25/10/2023 14:30", 3); // Retorna "25/10/2023 17:30".
    ```

---

### `minute(data, minutes)`

Adiciona minutos a uma data e horário.

- **Parâmetros:**
    
    
    - `data` (String): Data e horário no formato `DD/MM/YYYY HH:mm`.
    - `minutes` (Number): Número de minutos a serem adicionados.
- **Retorno:**
    
    
    - Data e horário resultante no formato `DD/MM/YYYY HH:mm`.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring">javascript</div><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">Copy</div></div></div></div></div>```
    formContext.datetime.add.minute("25/10/2023 14:30", 15); // Retorna "25/10/2023 14:45".
    ```

---

## **Obtenção de Datas**

### `getLastDayOfCurrentMonth()`

Retorna o último dia do mês atual.

- **Retorno:**
    
    
    - Data no formato `DD/MM/YYYY`.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring">javascript</div><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">Copy</div></div></div></div></div>```
    formContext.datetime.getLastDayOfCurrentMonth(); // Retorna "31/10/2023" se outubro for o mês atual.
    ```

---

### `getLastDayOfMonth(data)`

Retorna o último dia do mês da data fornecida.

- **Parâmetros:**
    
    
    - `data` (String): Data no formato `DD/MM/YYYY`.
- **Retorno:**
    
    
    - Data no formato `DD/MM/YYYY`.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring">javascript</div><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">Copy</div></div></div></div></div>```
    formContext.datetime.getLastDayOfMonth("25/10/2023"); // Retorna "31/10/2023".
    ```

---

## **Data e Horário Atuais**

### `getDateNow()`

Retorna a data e horário atuais.

- **Retorno:**
    
    
    - Objeto `Date` representando a data e horário atuais.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring">javascript</div><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">Copy</div></div></div></div></div>```
    formContext.datetime.getDateNow(); // Retorna a data e horário atuais.
    ```

---

### `getFormattedDateTime()`

Retorna a data e horário atuais formatados.

- **Retorno:**
    
    
    - String no formato `DD/MM/YYYY HH:mm`.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring">javascript</div><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">Copy</div></div></div></div></div>```
    formContext.datetime.getFormattedDateTime(); // Retorna "25/10/2023 14:30".
    ```

---

### `getFormattedDate()`

Retorna a data atual formatada.

- **Retorno:**
    
    
    - String no formato `DD/MM/YYYY`.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-infostring">javascript</div><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">Copy</div></div></div></div></div>```
    formContext.datetime.getFormattedDate(); // Retorna "25/10/2023".
    ```




## **Manipulação de Campos**

O módulo `formContext.field` fornece funções para manipular campos em formulários, como verificar assinaturas, controlar campos obrigatórios, gerenciar selects, ocultar/exibir campos, habilitar/desabilitar campos e definir/obter valores. Abaixo estão as funcionalidades disponíveis.

---

### **Campo de Assinatura**

### `signature.isDefined(campokey)`

Verifica se uma assinatura foi preenchida em um campo específico.

- **Parâmetros:**
    
    
    - `campokey` (String): ID do campo de assinatura.
- **Retorno:**
    
    
    - `true` se a assinatura foi preenchida.
    - `false` caso contrário.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    if (formContext.field.signature.isDefined("assinatura")) {
        console.log("Assinatura preenchida.");
    }
    ```

---

### **Campos Obrigatórios**

### `required.ignoreRequired(campokey)`

Ignora a validação de campo obrigatório para um campo específico.

- **Parâmetros:**
    
    
    - `campokey` (String): ID do campo.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.field.required.ignoreRequired("campo1"); // Ignora a validação de campo obrigatório para "campo1".
    ```

---

### `required.unsetIgnoreRequired(campokey)`

Remove a configuração de ignorar validação de campo obrigatório para um campo específico.

- **Parâmetros:**
    
    
    - `campokey` (String): ID do campo.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.field.required.unsetIgnoreRequired("campo1"); // Remove a configuração de ignorar validação para "campo1".
    ```

---

### **Campos Select Personalizados**

### `customSelect.setDefaultStyle(selector)`

Aplica o estilo padrão do sistema a um select personalizado.

- **Parâmetros:**
    
    
    - `selector` (String): Seletor do campo select.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.field.customSelect.setDefaultStyle("meuSelect"); // Aplica o estilo padrão ao select com ID "meuSelect".
    ```

---

### **Manipulação de Itens em Campos Select Personalizados**

### `select.items.disable(campokey, valuesToDisable)`

Desabilita itens específicos em um campo select.

- **Parâmetros:**
    
    
    - `campokey` (String): ID do campo select.
    - `valuesToDisable` (String ou Array): Valor(es) do(s) item(ns) a ser(em) desabilitado(s).
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.field.select.items.disable("meuSelect", "valor1"); // Desabilita o item com valor "valor1".
    formContext.field.select.items.disable("meuSelect", ["valor1", "valor2"]); // Desabilita os itens com valores "valor1" e "valor2".
    ```

---

### `select.items.enable(campokey, valuesToDisable)`

Habilita itens específicos em um campo select.

- **Parâmetros:**
    
    
    - `campokey` (String): ID do campo select.
    - `valuesToDisable` (String ou Array): Valor(es) do(s) item(ns) a ser(em) habilitado(s).
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.field.select.items.enable("meuSelect", "valor1"); // Habilita o item com valor "valor1".
    formContext.field.select.items.enable("meuSelect", ["valor1", "valor2"]); // Habilita os itens com valores "valor1" e "valor2".
    ```

---

### `select.items.disableAll(campokey)`

Desabilita todos os itens de um campo select.

- **Parâmetros:**
    
    
    - `campokey` (String): ID do campo select.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.field.select.items.disableAll("meuSelect"); // Desabilita todos os itens do select.
    ```

---

### `select.items.enableAll(campokey)`

Habilita todos os itens de um campo select.

- **Parâmetros:**
    
    
    - `campokey` (String): ID do campo select.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.field.select.items.enableAll("meuSelect"); // Habilita todos os itens do select.
    ```

---

### **Visibilidade de Campos**

### `hide(campokey)`

Oculta um campo específico.

- **Parâmetros:**
    
    
    - `campokey` (String ou Array): ID do campo ou lista de IDs.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.field.hide("campo1"); // Oculta o campo com ID "campo1".
    formContext.field.hide(["campo1", "campo2"]); // Oculta os campos com IDs "campo1" e "campo2".
    ```

---

### `show(campokey)`

Exibe um campo específico.

- **Parâmetros:**
    
    
    - `campokey` (String ou Array): ID do campo ou lista de IDs.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.field.show("campo1"); // Exibe o campo com ID "campo1".
    formContext.field.show(["campo1", "campo2"]); // Exibe os campos com IDs "campo1" e "campo2".
    ```

---

### `hideAll()`

Oculta todos os campos do formulário.

- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.field.hideAll(); // Oculta todos os campos.
    ```

---

### `showAll()`

Exibe todos os campos do formulário.

- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.field.showAll(); // Exibe todos os campos.
    ```

---

### **Habilitação/Desabilitação de Campos**

### `disable(campokey)`

Desabilita um campo específico.

- **Parâmetros:**
    
    
    - `campokey` (String ou Array): ID do campo ou lista de IDs.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.field.disable("campo1"); // Desabilita o campo com ID "campo1".
    formContext.field.disable(["campo1", "campo2"]); // Desabilita os campos com IDs "campo1" e "campo2".
    ```

---

### `enable(campokey)`

Habilita um campo específico.

- **Parâmetros:**
    
    
    - `campokey` (String ou Array): ID do campo ou lista de IDs.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.field.enable("campo1"); // Habilita o campo com ID "campo1".
    formContext.field.enable(["campo1", "campo2"]); // Habilita os campos com IDs "campo1" e "campo2".
    ```

---

### `disableAll()`

Desabilita todos os campos do formulário.

- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.field.disableAll(); // Desabilita todos os campos.
    ```

---

### `enableAll()`

Habilita todos os campos do formulário.

- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.field.enableAll(); // Habilita todos os campos.
    ```

---

### **Definição e Obtenção de Valores de Campos**

### `setValue(campoKey, value, options)`

Define o valor de um campo.

- **Parâmetros:**
    
    
    - `campoKey` (String): ID do campo.
    - `value` (String): Valor a ser definido.
    - `options` (Object): Opções adicionais.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    formContext.field.setValue("campo1", "Valor exemplo"); // Define o valor do campo "campo1".
    ```

---

### `getValue(campoKey)`

Obtém o valor de um campo.

- **Parâmetros:**
    
    
    - `campoKey` (String): ID do campo.
- **Retorno:**
    
    
    - Valor do campo.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    const valor = formContext.field.getValue("campo1"); // Obtém o valor do campo "campo1".
    ```

---

### `getText(campoKey)`

Obtém o texto exibido de um campo.

- **Parâmetros:**
    
    
    - `campoKey` (String): ID do campo.
- **Retorno:**
    
    
    - Texto do campo.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    const texto = formContext.field.getText("campo1"); // Obtém o texto do campo "campo1".
    ```

---

### `getInt(campoKey)`

Obtém o valor de um campo como número inteiro.

- **Parâmetros:**
    
    
    - `campoKey` (String): ID do campo.
- **Retorno:**
    
    
    - Valor inteiro.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    const valorInteiro = formContext.field.getInt("campo1"); // Obtém o valor inteiro do campo "campo1".
    ```

---

### `getDecimal(campoKey)`

Obtém o valor de um campo como número decimal.

- **Parâmetros:**
    
    
    - `campoKey` (String): ID do campo.
- **Retorno:**
    
    
    - Valor decimal.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    const valorDecimal = formContext.field.getDecimal("campo1"); // Obtém o valor decimal do campo "campo1".
    ```

---

### `getFloat(campoKey)`

Obtém o valor de um campo como número de ponto flutuante.

- **Parâmetros:**
    
    
    - `campoKey` (String): ID do campo.
- **Retorno:**
    
    
    - Valor de ponto flutuante.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    const valorFloat = formContext.field.getFloat("campo1"); // Obtém o valor de ponto flutuante do campo "campo1".
    ```

---

### `getNumber(campoKey)`

Obtém o valor de um campo como número (inteiro ou decimal, dependendo da máscara do campo).

- **Parâmetros:**
    
    
    - `campoKey` (String): ID do campo.
- **Retorno:**
    
    
    - Valor numérico.
- **Exemplo:**
    
    <div class="md-code-block"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner"><div class="md-code-block-action"><div class="ds-markdown-code-copy-button">  
    </div></div></div></div></div>```
    const valorNumerico = formContext.field.getNumber("campo1"); // Obtém o valor numérico do campo "campo1".
    ```

## **Manipulação do Formulário** 

O objeto `formContext.form` gerencia diversas funcionalidades relacionadas ao formulário, incluindo salvamento, rascunhos, ações e manipulação da toolbar.

#### **Estrutura do Objeto formContext.form**

- `formContext.form`: Contém funcionalidades relacionadas ao formulário.
    
    
    - `save()`: Salva o formulário.
    - `saveDraft()`: Salva o formulário como rascunho.
    - `undoDraft()`: Desfaz um rascunho.
    - `getFormActionOnSubmit()`: Obtém o tipo de envio do formulário.
    - `invalidateForm(options)`: Inválida o submit do formulário.
    - `toolbar`: Manipula a toolbar do formulário.
    - `disableNativeSuccessMsg()`: Desabilita mensagens nativas de sucesso.
    - `forceToSetStateFormToChanged()`: Força o status do formulário para "alterado".
    - `isNew()`: Verifica se o formulário é novo.
    - `isDraft()`: Verifica se o formulário é um rascunho.
    - `action`: Define os tipos de ações possíveis no formulário.

### **Funções e Exemplos de Uso do formContext.form**

### `save()`

Salva o formulário.

```
formContext.form.save();
```

### `saveDraft()`

Salva o formulário como rascunho.

```
formContext.form.saveDraft();
```

### `undoDraft()`

Desfaz um rascunho.

```
formContext.form.undoDraft();
```

### `getFormActionOnSubmit()`

Obtém o tipo de envio do formulário.

```
var action = formContext.form.getFormActionOnSubmit();
console.log(action);
```

### `invalidateForm(options)`

Inválida o submit do formulário.

```
formContext.form.invalidateForm({ message: "Erro ao enviar!" });
```

### `toolbar.hide()`

Esconde a toolbar.

```
formContext.form.toolbar.hide();
```

### `toolbar.show()`

Exibe a toolbar.

```
formContext.form.toolbar.show();
```

### `toolbar.remove()`

Remove a toolbar.

```
formContext.form.toolbar.remove();
```

### `disableNativeSuccessMsg()`

Desabilita mensagens nativas de sucesso.

```
formContext.form.disableNativeSuccessMsg();
```

### `forceToSetStateFormToChanged()`

Força o status do formulário para "alterado".

```
formContext.form.forceToSetStateFormToChanged();
```

### `isNew()`

Verifica se o formulário é novo.

```
if (formContext.form.isNew()) {
    console.log("Formulário novo");
}
```

### `isDraft()`

Verifica se o formulário é um rascunho.

```
if (formContext.form.isDraft()) {
    console.log("Formulário em rascunho");
}
```

### Funções e Exemplos de Uso do formContext.form.action

### `action.isSave(formAction)`

Verifica se a ação é de salvar.

```
if (formContext.form.action.isSave(1)) {
    console.log("Ação de salvar detectada");
}
```

### `action.isSaveDraft(formAction)`

Verifica se a ação é de salvar como rascunho.

```
if (formContext.form.action.isSaveDraft(2)) {
    console.log("Ação de salvar rascunho");
}
```

### `action.isDiscardDraft(formAction)`

Verifica se a ação é de descartar o rascunho.

```
if (formContext.form.action.isDiscardDraft(3)) {
    console.log("Ação de descartar rascunho");
}
```

### `action.isApproveFromWorkflow(formAction)`

Verifica se a ação é de aprovar no workflow.

```
if (formContext.form.action.isApproveFromWorkflow(4)) {
    console.log("Ação de aprovação no workflow");
}
```

### `action.isRejectFromWorkflow(formAction)`

Verifica se a ação é de rejeitar no workflow.

```
if (formContext.form.action.isRejectFromWorkflow(5)) {
    console.log("Ação de rejeição no workflow");
}
```

### `action.isReturnFromWorkflow(formAction)`

Verifica se a ação é de retorno no workflow.

```
if (formContext.form.action.isReturnFromWorkflow(6)) {
    console.log("Ação de retorno no workflow");
}
```

### `action.isDelete(formAction)`

Verifica se a ação é de deleção.

```
if (formContext.form.action.isDelete(7)) {
    console.log("Ação de deleção detectada");
}
```

### `action.isSaveChildForm(formAction)`

Verifica se a ação é de salvar um formulário filho.

```
if (formContext.form.action.isSaveChildForm(8)) {
    console.log("Ação de salvar formulário filho");
}
```

### `action.isDeleteChildForm(formAction)`

Verifica se a ação é de deletar um formulário filho.

```
if (formContext.form.action.isDeleteChildForm(9)) {
    console.log("Ação de deletar formulário filho");
}
```

<div id="bkmrk--69">---

</div>
## **Manipulação do Formulário Filho (Child Form)** `formContext.childForm`

### `datatable.refresh(tableid_relacaoFormularioPaiFilhoId)`

Atualiza a tabela do formulário filho que está no formulário pai.

#### Exemplo de Uso:

```
formContext.childForm.datatable.refresh("tabela123");
```

<div id="bkmrk--71">---

</div>### `datatable.totalRows(tableid_relacaoFormularioPaiFilhoId)`

Retorna o número total de linhas da tabela do formulário filho.

#### Exemplo de Uso:

```
var total = formContext.childForm.datatable.totalRows("tabela123");
console.log("Total de linhas:", total);
```

<div id="bkmrk--72">---

</div>### `datatable.getAllChildIds(tableid_relacaoFormularioPaiFilhoId)`

Retorna todos os IDs dos formulários filhos presentes na tabela.

#### Exemplo de Uso:

```
var ids = formContext.childForm.datatable.getAllChildIds("tabela123");
console.log("IDs dos formulários filhos:", ids);
```

<div id="bkmrk--73">---

</div>### `datatable.getAllChildIdsOrdered(tableid_relacaoFormularioPaiFilhoId)`

Retorna todos os IDs dos formulários filhos respeitando a ordenação atual.

#### Exemplo de Uso:

```
var orderedIds = formContext.childForm.datatable.getAllChildIdsOrdered("tabela123");
console.log("IDs ordenados:", orderedIds);
```

<div id="bkmrk--74">---

</div>### `datatable.getResultJson(tableid_relacaoFormularioPaiFilhoId)`

Retorna um JSON com os resultados apresentados na tabela do formulário filho.

#### Exemplo de Uso:

```
var result = formContext.childForm.datatable.getResultJson("tabela123");
console.log("Resultados da tabela:", result);
```

<div id="bkmrk--75">---

</div>### `datatable.setOrder(tableid_relacaoFormularioPaiFilhoId, items_sorted)`

Reordena os itens da tabela filha conforme a lista ordenada de IDs.

#### Exemplo de Uso:

```
var sortedItems = [
    { formid: "123", draftid: "" },
    { formid: "456", draftid: "" },
    { formid: "789", draftid: "" }
];
formContext.childForm.datatable.setOrder("tabela123", sortedItems);
```

<div id="bkmrk--76">---

</div>### `blockLinkEditOpening()`

Bloqueia a abertura do link ao clicar na linha do grid.

#### Exemplo de Uso:

```
formContext.childForm.blockLinkEditOpening();
```

<div id="bkmrk--77">---

</div>### `unlockLinkEditOpening()`

Desbloqueia a abertura do link ao clicar na linha do grid.

#### Exemplo de Uso:

```
formContext.childForm.unlockLinkEditOpening();
```



## **Painéis** `formContext.panel`


O módulo `formContext.panel` fornece funções para manipular painéis (grupo de informações), como exibir, ocultar e controlar o estado de colapso (aberto/fechado). Abaixo estão as funcionalidades disponíveis.

---

### **Exibir e Ocultar Painéis**

### `hide(panelId)`

Oculta um painel específico.

- **Parâmetros:**
    
    
    - `panelId` (String): ID do painel a ser ocultado.
- **Exemplo:**
    
    ```
    formContext.panel.hide("painel1"); // Oculta o painel com ID "painel1".
    ```

---

### `show(panelId)`

Exibe um painel específico.

- **Parâmetros:**
    
    
    - `panelId` (String): ID do painel a ser exibido.
- **Exemplo:**
    
    ```
    formContext.panel.show("painel1"); // Exibe o painel com ID "painel1".
    ```

---

### **Expandir e Recolher Painéis**

O módulo `collapse` permite controlar o estado de colapso (aberto/fechado) de um painel.

### `collapse.toggle(panelId)`

Alterna o estado de colapso de um painel (abre se estiver fechado e fecha se estiver aberto).

- **Parâmetros:**
    
    
    - `panelId` (String): ID do painel.
- **Exemplo:**
    
    ```
    formContext.panel.collapse.toggle("painel1"); // Alterna o estado de colapso do painel com ID "painel1".
    ```

---

### `collapse.isCollapsed(panelId)`

Verifica se um painel está colapsado (fechado).

- **Parâmetros:**
    
    
    - `panelId` (String): ID do painel.
- **Retorno:**
    
    
    - `true` se o painel estiver colapsado.
    - `false` se o painel estiver expandido.
- **Exemplo:**
    
    ```
    const estaColapsado = formContext.panel.collapse.isCollapsed("painel1");
    if (estaColapsado) {
        console.log("O painel está fechado.");
    } else {
        console.log("O painel está aberto.");
    }
    ```

---

### `collapse.close(panelId)`

Fecha (colapsa) um painel.

- **Parâmetros:**
    
    
    - `panelId` (String): ID do painel.
- **Exemplo:**
    
    ```
    formContext.panel.collapse.close("painel1"); // Fecha o painel com ID "painel1".
    ```

---

### `collapse.open(panelId)`

Abre (expande) um painel.

- **Parâmetros:**
    
    
    - `panelId` (String): ID do painel.
- **Exemplo:**
    
    ```
    formContext.panel.collapse.open("painel1"); // Abre o painel com ID "painel1".
    ```

---

### **Exemplos de Uso de funções de painéis**

### Ocultando e exibindo um painel:

```
formContext.panel.hide("painel1"); // Oculta o painel.
formContext.panel.show("painel1"); // Exibe o painel.
```

### Alternando o estado de colapso de um painel:

```
formContext.panel.collapse.toggle("painel1"); // Alterna entre aberto e fechado.
```

### Verificando se um painel está colapsado:

```
if (formContext.panel.collapse.isCollapsed("painel1")) {
    console.log("O painel está fechado.");
} else {
    console.log("O painel está aberto.");
}
```

### Fechando e abrindo um painel:

```
formContext.panel.collapse.close("painel1"); // Fecha o painel.
formContext.panel.collapse.open("painel1"); // Abre o painel.
```

# [Custom Page] Como Chamar um Método Global no Custom Page?

Em C#, utilize a classe **GlobalClass,** como no exemplo abaixo:

```c#
//pra chamar um metodo global por exemplo
await GlobalClass.ExecuteExampleAsync()
```

# Como Obter Parâmetros da Query String com JavaScript

## Introdução

A query string é a parte da URL que contém parâmetros, geralmente utilizados para passar informações entre páginas. No JavaScript, podemos extrair esses parâmetros utilizando a API `URLSearchParams`.

## Exemplo de URL

Vamos considerar a seguinte URL:

```
http://seusubdominio.agilifytlow.io?o=valor
```

Neste caso, o parâmetro `o` possui o valor `valor`.

## Código JavaScript

Podemos obter o valor do parâmetro `o` com o seguinte código:

```javascript
// Captura os parâmetros da query string
const urlParams = new URLSearchParams(window.location.search);

// Obtém o valor do parâmetro 'o'
const oValue = urlParams.get('o');

// Exibe o valor no console
console.log(oValue);
```

## Explicação do Código

1. `window.location.search` retorna a parte da URL após o `?`, ou seja, a query string (`?o=valor`).
2. `new URLSearchParams(window.location.search)` cria um objeto que permite manipular e acessar os parâmetros da query string.
3. `urlParams.get('o')` obtém o valor do parâmetro `o`, retornando `'valor'`.
4. `console.log(oValue);` exibe o valor capturado no console do navegador.

## Aplicações Comuns

- Captura de dados para preencher formulário
- Personalização de conteúdo baseado em parâmetros da URL
- Redirecionamentos e filtragens dinâmicas com base em parâmetros

## Tratamento de Parâmetros Opcionais

Caso o parâmetro não esteja presente na URL, `urlParams.get('o')` retornará `null`. Para evitar erros, podemos adicionar um valor padrão, nesse caso, deixamos em branco usando o '':

```javascript
const oValue = urlParams.get('o') || '';
console.log(oValue);
```

## Conclusão

A API `URLSearchParams` fornece uma maneira simples e eficiente de manipular parâmetros da querystring em JavaScript. Isso permite maior flexibilidade no desenvolvimento de aplicações web dinâmicas.

# Como escutar o evento javascript que ocorre antes de preencher uma tabela filha e depois de preencher

### Evento before-data-load que ocorre antes de carragar os dados na tabela filha

```javascript
//escutando o evento pós carregamento: before-data-load
//remover os botões de actions da table filha com id 3240ec20-313b-921e-c587-ea979a720690 por exemplo
$('#3240ec20-313b-921e-c587-ea979a720690').on('before-data-load', function (e) {


  console.log("evento que ocorre antes de carregar a tabela, before-data-load);

});
```

### Evento data-loaded que ocorre antes de carragar os dados na tabela filha

```javascript
//escutando o evento pós carregamento: data-loaded
//remover os botões de actions da table filha com id 3240ec20-313b-921e-c587-ea979a720690 por exemplo
$('#3240ec20-313b-921e-c587-ea979a720690').on('data-loaded', function (e, result_json) {

  console.log("evento que ocorre depois de carregar a tabela, data-loaded);
  
    $('.grid-result .action-buttons').remove();


});
```

# Como remover os botões de editar e remover de cada linha de uma tabela filha e também o botão de adicionar um novo registro filho

## Para remover o botão de adicionar novo registro na tabela filha

##  

#### **Javascript**: No form pai, coloque o código javacript abaixo, trocando o id do botão de adicionar da tabela filha que gostaria de remover

```javascript
$(document).on("ready", function () {

    //troca o id abaixo pelo id do botão que de adicionar form filho
    $("#btn-formulario-relacionado-3240ec20-313b-921e-c587-ea979a720690").remove();

});
```

#### **Css**: esconda o botão visualmente

  
No exemplo abaixo forçamos via css que o botão nem seja apresentado, caso o script javascript nao rode à tempo

```javascript
#btn-formulario-relacionado-3240ec20-313b-921e-c587-ea979a720690{
    display: none;
}
```

## Para Remover o editar e remover de cada linha da tabela filha:

#### **Javascript**: No form pai, coloque o código javacript abaixo, trocando o Id para o id da tabela filha que gostaria de remover os actions buttons

```javascript
//remover os actions da table filha só por  garantia
$('#trocar_aqui_para_o_guid_tabela_filha').on('data-loaded', function (e, result_json) {

    $('.grid-result .action-buttons').remove();


});
```

#### **Css**: Deixe visualmente a coluna onde os actions buttons eram apresentados menores

  
No exemplo abaixo colocamos uma largura de 30px para qualquer tabela de formulário filho e também forçamos via css que os actions buttons nem seja apresentados, caso o script javascript nao rode à tempo

```javascript
.grid-result .action-buttons {
    display: none !important;
}

.grid-result  colgroup col:first-child {
    width: 30px !important;
}
```

# Como validar se um e-mail está no formato válido?

### **Configurar o GlobalClass**

#####  

##### Na GlobalClass, crie um arquivo C#, chamado EmailValidator ou algo similar

[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-03/scaled-1680-/image.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-03/image.png)

##### Coloque dentro do C# criado a seguinte classe

```c#
public class EmailValidator{

    public bool IsValidEmail(string email)
    {
        if (string.IsNullOrWhiteSpace(email))
            return false;

        string pattern = @"^[^@\s]+@[^@\s]+\.[^@\s]+$";
        return System.Text.RegularExpressions.Regex.IsMatch(email, pattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    }

} 
 

```

### **Configurar a regra no Formulário**

Dentro do Businnes Rules de um formulário que você tenha um campo de e-mail que gostaria de validar, crie uma regra de negocio chamada Email Validator ou algo similar.

Para esse exemplo, estamos considerando que você tem um campo chamado "**email**" nesse formulário.

[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-03/scaled-1680-/aaIimage.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-03/aaIimage.png)

Arraste a business rules criada para ser executada no evento de "Salvar" do formulário.

Dentro da businesse rules, arraste um componente de Promograçao em C# e cole o seguinte código:

Esse código chama a utiliza a GlobalClass EmailValidator e o metodo criado IsValidEmail para validar se o e-mail é valido.

```c#
public async Task ExecuteAsync(){    
    
    
    var email = FormContext.GetValue("email");

    var emailValidator = GlobalClass.CreateInstanceEmailValidator();

    if(!emailValidator.IsValidEmail(email)){
        FormContext.WarningMessage("Informe um e-mail válido");
    }
    
    
    
}
```

# Configuração de perfil de acesso para visualizar o Custom Menu. Quem poderá ver o item do menu?

<p class="callout warning">**⚠ **Se o usuário não possuir permissão para a funcionalidade, o item de menu não será exibido para ele, mesmo que esteja configurado no Custom Menu.****</p>

### **Configurou o item no menu mas ele ainda nao aparece para um determinado usuário?**

**Esse artigo explica como resolver as regras de controle de acesso.**

### **Como funciona o controle de acesso aos itens do menu?**

Na tela de Custom Menu, você pode definir quais itens de menu estarão disponíveis para os usuários do sistema. No entanto, é importante entender que a simples adição de um item ao menu **não garante que o usuário terá acesso a ele**.

#### **Como funciona o controle de acesso?**

O sistema verifica se o usuário tem permissão para visualizar e acessar cada item do menu com base no **Perfil de Acesso** associado a ele. Isso significa que:

1. **Cada item de menu está vinculado a uma funcionalidade específica do sistema**.
2. **Os usuários só verão os itens de menu para os quais possuem acesso à funcionalidade correspondente**.
3. **O acesso às funcionalidades é controlado dentro do Perfil de Acesso vinculado ao usuário logado**.

#### **O que fazer para que um usuário veja um item no menu?**

Para garantir que um usuário tenha acesso ao item de menu desejado, siga estes passos:

1. **Confirme o Perfil de Acesso do usuário logado:** Identifique qual Perfil de Acesso está sendo usado pelo usuário que deve visualizar o menu.
2. **Habilite a Funcionalidade:** Acesse a configuração do Perfil de Acesso e conceda permissão à funcionalidade associada ao item de menu.

⚠ **Se o usuário não possuir permissão para a funcionalidade, o item de menu não será exibido para ele, mesmo que esteja configurado no Custom Menu.**

Caso tenha dúvidas, consulte a equipe responsável pela administração de perfis e permissões no sistema.

# Como destacar informações importantes, como alertas, sucessos, erros  no corpo de um Formulário? Adicione avisos coloridos no Formulário.

A imagem abaxio exemplifica 4 formas de colocar avisos coloridos:

[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-03/scaled-1680-/cdnimage.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-03/cdnimage.png)

## Introdução

Este guia explica como adicionar avisos coloridos (amarelo, azul, verde e vermelho) em um formulário usando HTML e classes CSS. Os avisos são úteis para destacar informações importantes, como alertas, sucessos, erros e informações.

## Passo a Passo

### 1. Na customização do Form, crie um componente `cshtml`

Crie um componente `cshtml` para definir os avisos coloridos. Você pode nomear o arquivo como `AvisosColoridos`.

<div drawio-diagram="450"><img src="https://wiki.agilityflow.io/uploads/images/drawio/2025-03/drawing-3-1742742201.png" alt=""/></div>

### 2. Adicionar o Código dos Avisos

No componente cshtml `AvisosColoridos`, adicione o seguinte código:

```html
<div class="alert alert-alt alert-warning" role="alert">
    <i class="icon md-lamp icon-alert-warning"></i>
    <div class="alert-text">
        Essa versão de um aviso de warning
    </div>
</div>

<div class="alert alert-alt alert-primary" role="alert">
    <i class="icon md-lamp icon-alert-primary"></i>
    <div class="alert-text">
        Essa versão de um aviso de informação
    </div>
</div>

<div class="alert alert-alt alert-success" role="alert">
    <i class="icon md-lamp icon-alert-success"></i>
    <div class="alert-text">
        Essa versão de um aviso de sucesso
    </div>
</div>

<div class="alert alert-alt alert-danger" role="alert">
    <i class="icon md-lamp icon-alert-danger"></i>
    <div class="alert-text">
        Essa versão de um aviso de erro
    </div>
</div>
```

### 3. Adicione o novo campo AvisosColoridos ao Form

[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-03/scaled-1680-/yZ7image.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-03/yZ7image.png)

### 4. Arraste o componente cshtml para dentro do form onde você gostaria que as msgs aparecessem.

[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-03/scaled-1680-/Rpaimage.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-03/Rpaimage.png)

### 5. Personalização

Você pode personalizar o texto e os ícones dos avisos conforme necessário. As css classes que mudam as cores de cada msg são (`alert-warning`, `alert-primary`, `alert-success`, `alert-danger`)

## Conclusão

Seguindo esses passos, você pode facilmente adicionar avisos coloridos em seus formulários para melhorar a experiência do usuário e destacar informações importantes.

# Como fazer a cópia completa de um registro de um formulário? Incluindo as tabelas filhas

## **Cópia Simples, sem considerar tabelas filhas**

Em todos os formulários por padrão já existe uma opção de duplicar/copiar o registro, através do botão representado pelo icone: ![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-04/scaled-1680-/e6oimage.png) que fica na barra de botões do formulário:

<p class="callout warning">Essa opção não copia os registos dos formulários filhos ou tabelas. Caso seja necessário, utilize a técnica demonstrada no tópico abaixo nesse mesmo artigo.</p>

[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-04/scaled-1680-/image.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-04/image.png)


## **Cópia Completa, considerando tabelas filhas**

#### **Crie e configure o botão para copiar**

1. **Entre no formulário que você deseja colocar o botão de "Copiar"**
2. **Crie um botão chamado "Copiar", marque para que esse botão**
3. **Marque para esse botão ser mostrado na barra de botões do formulario**
4. **[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-04/scaled-1680-/Vvbimage.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-04/Vvbimage.png)**
5. **Marque para esse botão Não ser mostrado dentro do formulario**
6. **Deixa o botão fora do layout do formulario, ele nao precisa ser arrastado para dentro do formularío, caso esteja, remova**
7. **no clique do botão em javascript, confiure para chamar a função js: copiarRegistro()**

[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-04/scaled-1680-/Fm8image.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-04/Fm8image.png)

### No Visual Code Editor do Formulário

Adicione o Javascript abaixo

```javascript
function copiarRegistro() {


    //só deixa copiar caso nao seja um form novo
    if (formContext.form.isNew())
    {
        pageMsg.formContext.msg.showMsgWarning("Salve o formulário antes de copiar", "Falha ao copiar")
        return;
    }

    //chama o cshtml "CopiarRegistro" que fará a copia
    formContext.loadAjax("CopiarRegistro", {
        onSuccess: function (response) {

            //em caso de sucesso, mostra a msg de sucesso e já redireciona o usuario para a proxima pagina
            pageMsg.showMsgSuccess("Orçamento Duplicado", "Sucesso");

            //em caso de sucesso, redireciona para a url que foi criado
            //importante mudar aqui para o id da estrutura do formulario correto
            window.parent.location = window.parent.base_url + "fluxo/index/74ad209b-ee6a-4ae3-9920-2caad2bc7451/" + response.trim() ;
                        
        },
        onError: function (err) {
            pageMsg.formContext.msg.showMsgWarning("Falha: " + err, "Falha ao copiar")
            console.error("Erro ao carregar o registro:", err);
        }
    });
}
```

Crie um cshtml chamado **CopiarRegistro**

[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-04/scaled-1680-/6psimage.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-04/6psimage.png)

Cole o código cshtml / C# abaixo:

```c#
@{

    /*

      NESSE EXEMPLO, ESTOU COPIANDO O FORMULARIO ORÇAMENTO E OS ORÇAMENTO ITEM QUE É FILHO DE ORÇAMENTO
  
     */

   //MUDAR AQUI PARA OS IDS DAS ESTRUTURA DOS FORMULARIOS 
    var idEstruturaFormularioOrcamento = Guid.Parse("74ad209b-ee6a-4ae3-9920-2caad2bc7451");
    var idEstruturaFormularioItemOrcamento = Guid.Parse("0c114359-8cb1-4d42-85b4-9882417c386a");    

    //CRIAR O DICTIONARY COM OS DADOS DO FORM PAI, ORÇAMENTO
    var values = new DataDictionary();
    values.Add("numero",PageContext.GetValue("numero"));
    values.Add("cliente",PageContext.GetValue("cliente"));

    //SALVAR O ORÇAMENTO E RECUPERA O ID CRIADO
    var orcamentoId = await PageContext.SaveEntityAsync(idEstruturaFormularioOrcamento, values);

    var paramsQueryItemOrcamento = new List<NpgsqlParameter>();
    paramsQueryItemOrcamento.Add(new NpgsqlParameter("@orcamento", new Guid(PageContext.FormId.ToString())));

    //FAZ UMA QUERY PARA BUSCAR TODOS OS ITENS DO ORÇEMANTO ITEM
    var sqlItemOrcamento = "select * from x_tbl_orcamento__item where deletado = false and idorcamento = @orcamento limit 100";
    var dtItemOrcamento = await PageContext.GetDataTableAsync(sqlItemOrcamento, paramsQueryItemOrcamento.ToArray());
    

    //CASO TENHA ITENS, FAZ UM LOOP PARA COPIAR TODOS E SALVAR
    if (dtItemOrcamento != null && dtItemOrcamento.Rows.Count >= 1)
    {
        foreach (DataRow itemOrcamento in dtItemOrcamento.Rows)
        {

            //CRIAR O DICTIONARY COM OS DADOS DO FORM FILHO, ORÇAMENTO ITEM
            var valuesItemOrcamento = new DataDictionary();

            //AQUI COLOCAR O ID DO ORÇAMENTO QUE FAZ A LIGAÇÃO ENTRE O ORÇAMENTO (PAI) E ORÇAMENTO ITEM (FILHO)
            valuesItemOrcamento.Add("idorcamento", orcamentoId);
          
            valuesItemOrcamento.Add("detalhes_do_item",itemOrcamento["detalhes_do_item"].ToString());
            valuesItemOrcamento.Add("nome_do_item",itemOrcamento["nome_do_item"].ToString());

            //SALVAR O ORÇAMENTO ITEM
            await PageContext.SaveEntityAsync(idEstruturaFormularioItemOrcamento, valuesItemOrcamento);

        }
    }

}
@orcamentoId
```

Nas configuraçoes de botões do formulário, marque para o botão padrão de "**duplicar/copiar**" não aparecer. Em algumas versões essa opção de nao aparecer pode não estar disponível, sendo assim, você pode usar o css abaixo na opção de CSS para deixar o botão invisível

```css
#btnCopyForm{
    display: none
}
```

# Como consultar no banco de dados os campos de upload e acessar a imagem por URL?

### Consulta de Dados de Upload no AgilityFlow

### Contexto

Campos do tipo **upload de arquivo** não ficam armazenados diretamente na tabela principal dos dados do formulário. Eles são gravados separadamente na tabela `tbl_storage`, sendo necessários alguns identificadores para localizar os arquivos corretamente.

---

### Como consultar os dados do upload

Utilize a consulta SQL abaixo para buscar as informações do arquivo enviado:

```SQl
SELECT sto_id, sto_diretorio AS diretorio, sto_nome_original AS nome_original, sto_nome_virtual AS nome_virtual FROM tbl_storage 
WHERE 
fca_id = '<id do campo>' AND 
frm_id = '<id do formulário>' AND 
deletado = false 
LIMIT 10
```

---

### Descrição dos parâmetros

<div class="_tableContainer_16hzy_1" id="bkmrk-campo-descri%C3%A7%C3%A3o-efr_"><div class="_tableWrapper_16hzy_14 group flex w-fit flex-col-reverse" tabindex="-1"><table class="w-fit min-w-(--thread-content-width)" data-end="1238" data-start="867"><thead data-end="893" data-start="867"><tr data-end="893" data-start="867"><th data-col-size="sm" data-end="880" data-start="867">Campo</th><th data-col-size="md" data-end="893" data-start="880">Descrição</th></tr></thead><tbody data-end="1238" data-start="921"><tr data-end="1053" data-start="1004"><td data-col-size="sm" data-end="1017" data-start="1004">`fca_id`</td><td data-col-size="md" data-end="1053" data-start="1017">ID do campo específico de upload (\*\*\* veja na imagem abaixo como pegar esse iD)</td></tr><tr data-end="1123" data-start="1054"><td data-col-size="sm" data-end="1067" data-start="1054">`frm_id`</td><td data-col-size="md" data-end="1123" data-start="1067">ID do formulário preenchido (registro do formulário)</td></tr><tr data-end="1238" data-start="1124"><td data-col-size="sm" data-end="1137" data-start="1124">`deletado`</td><td data-col-size="md" data-end="1238" data-start="1137">Define se o arquivo foi excluído logicamente. Use `false` para considerar apenas arquivos ativos.</td></tr></tbody></table>

</div></div>##### **Como recuperar o fca\_id do campo Upload?**

Acesse o Inspect Element do campo e vá até o local onde o campo de Upload está localizado. Pegue o Id do campo Hidden, como na figura abaixo:

[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-05/scaled-1680-/image.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-05/image.png)

### Exemplo prático

Com os seguintes valores:

- `fca_id = '66584118-b987-4560-bf0f-5fc3e884f849'`
- `frm_id = '33584118-b987-4560-bf0f-5fc3e884jdhr'`

A consulta seria:

```sql
SELECT 
  sto_id,
  sto_diretorio, 
  sto_nome_original, 
  sto_nome_virtual
FROM 
  tbl_storage
WHERE 
  fca_id = '66584118-b987-4560-bf0f-5fc3e884f849' AND 
  frm_id = '33584118-b987-4560-bf0f-5fc3e884jdhr' AND 
  deletado = false
LIMIT 10;
```

### Como acessar a imagem via URL

Após consultar os dados na tabela `tbl_storage`, você poderá obter também o valor do campo `sto_id`. Com esse ID, é possível acessar a imagem diretamente pelo navegador ou por uma integração externa, utilizando a seguinte URL:

<div class="contain-inline-size rounded-md border-[0.5px] border-token-border-medium relative bg-token-sidebar-surface-primary" id="bkmrk-%2Fimagebyid%2F%3Csto_id%3E"><div class="overflow-y-auto p-4" dir="ltr">`/imagebyid/<sto_id>`</div></div>**Exemplo:**

Se o `sto_id` retornado na consulta for `abc123`, a URL para acessar a imagem será:

<div class="contain-inline-size rounded-md border-[0.5px] border-token-border-medium relative bg-token-sidebar-surface-primary" id="bkmrk-%2Fimagebyid%2Fabc123"><div class="overflow-y-auto p-4" dir="ltr">`/imagebyid/abc123`</div></div>Essa URL pode ser usada para visualização, download ou incorporação da imagem em outros sistemas ou páginas.

# Como chamar uma API externa a partir do agilityflow

Este exemplo mostra como fazer uma requisição HTTP `POST` para uma API externa no contexto do AgilityFlow.


#### Importante sobre `CancellationToken`

O método `PostAsync` **deve sempre utilizar** um `CancellationToken` para garantir que a requisição seja cancelável, evitando problemas em fluxos interrompidos ou expirados.

Para recuperar o `CancellationToken`, utilize o método adequado ao **contexto em que o código está sendo executado**. Alguns exemplos:

- Em **regras de negócio** do formulário:  
    `FormContext.GetCurrentCancellationToken()`
- Em chamadas feitas dentro de uma **API customizada**:  
    `ApiContext.GetCurrentCancellationToken()`
- Em **componentes Razor (.cshtml)** do formulário:  
    `PageContext.GetCurrentCancellationToken()`
- E assim por diante, conforme o contexto (`GlobalContext`,`CustomPageContext`,`CardContext`, etc.)

> Basta utilizar o método `GetCurrentCancellationToken()` do contexto atual.


#### Observação

- Troque `<<URL_DA_API>>` pela URL real da API que deseja acionar.

### Como chamar a api em cada contexto?

#### No FormContext

Crie uma regra de negócio e dentro da regra de Programação em C#, utilize o código abaixo

```c#
public async Task ExecuteAsync()
{
    var formId = FormContext.FormId.Value.ToString();
    await CallExternalApiAsync(formId);
}

public async Task CallExternalApiAsync(string qualquerParametro)
{
    if (string.IsNullOrWhiteSpace(qualquerParametro)) return;

    var payload = new
    {
        parametroParaApi = qualquerParametro
    };

    using (var httpClient = new HttpClient())
    {
        var content = new StringContent(
            JsonConvert.SerializeObject(payload),
            Encoding.UTF8,
            "application/json"
        );

        await httpClient.PostAsync("<<URL_DA_API>>", content, FormContext.GetCurrentCancellationToken());
    }
}
```

#### Na ApiContext

Na programação em C#

```c#
public async Task RunAsync()
{
    await CallExternalApiAsync("exemplo de parametro");
}

public async Task CallExternalApiAsync(string qualquerParametro)
{
    if (string.IsNullOrWhiteSpace(qualquerParametro)) return;

    var payload = new
    {
        parametroParaApi = qualquerParametro
    };

    using (var httpClient = new HttpClient())
    {
        var content = new StringContent(
            JsonConvert.SerializeObject(payload),
            Encoding.UTF8,
            "application/json"
        );

        await httpClient.PostAsync("<<URL_DA_API>>", content, ApiContext.GetCurrentCancellationToken());
    }
}
```

#### No PageContext dos componentes Cshtml do formulário

Na programação em C# razor dos componente

```c#
@{
   
    string qualquerParametro = "";
    if (!string.IsNullOrWhiteSpace(qualquerParametro)){
      var payload = new
      {
          parametroParaApi = qualquerParametro
      };
  
      using (var httpClient = new HttpClient())
      {
          var content = new StringContent(
              JsonConvert.SerializeObject(payload),
              Encoding.UTF8,
              "application/json"
          );
  
          await httpClient.PostAsync("<<URL_DA_API>>", content, PageContext.GetCurrentCancellationToken());
      }
    }
}
```

#### No GlobalContext

Na programação em C#

```c#
public async Task CallExternalApiAsync(string qualquerParametro)
{
    if (string.IsNullOrWhiteSpace(requestId)) return;

    var payload = new
    {
        parametroParaApi = qualquerParametro
    };

    using (var httpClient = new HttpClient())
    {
        var content = new StringContent(
            JsonConvert.SerializeObject(payload),
            Encoding.UTF8,
            "application/json"
        );

        await httpClient.PostAsync("<<URL_DA_API>>", content, GlobalContext.GetCurrentCancellationToken());
    }
}
```

#### No CustomPageContext

Na programação em C# do custom page context

```c#
public async Task CallExternalApiAsync(string qualquerParametro)
{
    if (string.IsNullOrWhiteSpace(requestId)) return;

    var payload = new
    {
        parametroParaApi = qualquerParametro
    };

    using (var httpClient = new HttpClient())
    {
        var content = new StringContent(
            JsonConvert.SerializeObject(payload),
            Encoding.UTF8,
            "application/json"
        );

        await httpClient.PostAsync("<<URL_DA_API>>", content, CustomPageContext.GetCurrentCancellationToken());
    }
}
```

# Limitação ao usar campo do tipo Autocomplete com Numero Sequencial, "Identity" (bigint) na Descrição

No AgilityFlow, ao utilizar um **campo do tipo Autocomplete** e configurar a **Descrição** do item com o campo **"Identity"** de tipo `bigint`, pode ocorrer o seguinte erro:<button class="flex items-center gap-1 py-1 select-none"></button>

<div class="contain-inline-size rounded-2xl border-[0.5px] border-token-border-medium relative bg-token-sidebar-surface-primary" id="bkmrk-error%3A-42883%3A-operat"><div class="overflow-y-auto p-4" dir="ltr">`<span class="hljs-symbol">ERROR:</span> <span class="hljs-number">42883</span>: <span class="hljs-keyword">operator</span> does <span class="hljs-built_in">not</span> exist: bigint ~~* <span class="hljs-keyword">text</span><span class="hljs-symbol">POSITION:</span> <span class="hljs-number">146</span>`</div></div>#### Causa

O erro ocorre porque, internamente, na busca que é feita para apresentar as infos no Autocomplete é utilizado um operador de comparação do tipo `~~*` (ilike), que é compatível apenas com campos `text` ou `varchar`. O tipo `bigint` não pode ser utilizado diretamente em uma operação `ilike`.

#### Solução

Para contornar esse comportamento, é necessário utilizar **uma Query Customizável** como origem dos dados do campo Autocomplete. Dessa forma, você pode fazer o cast adequado ou definir uma lógica personalizada para exibição e busca.

#### Exemplo de Ajuste<button class="flex items-center gap-1 py-1 select-none"></button>

```sql
SELECT Id as Value, "CAMPO_DE_APRESENTACAO" as Name FROM TABELA 
where deletado = false and 
          ( @whereLikeCampoApresentacao IS NULL OR 
         "CAMPO_DE_APRESENTACAO" ilike '%' || @whereLikeCampoApresentacao || '%' )
```

<div class="contain-inline-size rounded-2xl border-[0.5px] border-token-border-medium relative bg-token-sidebar-surface-primary" id="bkmrk-"><div class="overflow-y-auto p-4" dir="ltr">  
</div><div class="overflow-y-auto p-4" dir="ltr">  
</div></div>**Algumas regras importantes para a Query Customizada:**  
  
1 - O resultado final da query precisa ser os dados do formulário base que você definiu como campo de origem do autocomplete  
  
2 - Na query, o campo de apresentação ainda precisa ser o mesmo do campo qe você definiu nas configurações do autocomplete  
  
3 - Lembre-se de tratar os dados que já foram deletados, usando no where "...deletado = false.."  
  
4 - A query deve retornar duas colunas com os seguintes *alias*: "Name" e "Value". O "Name" deve ser a mesma coluna definida no campo de apresentação (#) e o "Value", deve ser a coluna "id" do formulário definido como base de dados (Compras ). Exemplo:  
  
SELECT Id as Value, "CAMPO\_DE\_APRESENTACAO" as Name FROM TABELA where deletado = false and ( @whereLikeCampoApresentacao IS NULL OR "CAMPO\_DE\_APRESENTACAO" ilike '%' || @whereLikeCampoApresentacao || '%' )

# Abrindo Telas em Modo Standalone (sem menus, logo, etc.)

Em algumas situações, pode ser necessário abrir uma tela ou formulário do AgilityFlow de forma isolada, sem exibir os elementos padrões da interface, como:

- Menu lateral
- Menu superior
- Logo
- Ícones de usuário

Esse recurso é útil para integrações externas, form embutidos, visualizações em iframe, ou até mesmo para simplificar a interface em determinados contextos específicos.

### Como ativar o modo standalone

Para isso, basta adicionar o parâmetro `pagemode=standalone` à URL desejada.  
Exemplo:<button class="flex items-center gap-1 py-1 select-none"></button>

<div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary" id="bkmrk-https%3A%2F%2Fmeuambiente."><div class="overflow-y-auto p-4" dir="ltr">`https://meuambiente.agilityflow.io/<span class="hljs-comment">#/fluxo/index/xxxxxxxxxxx<span style="color: rgb(53, 152, 219);"><strong>?pagemode=standalone</strong></span></span>`</div></div>### Comportamento do modo standalone

Ao utilizar `pagemode=standalone`, os seguintes elementos da interface serão ocultados automaticamente:

- Menu lateral esquerdo
- Menu superior
- Logo do sistema
- Ícones e menus de usuário
- Qualquer outro elemento de navegação global

### Quando usar

Use o `pagemode=standalone` nos seguintes casos:

- Compartilhamento de links limpos, com foco apenas no conteúdo principal
- Ambientes de exibição simplificada (como quiosques ou tablets)

### Observações

- A URL continua respeitando as permissões de acesso e autenticação do usuário.
- O parâmetro pode ser combinado com outros parâmetros de URL normalmente.

# Como desativar a paginação automática em Queries do AgilityFlow [disable(auto-pagination)]

## Visão Geral

Por padrão, o AgilityFlow aplica **paginação automática** nas queries para garantir performance e evitar sobrecarga na aplicação. No entanto, **desenvolvedores** podem optar por **desabilitar a paginação automática**, desde que sigam rigorosamente algumas **regras obrigatórias**.

Essa configuração é usada em cenários específicos como:

- Customização avançada de queries
- Tabelas filhas (Master x Detail)
- Queries para componentes como `AutoComplete`, `Listas dinâmicas`, `CustomDatatable`, entre outros

---

## Como desativar a paginação automática

Você deve **adicionar a seguinte tag no início da query**:

<div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary" id="bkmrk-%5Bdisable%28auto-pagina"><div class="overflow-y-auto p-4" dir="ltr">`[disable(auto<span class="hljs-operator">-</span>pagination)]`</div></div>E também usar essas **tags obrigatórias no corpo da query**:

- `{{pagination-clause}}` → onde será injetado o `OFFSET ... LIMIT ...`
- `{{orderby}}` → onde será injetado o `ORDER BY`
- `{{pagination-column}}` → onde será injetada a coluna auxiliar `,0 as __result_count_total` para compatibilidade com aggregate

### Exemplo completo:<button class="flex items-center gap-1 py-1 select-none"></button>

```sql
[disable(auto-pagination)] 
SELECT 
  nome, email, created_at {{pagination-column}} 
FROM 
  tbl_xxxxx 
WHERE 
  deletado = false 
  {{orderby}} 
  {{pagination-clause}}
```

---

## Regras obrigatórias para queries com paginação desativada

Se você optar por **desativar a paginação**, deve:

<div class="_tableContainer_80l1q_1" id="bkmrk-regra-descri%C3%A7%C3%A3o-%E2%9C%85-in"><div class="_tableWrapper_80l1q_14 group flex w-fit flex-col-reverse" tabindex="-1"><table class="w-fit min-w-(--thread-content-width)" data-end="2655" data-start="1854" style="width: 100%; height: 239.037px;"><thead data-end="1875" data-start="1854"><tr data-end="1875" data-start="1854" style="height: 29.349px;"><th data-col-size="md" data-end="1862" data-start="1854" style="width: 64.5306%; height: 29.349px;">Regra</th><th data-col-size="md" data-end="1875" data-start="1862" style="width: 35.4032%; height: 29.349px;">Descrição</th></tr></thead><tbody data-end="2655" data-start="1898"><tr data-end="2045" data-start="1898" style="height: 46.1458px;"><td data-col-size="md" data-end="1991" data-start="1898" style="width: 64.5306%; height: 46.1458px;">✅ Incluir as tags `{{pagination-clause}}`, `{{orderby}}` e `{{pagination-column}` na query</td><td data-col-size="md" data-end="2045" data-start="1991" style="width: 35.4032%; height: 46.1458px;">Elas serão substituídas automaticamente no runtime</td></tr><tr data-end="2276" data-start="2166" style="height: 29.349px;"><td data-col-size="md" data-end="2239" data-start="2166" style="width: 64.5306%; height: 29.349px;">✅ Garantir que a query nunca retorne mais do que a configuração `page size` (qtd de registros esperado)</td><td data-col-size="md" data-end="2276" data-start="2239" style="width: 35.4032%; height: 29.349px;">O sistema lançará erro se exceder</td></tr><tr data-end="2360" data-start="2277" style="height: 29.349px;"><td data-col-size="md" data-end="2345" data-start="2277" style="width: 64.5306%; height: 29.349px;">✅ Adicionar `deletado = false` em **todas as tabelas** utilizadas</td><td data-col-size="md" data-end="2360" data-start="2345" style="width: 35.4032%; height: 29.349px;">Obrigatório</td></tr><tr data-end="2479" data-start="2361" style="height: 46.1458px;"><td data-col-size="md" data-end="2460" data-start="2361" style="width: 64.5306%; height: 46.1458px;">❌ Nunca usar `ORDER BY`, `LIMIT`, `OFFSET` diretamente na query sem `[disable(auto-pagination)]`</td><td data-col-size="md" data-end="2479" data-start="2460" style="width: 35.4032%; height: 46.1458px;">Vai lançar erro</td></tr><tr data-end="2655" data-start="2580" style="height: 29.349px;"><td data-col-size="md" data-end="2622" data-start="2580" style="width: 64.5306%; height: 29.349px;">❌ Não usar `INSERT`, `UPDATE`, `DELETE`</td><td data-col-size="md" data-end="2655" data-start="2622" style="width: 35.4032%; height: 29.349px;">Apenas SELECTs são permitidos</td></tr></tbody></table>

</div></div>## Validações adicionais feitas pelo sistema

Mesmo com a paginação desativada, a query será validada quanto a:

- **Segurança** (SQL Injection, funções perigosas)
- **Conformidade com naming** (sem colunas com espaços, acentos ou nomes reservados como `data`)
- **Volume de dados** (validação por `EXPLAIN`)
- **Tags obrigatórias ausentes**
- **Uso de parâmetros esperados (ex: `@master_id` em detail tables)**

<div class="_tableWrapper_80l1q_14 group flex w-fit flex-col-reverse" id="bkmrk--3" tabindex="-1"></div>

# Como adicionar uma assinatura digital em um Report Print / template de Impressão / PDF

Em muitos cenários regulatórios ou operacionais, é necessário que um **Report Print** contenha uma **assinatura do responsável**, seja ela manual, digitalizada ou capturada via formulário.  
Neste artigo, vamos mostrar **como configurar um campo de assinatura e ajustá-lo visualmente no Report Print**, de forma simples e flexível.

[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-12/scaled-1680-/iqMimage.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-12/iqMimage.png)

## Visão geral da solução

A ideia é bem objetiva:

1. Criar um **formulário** com um campo do tipo **Assinatura**
2. Arrastar esse campo para dentro do **Report Print**
3. Ajustar o tamanho e o posicionamento da assinatura usando o **Código-Fonte** do editor

---

## 1. Criando o campo de Assinatura no formulário

No formulário que alimenta o Report Print:

- Crie um novo campo
- Selecione o **tipo: Assinatura**
- Salve o formulário

Esse campo será responsável por armazenar a imagem da assinatura associada ao operador ou responsável.

> Importante: o campo aparecerá disponível como variável para ser usado no Report Print.

---

## 2. Inserindo a assinatura no Report Print

Com o Report Print aberto no editor:

- Arraste o campo **Assinatura** para o local desejado no documento
- Ele aparecerá como um placeholder dinâmico (exemplo: `@Assinatura`)

Neste momento, o layout ainda é básico, sem controle fino de tamanho ou alinhamento.

[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-12/scaled-1680-/wxoimage.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-12/wxoimage.png)

---

## 3. Acessando o modo Código-Fonte

Para personalizar o layout:

- Clique no ícone **Código-Fonte** no menu do editor
- O HTML completo do Report Print será exibido

[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-12/scaled-1680-/KG4image.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-12/KG4image.png)

<div class="no-scrollbar flex min-h-36 flex-nowrap gap-0.5 overflow-auto sm:gap-1 sm:overflow-hidden xl:min-h-44 mt-1 mb-5 [&:not(:first-child)]:mt-4" id="bkmrk--6"></div>É nesse ponto que conseguimos controlar exatamente **como a assinatura será exibida**.

---

## 4. Criando uma classe CSS para a assinatura

No início do código (ou em um local apropriado), adicione um bloco de estilo, exemplo:

```html
<style type="text/css">.assina2{
    width: 270px;
    margin: auto;
    margin-bottom: -30px;
}
</style>
```

<div class="contain-inline-size rounded-2xl corner-superellipse/1.1 relative bg-token-sidebar-surface-primary" id="bkmrk-o-que-esse-css-faz"><div class="overflow-y-auto p-4" dir="ltr">`    `O que esse CSS faz</div></div>- `width: 270px`  
    Define um tamanho padrão para a assinatura, evitando que ela fique grande demais
- `margin: auto`  
    Centraliza a assinatura horizontalmente
- `margin-bottom: -30px`  
    Ajusta o espaçamento vertical, aproximando a assinatura do texto abaixo (nome, cargo, empresa etc.)

Esse valor pode (e deve) ser ajustado conforme o layout do seu documento.

---

## 5. Envolvendo o campo de assinatura com a classe CSS

Agora, localize no HTML o trecho onde o campo de assinatura aparece e envolva-o com uma `div` usando a classe criada:

<div class="contain-inline-size rounded-2xl corner-superellipse/1.1 relative bg-token-sidebar-surface-primary" id="bkmrk-%3Cdiv-class%3D%22assina2%22"><div class="@w-xl/main:top-9 sticky top-[calc(--spacing(9)+var(--header-height))]"><div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"><div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs">  
</div></div></div><div class="overflow-y-auto p-4" dir="ltr">`<span class="hljs-tag"><<span class="hljs-name">div</span></span> <span class="hljs-attr">class</span>=<span class="hljs-string">"assina2"</span>>    @Assinatura<span class="hljs-tag"></<span class="hljs-name">div</span></span>>`</div></div>No seu caso real, o campo aparece como um `label` com bindings internos, algo semelhante a:

<div class="contain-inline-size rounded-2xl corner-superellipse/1.1 relative bg-token-sidebar-surface-primary" id="bkmrk--9"><div class="@w-xl/main:top-9 sticky top-[calc(--spacing(9)+var(--header-height))]"><div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"><div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs">  
</div></div></div><div class="overflow-y-auto p-4" dir="ltr">  
</div></div>```html
<div class="assina2"> 
  <span class="fontededados"> 
    <label class="p-name" data-variablename="Assinatura"> Assinatura </label> 
  </span> 
</div>
```

O importante é que **todo o bloco da assinatura esteja dentro da `div.assina2`**. como no exemplo abaixo

<div class="border-token-border-default relative w-32 shrink-0 overflow-hidden rounded-xl border-[0.5px] md:shrink max-h-64 sm:w-[calc((100%-0.5rem)/3)] rounded-s-xl" id="bkmrk--10">  
</div><div class="border-token-border-default relative w-32 shrink-0 overflow-hidden rounded-xl border-[0.5px] md:shrink max-h-64 sm:w-[calc((100%-0.5rem)/3)] rounded-s-xl" id="bkmrk--11"></div><div class="border-token-border-default relative w-32 shrink-0 overflow-hidden rounded-xl border-[0.5px] md:shrink max-h-64 sm:w-[calc((100%-0.5rem)/3)] rounded-s-xl" id="bkmrk--12">[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-12/scaled-1680-/image.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-12/image.png)</div><div class="border-token-border-default relative w-32 shrink-0 overflow-hidden rounded-xl border-[0.5px] md:shrink max-h-64 sm:w-[calc((100%-0.5rem)/3)] rounded-s-xl" id="bkmrk--13"></div><div class="no-scrollbar flex min-h-36 flex-nowrap gap-0.5 overflow-auto sm:gap-1 sm:overflow-hidden xl:min-h-44 mt-1 mb-5 [&:not(:first-child)]:mt-4" id="bkmrk--14"><div class="border-token-border-default relative w-32 shrink-0 overflow-hidden rounded-xl border-[0.5px] md:shrink max-h-64 sm:w-[calc((100%-0.5rem)/3)] rounded-e-xl">  
</div></div><div class="no-scrollbar flex min-h-36 flex-nowrap gap-0.5 overflow-auto sm:gap-1 sm:overflow-hidden xl:min-h-44 mt-1 mb-5 [&:not(:first-child)]:mt-4" id="bkmrk--16"><div class="border-token-border-default relative w-32 shrink-0 overflow-hidden rounded-xl border-[0.5px] md:shrink max-h-64 sm:w-[calc((100%-0.5rem)/3)] rounded-e-xl">  
</div></div>

# Como adicionar e atualizar itens em uma tabela de formulário filho

# Como adicionar e atualizar itens em uma tabela de formulário filho

Este guia explica como **inserir e atualizar registros em uma tabela de formulário filho** a partir de um **formulário pai**, utilizando **JavaScript + componente CsHtml (partial)**.

O exemplo usa dados fictícios apenas para demonstrar o funcionamento.

---

## Visão geral da solução

O fluxo funciona assim:

1. Criamos um **Formulário Filho** (referenciando o pai).
2. Criamos um **Formulário Pai** e associamos o formulário filho como uma tabela.
3. No formulário pai, criamos um **botão** que chama um método JavaScript no onclick.
4. Esse método JavaScript carrega um **componente CsHtml** (partial).
5. Dentro do CsHtml, executamos um loop para **inserir registros na tabela do formulário filho**.
6. Após a execução, a tabela é **atualizada automaticamente na tela**.

---

## 1. Criar o Formulário Pai

Primeiro, crie um **formulário pai** contendo os campos que você julgar necessário.

- Valor da Operação
- Repsonsável pela operação

## 2. Criar o Formulário Filho

Em seguida, crie um **formulário filho** contendo os campos que serão inseridos na tabela.

Exemplo de campos:

- Tipo de recebível
- Cedente
- Sacado
- Quantidade de parcelas
- Data de vencimento
- Valor nominal
- **id\_pai (IMPORTANTE, aqui você cria o campo que vai associar o form pai e filho) \*\*\***

\*\*\* detalhes de como fazer a relação Pai e Filho podem ser encontrado em outros docs na Wiki do agilityflow

<div class="contain-inline-size rounded-2xl corner-superellipse/1.1 relative bg-token-sidebar-surface-primary" id="bkmrk--2"><div class="sticky top-[calc(--spacing(9)+var(--header-height))] @w-xl/main:top-9"><div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"></div></div><div class="overflow-y-auto p-4" dir="ltr"></div></div>---

## 2. Associar o Formulário Pai ao Filho

No formulário pai:

- Associe o formulário filho como uma tabela
- Garanta que ele esteja configurado como **tabela de formulário filho**

**Recupere o Id dessa tabela, no nosso exemplo é: "`<span class="hljs-string">0e7f3b2f-dd68-a2d4-fe4e-b68e1c3957ef"</span>`**

**Usaremos mais abaixo, algo assim:**

**`<span class="hljs-keyword">var</span> tableid_recebivel = Guid.Parse(<span class="hljs-string">"0e7f3b2f-dd68-a2d4-fe4e-b68e1c3957ef"</span>); `**

---

## 3. Criar o componente CsHtml (partial)

Agora criamos o **componente CsHtml** que será carregado pelo JavaScript, crie com o nome **import\_fake**

Esse componente será responsável por:

- Inserir registros no formulário filho
- Retornar o controle para o JavaScript

---

## 4. Lógica do CsHtml para inserir registros

Dentro do CsHtml, usamos C# para inserir os dados.

Neste exemplo:

- Só inserimos se o formulário for **novo**
- Ignoramos formulários em **rascunho**
- Criamos **10 registros fictícios** apenas para demonstração

Exemplo:

<div class="contain-inline-size rounded-2xl corner-superellipse/1.1 relative bg-token-sidebar-surface-primary" id="bkmrk--6"><div class="sticky top-[calc(--spacing(9)+var(--header-height))] @w-xl/main:top-9"><div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"><div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs">  
</div></div></div><div class="overflow-y-auto p-4" dir="ltr"></div></div>```c#
@{	

	//id da tabela
    var tableid_recebivel = Guid.Parse("0e7f3b2f-dd68-a2d4-fe4e-b68e1c3957ef"); //table id DO FORMULÁRIO FILHO
  

    //testa se é um form NOVO e se NÂO é RASCUNHO pois nesse exemplo quero inserir apenas para formulário NOVOS que não sejam RASCUNHOs
    var isNovo = Model.Id.IsNullOrEmpty();
    var isRascunho = !Model.RascunhoId.IsNullOrEmpty();

    if(isNovo && !isRascunho){

        for (var i = 0;i<10;i++){

            var parcelas =  Random.Shared.Next(1, 19);

            //info do formulario filho
            var campos_e_valores = new DataDictionary();
            campos_e_valores["tipo_de_recebivel"] = "e253f97a-8315-4ed9-b5f8-9820f7152a60";
            campos_e_valores["cedente"] = "335e3af4-f97d-4cf4-9b5c-faf5d14c726d";
            campos_e_valores["sacado"] = "12a5c07d-d955-4dc2-85cf-55b20d889761";
            campos_e_valores["qtd_de_parcelas"] = parcelas.ToString();
            campos_e_valores["data_de_vencto"] = DateTime.Now.AddMonths(1).ToUserTimeZone().ToString();
            campos_e_valores["valor_nominal"] = "35000";

        
                                
            //adiciona na tabela filha
            //retorna o id do rascunho desse formlario filho, pois o ID final só será gerado ao Salvar o Formulario PAi
            var formRascunhoId = await PageContext.AddChildFormAsync( tableid_recebivel, campos_e_valores);
                        
        
        }
        

    }
}


```

<div class="contain-inline-size rounded-2xl corner-superellipse/1.1 relative bg-token-sidebar-surface-primary" id="bkmrk--7"><div class="overflow-y-auto p-4" dir="ltr">  
</div></div>---

## 5. Criar o botão no Formulário Pai

No formulário pai, crie um botão com um **onclick** chamando uma função JavaScript.

Exemplo:

<div class="contain-inline-size rounded-2xl corner-superellipse/1.1 relative bg-token-sidebar-surface-primary" id="bkmrk-import_fake%28%29%3B"><div class="overflow-y-auto p-4" dir="ltr">`<span class="hljs-title function_">import_fake</span>();`</div><div class="overflow-y-auto p-4" dir="ltr"></div></div>Esse botão será responsável por iniciar o processo de inserção.

---

## 6. JavaScript do Formulário Pai

No JavaScript do formulário pai, carregamos o **componente CsHtml** usando `loadCsHtmlComponent`.

Esse componente cshtml executará a lógica de inserção e ao retornar faremos via Javacript o "refresh" da tabela para que os dados inseridos apareçam

Exemplo:

```javascript
function import_fake() {

  
    formContext.loadCsHtmlComponent("import_fake", {


        onSuccess: function (result) {
            // formContext.msg.success("Executado com sucesso", "Confirmação");

            var tableid_recebivel = "0e7f3b2f-dd68-a2d4-fe4e-b68e1c3957ef"
            
            formContext.childForm.datatable.refresh(tableid_recebivel);

       
            
        }

        
    });
}
```

<div class="overflow-y-auto p-4" dir="ltr" id="bkmrk--10"></div>Pontos importantes:

- O `onSuccess` é executado após o CsHtml terminar.
- O `datatable.refresh` garante que os novos registros apareçam na tela.

## 7. O que acontece internamente

- Cada chamada de `AddChildFormAsync` cria um **registro no formulário filho**
- O ID final do registro só será gerado quando o **formulário pai for salvo**
- O retorno do método é o **ID do rascunho**, usado internamente pelo sistema

---

## 8. Atualizando os dados da tabela

Após o CsHtml finalizar:

- O JavaScript executa `datatable.refresh`
- A tabela do formulário filho é recarregada
- Os registros recém-inseridos aparecem imediatamente na tela

---

## Observações importantes

- Este exemplo usa dados **fictícios**
- Sempre valide se o formulário não está em rascunho
- Para atualizações, a lógica pode ser adaptada para:
    
    
    - Buscar registros existentes
    - Alterar valores
    - Inserir apenas registros que não existam

### Se você precisar atualizar um registro basta seguir o código usando o **PageContext.UpdateChildForm como no exemplo abaixo:**

```c#
@{	

	//id da tabela
    var tableid_relacaoFormularioPaiFilhoId = Guid.Parse("0dd874a9-9c39-4e4f-acc3-02015a60f6bb"); //table id DO FORMULÁRIO FILHO
  
    //info do formulario filho
    var campos_e_valores = new DataDictionary();
    campos_e_valores["nome_filho"] = "Exemplo 01 - " + DateTime.Now;
    campos_e_valores["valor_numerico"] = PageContext.FormatNumberToString_EnglishFormat(999999.99, 2);
  
  
	//testa se é um form NOVO e se NÂO é RASCUNHO pois nesse exemplo quero inserir apenas para formulário NOVOS que não sejam RASCUNHOs
    var isNovo = Model.Id.IsNullOrEmpty();
    var isRascunho = !Model.RascunhoId.IsNullOrEmpty();
  
  
    if(isNovo && !isRascunho){
      
      	//adiciona na tabela filha
       //retorna o id do rascunho desse formlario filho, pois o ID final só será gerado ao Salvar o Formulario PAi
       var formRascunhoId = PageContext.AddChildForm( tableid_relacaoFormularioPaiFilhoId, campos_e_valores);
      
      
      
        //atualiza o item que acabamos de adicionar, apenas para demonstração
		Guid? idFormularioFilho = null;        
        campos_e_valores["nome_filho"] = "Exemplo Atualizado 0123456789 - " + DateTime.Now;            
        PageContext.UpdateChildForm(         	         
            //se ainda não foi salvo pela primeira vez, o item só terá o Id do Rascunho
            rascunhoId, 

            //se já foi salvo pela primeira vez, o item já terá o Id
            //então passa aqui o id (nesse exemplo estamos passando null para atualizar apenas o
            idFormularioFilho, 

            tableid_relacaoFormularioPaiFilhoId,
            campos_e_valores);
     
	}
}
```