Índice |
---|
outline | true |
---|
exclude | .*ndice |
---|
style | none |
---|
|
O objetivo deste guia é descrever os eventos de formulários avançados no fluig, abordando criar validações e manipulações do seu formulário.
Antes de iniciar, é importante que leia a documentação sobre Desenvolvimento de Formulários e, durante a leitura você vai sentir a necessidade de entender um pouco mais sobre o parâmetro form (FormController)
Após a criação de uma definição de formulário é possível realizar a criação de scripts para customização. O eventos para formulários são criados conforme passos a seguir:
Deck of Cards |
---|
effectDuration | 0.5 |
---|
history | false |
---|
id | samples |
---|
effectType | fade |
---|
|
Card |
---|
default | true |
---|
id | 1 |
---|
label | Passo1 |
---|
|
Para a criação de um script de formulário no fluig, na visão Explorador de pacotes (Package Explorer) deve-se acessar a pasta forms do projeto fluig, clicar com o botão direito e no menu acessar Novo (New) > Outras (Other).
Figura 5 - Criação de script evento da definição de formulário.
|
Card |
---|
|
Figura 6 - Criação de script evento da definição de formulário.
|
Card |
---|
|
- Selecione o tipo e clique em Avançar (Next >).
|
Card |
---|
|
Após a criação de uma definição de formulário é possível realizar a criação de scripts para customização. O eventos para formulários são criados conforme passos a seguir:
Para a criação de um script de formulário no fluig, na visão Explorador de pacotes (Package Explorer) deve-se acessar a pasta forms do projeto fluig, clicar com o botão direito e no menu acessar Novo (New) > Outras (Other).  Figura 5 - Criação de script evento da definição de formulário.
Abra a pasta Fluig e selecione a opção Script Fluig e clique no botão Avançar (Next > ). Figura 6 - Criação de script evento da definição de formulário.
Selecione o tipo e clique em Avançar (Next >). 
Figura 7 - Criação de script evento da definição de formulário.
|
Card |
---|
|
Figura 8 - Criação de script evento da definição de formulário.
|
Card |
---|
|
Figura 9 - Criação de script evento da definição de formulário.
|
Card |
---|
|
Figura 10 - Criação de script evento da definição de formulário.
|
|
Uma das funções mais importantes para entender o que está acontecendo no código e rastreamento futuro é o log. Tanto em eventos de formulário, eventos de processo, datasets, o fluig permite fazer log em quatro níveis:
Usado para apresentar alguma mensagem de rastreamento do código ou dos campos
Bloco de código |
---|
|
log.info(“Testando o log info”); |
Bloco de código |
---|
|
log.info(“O campo código contém o valor: ” + form.getValue("codigo")); |
Usado para indicar algum ponto de atenção ou problema eminente no código
Bloco de código |
---|
|
if (form.getValue("codigo") == "") {
log.warn(“O campo código está em branco e pode apresentar problemas com as integrações”);
} |
Os logs, se não usados com moderação, podem mais atrapalhar do que ajudar. Por isso, caso necessário, algumas informações podem ser utilizadas como debug, que são ativas somente quando o usuário realmente ver elas
Bloco de código |
---|
|
log.debug("verificando o conteúdo do campo código")
if (form.getValue("codigo") == "") {
log.debug("o campo código está em branco");
} else {
log.debug("o campo código está preenchido: " + form.getValue("codigo"));
} |
Usado para imprimir um log de erro
Bloco de código |
---|
|
if (form.getValue("codigo") == "") {
log.error("O campo código não foi preenchido");
throw "Preencha o campo código";
} |
Este log não é um tipo diferente, na verdade é um log.info turbinado. Serve para fazer o log de objetos mais complexos que simples strings
Bloco de código |
---|
|
var objeto = {'codigo': form.getValue("codigo"), 'nome': form.getValue("nome")};
log.dir(objeto); |
Os eventos de formulários são um conjunto de scripts carregados pela API de Formulários, os quais são desenvolvidos utilizando Javascript e são chamados durante a execução de ação em formulários ou em momentos específicos de interação em formulários.
Esse evento é o primeiro a ser disparado. Ocorre antes de qualquer outro evento da definição de formulário. O evento recebe como parâmetro um objeto do tipo FormController.
Neste contexto, o FormControler deve ser usado apenas para consulta de dados, alterações nos dados não serão persistidas.
Bloco de código |
---|
|
function beforeProcessing(form){
} |
No contexto deste evento a variável form pode ser usada somente para consulta aos campos da definição de formulário, seus valores e estado de apresentação.
Esse evento é disparado no momento em que os objetos do formulário são apresentados. O evento recebe como parâmetro um objeto do tipo FormController e um parâmetro customHTML que serve para personalizar é inserir dados diretamente do servidor no formulário.
Esse evento pode ser utilizado para alterar os valores a serem apresentados no campo do formulário e é o único que permite a alteração antes da renderização. Para isto basta usar o seguinte procedimento:
Bloco de código |
---|
language | js |
---|
title | Ao modificar um registro, preenche o campo com o valor 1 |
---|
linenumbers | true |
---|
|
function displayFields(form, customHTML) {
if ( form.getFormMode() == “MOD” ) {
form.setValue('RNC_colab_abertura', new java.lang.Integer(1));
}
} |
Você pode também ocultar campos pelo nome ou pelo id:
Bloco de código |
---|
|
function displayFields(form, customHTML) {
form.setVisible("campoA", false);
form.setVisibleById("linha___1", false);
} |
Outras funções interessantes que podem ser usados neste evento são:
- Para visualizar o formulário no formato original com os campos desabilitados, deve-se utilizar o método setShowDisabledFields.
- Para habilitar ou desabilitar o botão de excluir nas linhas do formulário filho, que por padrão é habilitado, deve-se utilizar o método setHideDeleteButton.
- Para ocultar o os botões Imprimir e Imprimir em nova Janela, deve-se utilizar o método setHidePrintLink.
Sem customizações | Com customização |
---|
|
Bloco de código |
---|
| function displayFields(form, customHTML) {
form.setShowDisabledFields(true);
form.setHidePrintLink(true);
} |
|
|
Bloco de código |
---|
| function displayFields(form, customHTML) {
form.setHideDeleteButton(false);
} |
|
Formulário funcional com exemplos de utilização de setVisible, setVisibleById, setHideDeleteButton e setHidePrintLink:
Bloco de código |
---|
language | xml |
---|
title | Formulário - Clique para expandir |
---|
linenumbers | true |
---|
collapse | true |
---|
|
<html>
<head>
<script type="text/javascript" src="/portal/resources/js/jquery/jquery.js"></script>
<link type="text/css" rel="stylesheet" href="/portal/resources/style-guide/css/fluig-style-guide.min.css"/>
<script type="text/javascript" src="/portal/resources/style-guide/js/fluig-style-guide.min.js" charset="utf-8"></script>
</head>
<body>
<div class="fluig-style-guide">
<form name="form" role="form">
<h1>Ao Salvar <small> escolha o que ocultar ao salvar o formulário</small></h1>
<p>
<div class="checkbox">
<label>
<input type="checkbox" name="ocultarTabela" value="on" >
Ocultar toda tabela
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="ocultarCampoA">
Ocultar campo A
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="ocultarCampoN1">
Ocultar campo N da primeira linha
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="ocultarCampoM2">
Ocultar campo M da segunda linha
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="ocultarLinha1">
Ocultar linha 1
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="ocultarExclusao">
Ocultar botão de excluir
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="ocultarImpressao">
Ocultar botão de imprimir
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="ocultarLoremIpsum">
Ocultar Lorem Ipsum
</label>
</div>
<p><br><p>
<input type="text" name="campoA" placeholder="Campo A" class="form-control" ></input><br>
<p>
<h2>Tabela de registros</h2>
<table class="table table-bordered" tablename="tabelaTeste" addbuttonlabel="Novo Registro" cellspacing="0" width="100%" id="minhaTabela">
<thead>
<tr class="tableHeadRow">
<td class="tableColumn">N</td>
<td class="tableColumn">M</td>
</tr>
</thead>
<tbody>
<tr class="tableBodyRow" id="linha">
<td><input class="form-control" name="campoN" type="text"></td>
<td><input class="form-control" name="campoM" type="text"></td>
</tr>
</tbody>
</table>
<p>
<div id="loremIpsum">
Lorem Ipsum: Proin eget purus non mauris vehicula aliquam vitae sed est
</div>
</form>
</div>
</body>
</html> |
Bloco de código |
---|
language | js |
---|
title | displayFields.js - Clique para expandir |
---|
linenumbers | true |
---|
collapse | true |
---|
|
function displayFields(form,customHTML){
var ocultarTodaTabela = form.getValue("ocultarTabela") == "on"; // Ocultar toda tabela
var ocultarCampoA = form.getValue("ocultarCampoA") == "on"; // Ocultar campo A
var ocultarCampoN1 = form.getValue("ocultarCampoN1") == "on"; // Ocultar campo N da primeira linha
var ocultarCampoM2 = form.getValue("ocultarCampoM2") == "on"; // Ocultar campo M da segunda linha
var ocultarLinha1 = form.getValue("ocultarLinha1") == "on"; // Ocultar linha 1
var ocultarExclusao = form.getValue("ocultarExclusao") == "on"; // Ocultar botão de excluir
var ocultarImpressao = form.getValue("ocultarImpressao") == "on"; // Ocultar botão de imprimir
var ocultarLoremIpsum = form.getValue("ocultarLoremIpsum") == "on"; // Ocultar a div Lorem Ipsum
if ( ocultarTodaTabela ) {
form.setVisibleById("minhaTabela", false); // bloqueia o campo, tabela ou div cujo id seja "minhaTabela"
}
if ( ocultarCampoA ) {
form.setVisible("campoA", false); // bloqueia o campo com name "campoA"
}
if ( ocultarCampoN1 ) {
form.setVisible("campoN___1", false); // bloqueia o campo com name "campoN___1"
}
if ( ocultarCampoM2 ) {
form.setVisible("campoM___2", false); // bloqueia o campo com name "campoM___2"
}
if ( ocultarLinha1 ) {
form.setVisibleById("linha___1", false); // bloqueia o campo, tabela ou div cujo id seja "linha___1"
}
if ( ocultarLoremIpsum ) {
form.setVisibleById("loremIpsum", false); // bloqueia o campo, tabela ou div cujo id seja "loremIpsum"
}
if ( ocultarExclusao ) {
form.setHideDeleteButton(true); // bloqueia o botão de exclusão de linha
}
if ( ocultarImpressao ) {
form.setHidePrintLink(true); // bloqueia botão de imprimir
}
} |
Conforme explicado, o customHTML permite personalizar o formulário diretamente pelo método displayFields. Este exemplo, adaptado dos nos Exemplos Avançados, mostra como usar o displayFields para, no formulário, ter acesso ao modo de visualização, código do solicitante e número da atividade. Além de preencher alguns campos da solicitação com a data atual e o nome do solicitante:
Bloco de código |
---|
|
function displayFields(form,customHTML){
// getValue("WKNumState"); -> Número da atividade atual de acordo com o diagrama
var numeroAtividadeAtual = getValue("WKNumState");
/*
* form.getFormMode();
* ADD - Momento inicial do formulário antes de iniciar e/ou salvar o processo
* MOD - Momento a qual os campos estão editavéis para o usuário modificar após iniciar e/ou salvar o processo
* VIEW - Modo de visualização do formulário
*/
var modoDeVisualizacaoDoFormulario = form.getFormMode();
// getValue("WKUser"); -> Retorno o código do usuário logado
var codigoSolicitante = getValue("WKUser");
if (modoDeVisualizacaoDoFormulario != "VIEW") {
if (numeroAtividadeAtual == Atividades.ZERO || numeroAtividadeAtual == Atividades.INICIO) { //Antes do processo ser iniciado ou salvo o número da primera ativade é 0
form.setValue("codigoSolicitante", codigoSolicitante);
form.setValue("nomeSolicitante", buscaNomeDeUsuarioPeloIdentificador(codigoSolicitante));
form.setValue("dataSolicitacao", retornaDataAtual());
}
}
// Exemplo de injeção de javascript pelo evento de formulário displayFields
customHTML.append("<script type='text/javascript'>");
customHTML.append("var modoDeVisualizacaoDoFormulario = '" + modoDeVisualizacaoDoFormulario + "';");
customHTML.append("var numeroAtividadeAtual = " + numeroAtividadeAtual + ";");
customHTML.append("var codigoSolicitante = '" + codigoSolicitante + "';");
customHTML.append("</script>");
}
/**
* Função para retornar a data atual
* @returns data atual
*/
function retornaDataAtual() {
return (new java.text.SimpleDateFormat('dd/MM/yyyy')).format(new Date());
}
/**
*
* @param {*} codigoSolicitante
* @returns retorno o nome do usuário
*/
function buscaNomeDeUsuarioPeloIdentificador(codigoSolicitante) {
var constraint = DatasetFactory.createConstraint("colleaguePK.colleagueId", codigoSolicitante , codigoSolicitante, ConstraintType.MUST);
var dataset = DatasetFactory.getDataset("colleague", null, [constraint], null);
return dataset.getValue(0, "colleagueName");
} |
Para que os dados sejam carregados e apresentados em tela, principalmente em dispositivos mobile, é necessário chamar as funções que irão carregá-los dentro de uma estrutura de read.
A invocação dos métodos que irão popular o formulário deve estar contida dentro de uma chamada $(function(), garantindo assim o carregamento dos arquivos exigidos pelo formulário antes das funções.
Por exemplo, deseja-se carregar dados de produtos em um formulário. Para que isto ocorra, foi criada uma função loadProdutos() que irá preencher um grid inserido no formulário HTML. Neste caso a chamada desta função dentro do displayFields ficaria:
Bloco de código |
---|
|
customHTML.append('<script>');
customHTML.append('$(function(){');
customHTML.append("loadProdutos();");
customHTML.append('});');
customHTML.append('</script>'); |
Mas, exceto em situações onde há mais coisas no customHTML que justifiquem isso, o mais recomendado é que você faça isso dentro dos próprios scripts javascript do formulário
Esse evento é disparado no momento em que os objetos do formulário são habilitados. O evento recebe como parâmetro um objeto do tipo FormController.
Bloco de código |
---|
language | js |
---|
title | Exemplo de como tornar campo desativado conforme o modo do formulário |
---|
linenumbers | true |
---|
|
function enableFields(form) {
if ( form.getFormMode() != 'ADD' ){
form.setEnabled("rnc_area",false);
form.setEnabled("rnc_tipo_ocorrencia",false);
}
} |
Outra forma de desabilitar os campos é utilizando comandos JavaScript implementados diretamente em funções do formulário. Porém, neste caso, não é permitido utilizar a propriedade disabled, pois os campos não serão gravados ao salvar o registro de formulário. Para esta situação, deve-se utilizar a propriedade readonly conforme exemplo abaixo:
Bloco de código |
---|
|
document.forms['nomeForm'].nomeCampo.setAttribute('readonly',true); |
Nota |
---|
|
Mesmo utilizando a função setEnable, ainda existe a possibilidade de algum usuário conseguir visualizar informações do campo formulário oculto, utilizando de recursos como a ferramenta de inspeção de código dos navegadores. |
Ao proteger um campo desabilitado, ele não terá o seu valor alterado no registro de formulário. Para isso, informe o valor true para o parâmetro protect do método setEnabled conforme o exemplo abaixo:
Bloco de código |
---|
|
function enableFields(form) {
if ( form.getFormMode() != 'ADD' ){
form.setEnabled("rnc_cod_ocorrencia",false, true);
}
} |
Também é possível utilizar o método setEnhancedSecurityHiddenInputs, que faz com que todos os campos desabilitados pelo método setEnabled fiquem protegidos:
Bloco de código |
---|
|
function enableFields(form) {
if ( form.getFormMode() != 'ADD' ){
form.setEnhancedSecurityHiddenInputs(true);
form.setEnabled("rnc_cod_ocorrencia",false);
}
} |
Nota |
---|
|
O método setEnhancedSecurityHiddenInputs só protegerá campos desabilitados após a sua execução no evento e quando o formulário estiver no contexto de uma execução de processo. |
Este evento pode ser usado para que as datas persistidas por formulários customizados sejam salvas corretamente. Hoje no sistema as datas salvas através de formulários pelo navegador Chrome tem o padrão americano (yyyy-mm-dd), enquanto as datas nos demais navegadores tem o padrão brasileiro (dd/mm/yyyy). Para empresas que utilizam múltiplos navegadores e querem que os dados de data estejam padronizados, recomendamos a utilização do evento inputFields com o seguinte trecho de código.
Bloco de código |
---|
language | js |
---|
title | Código para Datas |
---|
|
function inputFields(form) {
var regEx = /^\d{4}-\d{2}-\d{2}$/;
if (form.getValue("dt_solicitacao").match(regEx)) {
var split = form.getValue("dt_solicitacao").split('-');
form.setValue("dt_solicitacao", split[2] + '-' + split[1] + '-' + split[0]);
}
} |
Esse evento é disparado antes da gravação dos dados do formulário. O evento recebe como parâmetro um objeto do tipo FormController.
Ele é utilizado para fazer validações nos campos.
Bloco de código |
---|
language | js |
---|
title | Exemplo da validação do campo de formulário |
---|
linenumbers | true |
---|
|
function validateForm(form) {
if (form.getValue('RNC_colab_abertura') == null){
throw "O colaborador de abertura não foi informado";
}
} |
Bloco de código |
---|
language | js |
---|
title | Exemplo da validação do campo de formulário com mensagem com quebra de linha |
---|
linenumbers | true |
---|
|
function validateForm(form) {
if (form.getValue('RNC_colab_abertura') == null){
throw "O colaborador de abertura não foi informado\nFavor preencher o campo e tentar novamente";
}
} |
Esse evento é disparado após a criação de um formulário. O evento recebe como parâmetro um objeto do tipo FormController.
Este evento pode ser feito para criar algum tipo de log ou disparar algum evento:
Bloco de código |
---|
language | js |
---|
title | Exemplo de uso para imprimir log |
---|
linenumbers | true |
---|
|
function afterSaveNew(form) {
log.info("Colaborador de abertura: " + form.getValue("RNC_colab_abertura"));
} |
Este é último evento disparado no formulário. O evento recebe como parâmetro um objeto do tipo FormController.
Neste contexto, o FormControler deve ser usado apenas para consulta de dados, alterações nos dados não serão persistidas. Assim como o afterSaveNew pode ser usado para log ou disparo de algum tipo de evento.
Bloco de código |
---|
|
function afterProcessing(form){
} |
Diferentemente dos outros eventos que precisam de um script próprio e são executados no servidor, este evento acontece ao clicar em "enviar" no navegador antes de abrir a tela de movimentação. Por isso, esse código deve ser implementado em um arquivo javascript vinculado ao formulário html. Ele recebe o parâmetro da atividade atual e é muito útil para algumas validações de campos antes mesmo de ser enviado para o servidor.
Bloco de código |
---|
language | js |
---|
title | Exemplo de implementação em um arquivo.js |
---|
linenumbers | true |
---|
|
var beforeMovementOptions = function(numState) {
if (document.form.codigo.value == '') {
throw ("Erro: O código não foi preenchido");
}
return true;
} |
Nota |
---|
|
Este método só é executado caso haja a abertura da tela de movimentação, o que leva em consideração se há mais de uma atividade destino ou o mecanismo de atribuição da próxima tarefa. E também não é considerada em movimentações via api, ou diretamente no formulário pela navegação de documento. Utilize o validateForm em conjunto com esse método para garantir a integridade das validações |
Assim como beforeMovementOptions, este evento acontece ao clicar em "enviar" no navegador executar a movimentação em si. Ou seja, depois do beforeMovementOptions e independente da tela de seleção de atividade/usuário destino.
Esse código deve ser implementado em um arquivo javascript vinculado ao formulário html. Ele recebe o parâmetro da atividade atual e da atividade destino (ou seja, pra qual atividade está sendo enviado essa solicitação) e é muito útil para algumas validações de campos antes mesmo de ser enviado para o servidor.
Ocorre antes da solicitação ser movimentada, após já ter sido selecionada a atividade destino o usuário e demais informações necessárias à solicitação.
Bloco de código |
---|
language | js |
---|
title | Exemplo de implementação em um arquivo.js |
---|
linenumbers | true |
---|
|
var beforeSendValidate = function(numState, nextState) {
if (numState == 1 && nextState == 2 && document.form.codigo.value == '') {
throw ("Erro: Para movimentar para a atividade 2, o código deve ser preenchido");
}
return true;
} |
Este evento está depreciado e não é mais utilizado.